MQLplus/lib_debug.mqh
super.admin 466f9ca5c5 convert
2025-05-30 16:09:52 +02:00

2602 lines
335 KiB
MQL5

#ifndef LIB_DBG_DEBUG_MQH_INCLUDED
#define LIB_DBG_DEBUG_MQH_INCLUDED
#property version "4.81";
/**********************************************************************************
* Copyright (C) 2010-2020 Dominik Egert <dominik.egert@freie-netze.de>
*
* This file holds debug support code.
*
* This file may be copied and/or distributed at free will.
* Author Dominik Egert / Freie Netze UG.
**********************************************************************************
*
* File information
* ================
*
* Version: 4.81
*
*
* Usage:
*
* Defines macros for supporting debugging code.
*
* Macros beginning with DBG_STR_* will represent a string.
* Macros beginning with DBG_MSG_* will printf information.
*
* Following output and string macros are defined:
*
* DBG_STR() // Trace info prefix.
* DBG_STR_PERSIST() // Trace info prefix, message string will persist into release build.
* DBG_STR_VAR() // Convert variable value to string
*
* DBG_MSG() // Will print out a text prefixed with trace information
* DBG_MSG_VAR() // Print a variable
* DBG_MSG_VAR_IF() // Print a variable on condition (condition, variable)
*
* DBG_MSG_TRACE_BEGIN // Output >Trace begin<
* DBG_MSG_TRACE_END // Output >Trace end<
* DBG_MSG_TRACE_RETURN // Replace return(void);
* DBG_MSG_TRACE_RETURN_VAR(x) // Replace return(x);
*
* DBG_STR_COMMENT() // A comment string only valid in debug, removed in release
*
* DBG_MSG_TRACE_FILE_LOADER // Traces the loading order of source code files, place the macro at the top of a file.
* // As the file gets loaded, it will rint out the filename in the experts journal.
*
* DBG_STR_OBJ_RTTI // Resolve object name to string, works only inside of classes and structures
* DBG_MSG_OBJ_RTTI // Print object name, works only inside of classes and structures
*
*
* Vardump for arrays:
*
* DBG_MSG_VARDUMP(x) // Dump variables or arrays content
*
*
* To support assert debugging code, following macros are defined:
*
* DBG_ASSERT(condition, message) // Default assert macro. Will end execution by crash code.
* DBG_ASSERT_LOG(condition, message) // Logging only assert macro. Execution will continue normally.
* DBG_ASSERT_RETURN_VOID(condition, message) // Return assert macro. Will execute a function return if condition is met.
* DBG_ASSERT_RETURN(condition, message, return_value) // Return assert macro. Will execute a function return if condition is met and return a given value/variable.
*
*
* Software Break points:
*
* DBG_SLEEP_SECONDS(seconds) // Will insert a realtime sleep into execution
* DBG_SOFT_BREAKPOINT // Will halt execution for given timeout
* DBG_SOFT_BREAKPOINT_TS(timestamp) // Will halt for timeout seconds at (TimeCurrent() - (TimeCurrent() % PeriodSeconds()) == timestamp)
* DBG_SOFT_BREAKPOINT_CONDITION(x) // Will halt execution if condition is met
* DBG_SOFT_BREAKPOINT_EXEC_TIME(x) // Will halt execution after given execution time runtime
*
*
* Condtional Break points:
*
* Initially you create a break ID on the global scope of the program, using the macro
* DBG_BREAK_CONDITION_CREATE. The first parameter is any alphanumeric ID you make up
* to identify the break point group. The second parameter allows you to disable the group
* and therefore should be set to true by default.
* Within the code, you use the other macros. The macro DBG_BREAK_CONDITION_ACTIVATE is used to
* activate a break point group. if the y parameter is true, it will activate the brakepoints
* with the identifier given in the parameter x.
* The macro DBG_BREAK_CONDITION_DEACTIVATE allows you to disable a breakpoint group by code. If
* its parameter y is true, it will disable the group.
* The macro DBG_BREAK_CONDITION_ON_ID is used to have breakpointsspread out inn your code,
* whereever this macro is placed and when the condition has been evaluated to true, the break
* point will be enabled and halt execution on this macro.
*
* The parameter x is the group id, set by you, alphanumeric. No quotations!!
* The parameter y is the conditional parameter and must evaluate to true or false. It can be
* a function call, a variable or an evaluation. Following the boolean evaluation of the compiler.
*
* DBG_BREAK_CONDITION_CREATE(x, y) // Create a conditional break ID group
* DBG_BREAK_CONDITION_ACTIVATE(x, y) // Enable the groups break points
* DBG_BREAK_CONDITION_DEACTIVATE(x, y) // Disable a groups break points
* DBG_BREAK_CONDITION_ON_ID(x) // Check for break on this group
*
*
* Loop tracing:
*
* DBG_TRACE_LOOP_BEGIN // A new loop will be defined
* DBG_TRACE_LOOP_START // At the beginning of a loop, inside the loop
* DBG_TRACE_LOOP_FINISH // At the end of a loop, inside the loop
* DBG_TRACE_LOOP_END // After a loop is done, will print out stats
*
*
* Complex loop tracing:
*
* To have multiple execution paths withina loop being seperately traced, you may
* want to specify the trace id. This way you can define different paths throughout the loop
* and get an understanding of the execution costs each path implies.
*
* DBG_TRACE_LOOP_BEGIN_ID(id) // A new loop counter with id will be defined
* DBG_TRACE_LOOP_START_ID(id) // Start loop counter with ID at the beginning of a loop, inside the loop
* DBG_TRACE_LOOP_FINISH_ID(id) // Finish loop counter with ID at the end of a loop, inside the loop
* DBG_TRACE_LOOP_END_ID(id) // After a loop is done, will print out stats for this ID
*
*
* Hint:
*
* All debug macros will be removed in runtime builds.
*
*
* Example:
*
* Function definition for call tracing:
*
* Define two macros for replacement to be able to turn on/off tracing
* for a specific function.
* To enable tracing a define will switch trace code on.
*
* #define DBG_TRACE_SOME_FUNCTION
*
* Later in the function body, the macro xxx_RETURN will be used instead
* of the usual "return" command. .
*
* /////////////////////////////////////
* // Function debug trace code
*
* #ifdef DBG_TRACE_SOME_FUNCTION
* #undef DBG_TRACE_SOME_FUNCTION
* #define DBG_TRACE_SOME_FUNCTION(x) x
* #define DBG_TRACE_SOME_FUNCTION_RETURN(x) DBG_MSG_TRACE_RETURN_VAR(x)
* #else
* #define DBG_TRACE_SOME_FUNCTION(x)
* #define DBG_TRACE_SOME_FUNCTION_RETURN(x) DBG_MSG_NOTRACE_RETURN_VAR(x)
* #endif
*
* /////////////////////////////////////
*
* Return value example:
*
* #define xxx_RETURN(x) DBG_MSG_TRACE_RETURN_VAR(x)
*
* Here the return value will be for example an integer.
*
* When using Performance Counters, the Return Macro gets extended
* with the macro PERF_COUNTER_END in RELEASE. This will print out
* the statistics of the functions performance counter value.
*
*
* double some_function(const int index = NULL)
* {
* DBG_TRACE_SOME_FUNCTION(
* DBG_MSG_TRACE_BEGIN;
* DBG_MSG_VAR(index)
* );
* PERF_COUNTER_BEGIN;
*
* DBG_TRACE_SOME_FUNCTION(DBG_TRACE_LOOP_BEGIN);
* for(int cnt = (int)some_periods; ((cnt > NULL) && (!_StopFlag)); cnt--)
* {
* DBG_TRACE_SOME_FUNCTION(DBG_TRACE_LOOP_START);
*
* // Basic calculations
* a += a * cnt;
*
* // Some check
* if(a)
* { continue; }
*
* DBG_TRACE_SOME_FUNCTION(DBG_TRACE_LOOP_FINISH);
* }
* DBG_TRACE_SOME_FUNCTION(DBG_TRACE_LOOP_END);
*
* // Assert value is greater than NULL
* DBG_ASSERT((some_testing_value > NULL), DBG_MSG_VAR(some_testing_value));
*
* // Return
* DBG_TRACE_SOME_FUNCTION_RETURN(some_double_value);
* }
*
*
* Notice:
*
* This line of code is the function return command.
* When passing a NULL value to a macro, you need to
* cast the NULL-Macro according to the return value type
* like this:
*
* // Return
* DBG_TRACE_SOME_FUNCTION_RETURN((double)NULL);
*
* Else you will receive a complie error.
*
*
* Performance tracing
*
* These macros are used to have performance indications on
* the execution speed of a function or block of code.
*
* The macros without parameter are specificated on the function
* itself, if more than one counter within the same function or
* execution block is needed, they can be created by using the
* macros with the parameter. Pass any type of ID to it and use
* it later to close this counter again.
*
* Performance macros will only be available in RELEASE versions.
* They are stripped of in debugging as well from release, if disabled.
*
* Defined performance macros
*
* PERF_COUNTER_BEGIN // Begin measurement of execution time
* PERF_COUNTER_END // End performance measurement and show stats
*
* PERF_COUNTER_DEFINE_ID(x) // Create function global performance counter
* PERF_COUNTER_SET_ID(x) // Begin measurement of execution time
* PERF_COUNTER_CLOSE_ID(x) // End performance measurement and show stats
*
*
* EX5 Program info
*
* A special macro is defined to deliver program information and can be
* displyed ie at program start. (Very helpful to determin if the program is
* running in debug or release mode)
*
* DBG_STR_EX45_FILEINFO // EX4/EX5 program information
*
*
* Available configuration options:
*
* Basic settings are exposed below. Here is a full list of options:
*
* Functional options:
*
* LIB_DEBUG // Force enable debugging support
* LIB_PERF_PROFILING // Enable performance counters (Only in release mode)
* DBG_VARDUMP_PAUSE // Vardump pause before continuing execution
* DBG_SOFT_BKP_TIMEOUT // Breakpoint timeout before continuing execution, for soft break-points (a type of sleep-command)
* DBG_TRACE_EXEC_DELAY_MS // When tracing function calls, this will insert a delay in execution
* DBG_CRASH_CODE // Code used to crash the program if an assert() fails
*
* Output format options:
*
* DBG_ASSERT_MSG_TXT // Prefix to assert messages
* DBG_TRACE_BEGIN_MSG_TXT // Trace function call begin prefix
* DBG_TRACE_END_MSG_TXT // Trace function call end prefix
* DBG_OUTPUT_PREFIX // General debug output prefix
* DBG_OUTPUT_FORMAT // Format string applied to debug output
* DBG_DOUBLE_OUTPUT_DIGITS // Digits debugger wil loutput on double values
*
* If not defined, the default applies automatically.
*
* Following list of defaults is configured as preset:
*
* DBG_SOFT_BKP_TIMEOUT 120 // Wait 2 minutes
* DBG_TRACE_EXEC_DELAY_MS 0x00 // Disabled by default
* DBG_CRASH_CODE { int i = 1; i = (i / (i - i)); } // Zero divide abnormal program termination
*
* DBG_ASSERT_MSG_TXT "### --- Assertion failed!"
* DBG_TRACE_BEGIN_MSG_TXT ">>>Function begin<<<"
* DBG_TRACE_END_MSG_TXT ">>>Function end<<<"
* DBG_OUTPUT_PREFIX " " // Four white spaces
* DBG_OUTPUT_STRING "%s%s, %s, line: %i%s"
* DBG_OUTPUT_FORMAT DBG_OUTPUT_STRING, ((prefix == NULL) ? NULL : prefix + ", "), __FILE__, __FUNCSIG__, __LINE__, ((message == NULL) ? NULL : ", " + message)
* DBG_DOUBLE_OUTPUT_DIGITS SymbolInfoInteger(Symbol(), SYMBOL_DIGITS)
*
*/
//////////////////////////////////////////
//
// Remove this for full support of
// the calendar structure.
//
// The validation-process is not capable
// of compiling this file correctly.
// Reason seems to be because some falues
// of this structure are retrieved by
// function call.
//
// Structure in concern:
// MqlCalendarValue
//
//#define __MQLPUBLISHING__
//////////////////////////////////////////
//
// Debugger switches and definitions
//
// Force enable debugger
//#define LIB_DEBUG
// Force enable MQL API function call tracing (experimental feature!!! - No docs provided jet)
//#define LIB_MQLAPI_CALL_TRACING_ENABLED
// Force disable MQL API function call tracing
//#define LIB_MQLAPI_CALL_TRACING_DISABLE
// Enable performance tracer
//#define LIB_PERF_PROFILING
// Pause execution after a vardump calls
#define DBG_VARDUMP_PAUSE 0
// Soft breakpoint timeout in seconds
//#define DBG_SOFT_BKP_TIMEOUT 120
// Execution delay inserted into trace runs in milliseconds
//#define DBG_TRACE_EXEC_DELAY_MS 25
// Crash code definition
//#define DBG_CRASH_CODE { int i = 1; i = (i / (i - i)); }
//
//////////////////////////////////////////
//////////////////////////////////////////
//
// Debugger output format setup
//
// Set default assert message
//#define DBG_ASSERT_MSG_TXT "### --- Assertion failed!"
// Set default trace begin messages
//#define DBG_TRACE_BEGIN_MSG_TXT ">>>Function begin<<<"
// Set default trace end messages
//#define DBG_TRACE_END_MSG_TXT ">>>Function end<<<"
// Default output prefix
//#define DBG_OUTPUT_PREFIX " "
// Default file location string
//#define DBG_CODE_LOCATION_STRING __FILE__, __FUNCTION__, __LINE__
// Output format definition
//#define DBG_OUTPUT_STRING "%s>%s< %s(){ @%i: %s }"
//#define DBG_OUTPUT_FORMAT(prefix, message) DBG_OUTPUT_STRING, ((prefix == "") ? "" : prefix + " "), DBG_CODE_LOCATION_STRING, message
// Float and double output precision
//#define DBG_FLOAT_OUTPUT_DIGITS SymbolInfoInteger(Symbol(), SYMBOL_DIGITS)
//#define DBG_DOUBLE_OUTPUT_DIGITS SymbolInfoInteger(Symbol(), SYMBOL_DIGITS)
//
//////////////////////////////////////////
//*********************************************************************************************************************************************************/
// Debugging support
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Auto enable/disable by environment
//
// Autoenable
#ifdef _DEBUG
#ifndef LIB_DEBUG
#define LIB_DEBUG
#endif
#define DBG_DEBUGGER_FLAG ((LIB_DBG_NAMESPACE(dbg_lib, dbg_MQLInfoInteger)(MQL_DEBUG)) ? "MQL_DEBUG set" : "_DEBUG defined")
#endif
// Environment check
#ifndef __MQL5__
#ifndef __MQL4_COMPATIBILITY_CODE__
#define __MQL4_COMPATIBILITY_CODE__
#endif
#ifndef LIB_DBG_NAMESPACE
#define LIB_DBG_NAMESPACE(x, y) x##_##y
#endif
#ifndef LIB_DBG_NAMESPACE_DEF
#define LIB_DBG_NAMESPACE_DEF(x, y) LIB_DBG_NAMESPACE(x, y)
#endif
#else
#ifndef LIB_DBG_NAMESPACE
#define LIB_DBG_NAMESPACE(x, y) x::y
#endif
#ifndef LIB_DBG_NAMESPACE_DEF
#define LIB_DBG_NAMESPACE_DEF(x, y) y
#endif
#endif
// Custom MQLplus expert remove reasons
#ifndef REASON_MQLPLUS_EXPERT_KILL
#define REASON_MQLPLUS_EXPERT_KILL 0xFF01
#endif
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef LIB_DEBUG
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Debugger mode
//
// By default disable mql api tracing
#ifndef LIB_DEBUG_MQLAPI
#define LIB_MQLAPI_CALL_TRACING_DISABLE
#endif
// Set debugging mode
#define LIB_DBG_DEBUG_MQH_DEBUG_MODE
// Set _DEBUG flag if not set
#ifndef _DEBUG
#define _DEBUG false
#endif
// Clear any existing definitions
#ifdef DBG_CODE_LOCATION
#undef DBG_CODE_LOCATION
#endif
#ifdef DBG_DEBUGGER_FLAG_STATE
#undef DBG_DEBUGGER_FLAG_STATE
#endif
#ifdef DBG_STR_EX45_FILEINFO
#undef DBG_STR_EX45_FILEINFO
#endif
#ifdef DBG_STR
#undef DBG_STR
#endif
#ifdef DBG_STR_PERSIST
#undef DBG_STR_PERSIST
#endif
#ifdef DBG_STR_VAR
#undef DBG_STR_VAR
#endif
#ifdef DBG_STR_BOOL
#undef DBG_STR_BOOL
#endif
#ifdef DBG_MSG
#undef DBG_MSG
#endif
#ifdef DBG_MSG_SHIFT
#undef DBG_MSG_SHIFT
#endif
#ifdef DBG_MSG_PERSIST
#undef DBG_MSG_PERSIST
#endif
#ifdef DBG_MSG_VAR
#undef DBG_MSG_VAR
#endif
#ifdef DBG_MSG_VAR_IF
#undef DBG_MSG_VAR_IF
#endif
#ifdef DBG_MSG_VARDUMP
#undef DBG_MSG_VARDUMP
#endif
#ifdef DBG_MSG_LISTDUMP
#undef DBG_MSG_LISTDUMP
#endif
#ifdef DBG_MSG_TRACE_BEGIN
#undef DBG_MSG_TRACE_BEGIN
#endif
#ifdef DBG_MSG_TRACE_END
#undef DBG_MSG_TRACE_END
#endif
#ifdef DBG_MSG_TRACE_RETURN
#undef DBG_MSG_TRACE_RETURN
#endif
#ifdef DBG_MSG_TRACE_RETURN_VAR
#undef DBG_MSG_TRACE_RETURN_VAR
#endif
#ifdef DBG_MSG_NOTRACE_RETURN
#undef DBG_MSG_NOTRACE_RETURN
#endif
#ifdef DBG_MSG_NOTRACE_RETURN_VAR
#undef DBG_MSG_NOTRACE_RETURN_VAR
#endif
#ifdef DBG_SET_UNINIT_REASON
#undef DBG_SET_UNINIT_REASON
#endif
#ifdef DBG_MSG_UNINIT_RESOLVER
#undef DBG_MSG_UNINIT_RESOLVER
#endif
#ifdef DBG_STR_COMMENT
#undef DBG_STR_COMMENT
#endif
#ifdef DBG_FILELOADER_VARNAME
#undef DBG_FILELOADER_VARNAME
#endif
#ifdef DBG_MSG_TRACE_FILE_LOADER
#undef DBG_MSG_TRACE_FILE_LOADER
#endif
#ifdef DBG_ASSERT
#undef DBG_ASSERT
#endif
#ifdef DBG_ASSERT_LOG
#undef DBG_ASSERT_LOG
#endif
#ifdef DBG_ASSERT_RETURN
#undef DBG_ASSERT_RETURN
#endif
#ifdef DBG_ASSERT_RETURN_VAR
#undef DBG_ASSERT_RETURN_VAR
#endif
#ifdef DBG_STOP_ARRAY_OUT_OF_RANGE
#undef DBG_STOP_ARRAY_OUT_OF_RANGE
#endif
#ifdef DBG_SLEEP_SECONDS
#undef DBG_SLEEP_SECONDS
#endif
#ifdef DBG_SOFT_BREAKPOINT
#undef DBG_SOFT_BREAKPOINT
#endif
#ifdef DBG_SOFT_BREAKPOINT_TS
#undef DBG_SOFT_BREAKPOINT_TS
#endif
#ifdef DBG_SOFT_BREAKPOINT_CONDITION
#undef DBG_SOFT_BREAKPOINT_CONDITION
#endif
#ifdef DBG_SOFT_BREAKPOINT_EXEC_TIME
#undef DBG_SOFT_BREAKPOINT_EXEC_TIME
#endif
#ifdef DBG_BREAK_CONDITION_CREATE
#undef DBG_BREAK_CONDITION_CREATE
#endif
#ifdef DBG_BREAK_CONDITION_ACTIVATE
#undef DBG_BREAK_CONDITION_ACTIVATE
#endif
#ifdef DBG_BREAK_CONDITION_DEACTIVATE
#undef DBG_BREAK_CONDITION_DEACTIVATE
#endif
#ifdef DBG_BREAK_CONDITION_ON_ID
#undef DBG_BREAK_CONDITION_ON_ID
#endif
#ifdef DBG_TRACE_LOOP_BEGIN
#undef DBG_TRACE_LOOP_BEGIN
#endif
#ifdef DBG_TRACE_LOOP_START
#undef DBG_TRACE_LOOP_START
#endif
#ifdef DBG_TRACE_LOOP_FINISH
#undef DBG_TRACE_LOOP_FINISH
#endif
#ifdef DBG_TRACE_LOOP_END
#undef DBG_TRACE_LOOP_END
#endif
#ifdef DBG_TRACE_LOOP_BEGIN_ID
#undef DBG_TRACE_LOOP_BEGIN_ID
#endif
#ifdef DBG_TRACE_LOOP_START_ID
#undef DBG_TRACE_LOOP_START_ID
#endif
#ifdef DBG_TRACE_LOOP_FINISH_ID
#undef DBG_TRACE_LOOP_FINISH_ID
#endif
#ifdef DBG_TRACE_LOOP_END_ID
#undef DBG_TRACE_LOOP_END_ID
#endif
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Debugger default configuration
//
// Code location string
#ifndef DBG_CODE_LOCATION_STRING
#define DBG_CODE_LOCATION_STRING __FILE__, __FUNCTION__, __LINE__
#endif
#define DBG_CODE_LOCATION(x) LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%s %s %s %i", x, DBG_CODE_LOCATION_STRING)
// Output message format definition
#ifndef DBG_OUTPUT_FORMAT
#define DBG_OUTPUT_STRING "%s>%s< %s(){ @%i: %s }"
#define DBG_OUTPUT_FORMAT(prefix, message) DBG_OUTPUT_STRING, ((prefix == "") ? "" : prefix + " "), DBG_CODE_LOCATION_STRING, message
#endif
// Output trace begin format definition
#ifndef DBG_OUTPUT_TRACE_BEGIN_FORMAT
#define DBG_OUTPUT_TRACE_BEGIN_FORMAT " V-V-V-V-V [ Chart-ID: %i :: Call depth: %-3i] V-V-V-V-V [ %s() BEGIN ] V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V"
#endif
// Output trace end format definition
#ifndef DBG_OUTPUT_TRACE_END_FORMAT
#define DBG_OUTPUT_TRACE_END_FORMAT " A-A-A-A-A [ Call depth: %-3i] A-A-A-A-A [ %s() END ] A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A"
#endif
// Set default api tracing behaviour
#ifdef LIB_MQLAPI_CALL_TRACING_ENABLED
#define LIB_DBG_API_CALL_TRACE_DEFAULT true
#else
#define LIB_DBG_API_CALL_TRACE_DEFAULT false
#endif
// Force disable mql api tracing
#ifdef LIB_MQLAPI_CALL_TRACING_DISABLE
#undef LIB_MQLAPI_CALL_TRACING_ENABLED
#undef LIB_DBG_API_CALL_TRACE_DEFAULT
#define LIB_DBG_API_CALL_TRACE_DEFAULT false
#endif
// Float output precision
#ifndef DBG_FLOAT_OUTPUT_DIGITS
#define DBG_FLOAT_OUTPUT_DIGITS 9
#endif
// Double output precision
#ifndef DBG_DOUBLE_OUTPUT_DIGITS
#define DBG_DOUBLE_OUTPUT_DIGITS 16
#endif
// Crash code definition
#ifndef DBG_CRASH_CODE
#define DBG_CRASH_CODE { int i = 1; i = (i / (i - i)); }
#endif
// Set default assert message
#ifndef DBG_ASSERT_MSG_TXT
#define DBG_ASSERT_MSG_TXT "### --- Assertion failed!"
#endif
// Set default trace begin messages
#ifndef DBG_TRACE_BEGIN_MSG_TXT
#define DBG_TRACE_BEGIN_MSG_TXT ">>>Function begin<<<"
#endif
// Set default trace end messages
#ifndef DBG_TRACE_END_MSG_TXT
#define DBG_TRACE_END_MSG_TXT ">>>Function end<<<"
#endif
// Default output prefix
#ifndef DBG_OUTPUT_PREFIX
#define DBG_OUTPUT_PREFIX " "
#endif
// Overwrite mode
#ifndef DBG_DEBUGGER_FLAG
#define DBG_DEBUGGER_FLAG "LIB_DEBUG overwrite mode"
#define DBG_DEBUGGER_OVERWRITE
#endif
// Soft breakpoint timeout in seconds
#ifndef DBG_SOFT_BKP_TIMEOUT
#define DBG_SOFT_BKP_TIMEOUT 120
#endif
// Turn off execution profiler
#ifdef LIB_PERF_PROFILING
#undef LIB_PERF_PROFILING
#endif
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Internal helper definitions
//
#ifndef __MQL4_COMPATIBILITY_CODE__
#define LIB_DBG_GETTICKCOUNT GetTickCount64
#else
#define LIB_DBG_GETTICKCOUNT GetTickCount
#endif
// Soft breakpoint timeout command
#define DBG_SLEEP_MILLISECONDS(x) { ulong dbg_sleep_seconds_delay = (LIB_DBG_NAMESPACE(dbg_lib, dbg_GetTickCount)() + (x)); while((!_DEBUG) && (!_StopFlag) && (dbg_sleep_seconds_delay > LIB_DBG_NAMESPACE(dbg_lib, dbg_GetTickCount)())); }
#define DBG_SLEEP_SECONDS(x) DBG_SLEEP_MILLISECONDS((x * 1000))
// Execution delay
#ifdef DBG_TRACE_EXEC_DELAY_MS
#define DBG_TRACE_EXEC_DELAY DBG_SLEEP_MILLISECONDS(DBG_TRACE_EXEC_DELAY_MS)
#define DBG_STR_TRACE_EXEC_DELAY_INFO LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("Debug trace execution delay: %i ms", DBG_TRACE_EXEC_DELAY_MS)
#else
#define DBG_TRACE_EXEC_DELAY
#define DBG_STR_TRACE_EXEC_DELAY_INFO ""
#endif
// Debugger state string
#define DBG_DEBUGGER_FLAG_STATE "[DEBUG]"
// Debugger runtime flag state
#define DBG_DEBUGGER_RUNTIME_STATE LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("IS_DEBUG_MODE = %s\r\n %s", (IS_DEBUG_MODE) ? "true" : "false", DBG_STR_TRACE_EXEC_DELAY_INFO)
// EX5 and terminal info string
#ifndef __MQL4_COMPATIBILITY_CODE__
#define DBG_STR_EX45_FILEINFO LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("MQL5 compiler build: %i %s\r\n compiled@%s\r\n => %s\r\n %s\r\n %s", __MQL5BUILD__, DBG_DEBUGGER_FLAG_STATE, LIB_DBG_NAMESPACE(dbg_lib, dbg_TimeToString)(__DATETIME__), DBG_DEBUGGER_FLAG_STATE, DBG_DEBUGGER_FLAG, DBG_DEBUGGER_RUNTIME_STATE)
#else
#define DBG_STR_EX45_FILEINFO LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("MQL4 Terminal build: %i\n compiler build: %i %s\n compiled@%s\n => %s\n %s\n %s", LIB_DBG_NAMESPACE(dbg_lib, dbg_TerminalInfoInteger)(TERMINAL_BUILD), __MQL4BUILD__, DBG_DEBUGGER_FLAG_STATE, LIB_DBG_NAMESPACE(dbg_lib, dbg_TimeToString)(__DATETIME__), DBG_DEBUGGER_FLAG_STATE, DBG_DEBUGGER_FLAG, DBG_DEBUGGER_RUNTIME_STATE)
#endif
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Debugger helpers
//
// Debug to string functions
#define DBG_STR(x) LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_FORMAT("", x))
#define DBG_STR_PERSIST(x) DBG_STR(x)
#define DBG_STR_VAR(x) (LIB_DBG_NAMESPACE(dbg_lib, var_out)(#x, x, DBG_MSG_SHIFT))
// #define DBG_STR_BOOL(x) ((x) ? "True" : "False")
#define DBG_STR_BITS(x) DBG_STR(LIB_DBG_NAMESPACE(dbg_lib, bits_out)(x))
// Debug std out
#ifndef __MQL4_COMPATIBILITY_CODE__
#define DBG_MSG(x) LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%*s%s", LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2, "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT("", (x))))
#define DBG_MSG_MQLAPI(x) LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)((LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls)) ? "%*s%s" : "", LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2, "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT("", (x))))
#define DBG_MSG_SHIFT (LIB_DBG_NAMESPACE(dbg_lib, dbg_StringLen)(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%*s%s", LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2, "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT("", (""))))) - 2)
#else
#define DBG_MSG(x) LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%"+ LIB_DBG_NAMESPACE(dbg_lib, dbg_IntegerToString)(LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2) +"s%s", "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT("", (x))))
#define DBG_MSG_MQLAPI(x) LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)((LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls)) ? "%"+ LIB_DBG_NAMESPACE(dbg_lib, dbg_IntegerToString)(LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2) +"s%s" : "", "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT("", (x))))
#define DBG_MSG_SHIFT (LIB_DBG_NAMESPACE(dbg_lib, dbg_StringLen)(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%"+ LIB_DBG_NAMESPACE(dbg_lib, dbg_IntegerToString)(LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2) +"s%s", "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT("", (""))))) - 2)
#endif
#define DBG_MSG_IF(c, x) { if(c) { DBG_MSG(x); } }
#define DBG_MSG_PERSIST(x) DBG_MSG(x)
#define DBG_MSG_VAR(x) DBG_MSG(DBG_STR_VAR((x)))
#define DBG_MSG_VAR_IF(c, x) DBG_MSG_IF(c, DBG_STR_VAR((x)))
#define DBG_MSG_BITS(x) DBG_MSG(DBG_STR_BITS(x))
#ifndef __MQL4_COMPATIBILITY_CODE__
#define DBG_MSG_MQLFUNC(x) DBG_MSG_MQLAPI(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)((LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls)) ? "MQL5-API Function => %s() [void]" : "", #x)); ::x
#define DBG_MSG_MQLFUNC_RETURN(x) LIB_DBG_NAMESPACE(dbg_lib, dbg_mql_api_retval).msg(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%*s%s", LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2, "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT("", (LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%s => %s() %35s", "MQL5-API Function", #x, "%s")))))) = ::x
#define DBG_MSG_MQLFUNC_PTR(x) LIB_DBG_NAMESPACE(dbg_lib, dbg_mql_api_retval_ptr).msg(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%*s%s", LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2, "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT("", (LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%s => %s() %s", "MQL5-API Function", #x, "%s")))))) = ::x
#else
#define DBG_MSG_MQLFUNC(x) DBG_MSG_MQLAPI(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)((LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls)) ? "MQL4-API Function => %s() [void]" : "", #x)); } x
#define DBG_MSG_MQLFUNC_RETURN(x) LIB_DBG_NAMESPACE(dbg_lib, dbg_mql_api_retval).msg(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%*s%s", LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2, "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT("", (LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%s => %s() %s", "MQL4-API Function", #x, "%s")))))) = x
#define DBG_MSG_MQLFUNC_PTR(x) LIB_DBG_NAMESPACE(dbg_lib, dbg_mql_api_retval_ptr).msg(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%*s%s", LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2, "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT("", (LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%s => %s() %s", "MQL4-API Function", #x, "%s")))))) = x
#endif
// Code tracing helpers
#ifndef __MQL4_COMPATIBILITY_CODE__
#define DBG_MSG_TRACE_BEGIN { LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls) = true; LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth)++; printf("\r\n%*s%s", LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth )* 2, "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT(DBG_TRACE_BEGIN_MSG_TXT, LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_TRACE_BEGIN_FORMAT, LIB_DBG_NAMESPACE(dbg_lib, dbg_ChartID)(), dbg_lib::trace_call_depth, __FUNCTION__)))); }
#define DBG_MSG_TRACE_END { LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%*s%s", LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2, "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT(DBG_TRACE_END_MSG_TXT, LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_TRACE_END_FORMAT, dbg_lib::trace_call_depth, __FUNCTION__)))); printf("%s", " "); dbg_lib::trace_call_depth--; DBG_TRACE_EXEC_DELAY; LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls) = LIB_DBG_API_CALL_TRACE_DEFAULT; }
#else
#define DBG_MSG_TRACE_BEGIN { LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls) = true; LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth)++; printf("\r\n%"+ LIB_DBG_NAMESPACE(dbg_lib, dbg_IntegerToString)(LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth )* 2) +"s%s", "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT(DBG_TRACE_BEGIN_MSG_TXT, LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_TRACE_BEGIN_FORMAT, LIB_DBG_NAMESPACE(dbg_lib, dbg_ChartID)(), dbg_lib::trace_call_depth, __FUNCTION__)))); }
#define DBG_MSG_TRACE_END { LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%"+ LIB_DBG_NAMESPACE(dbg_lib, dbg_IntegerToString)(LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2) +"s%s", "", LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_FORMAT(DBG_TRACE_END_MSG_TXT, LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_TRACE_END_FORMAT, dbg_lib::trace_call_depth, __FUNCTION__)))); printf("%s", " "); dbg_lib::trace_call_depth--; DBG_TRACE_EXEC_DELAY; LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls) = LIB_DBG_API_CALL_TRACE_DEFAULT; }
#endif
#define DBG_MSG_TRACE_RETURN LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls) = LIB_DBG_API_CALL_TRACE_DEFAULT; DBG_MSG("=> return(void)"); DBG_MSG_UNINIT_RESOLVER DBG_MSG_TRACE_END return
#define DBG_MSG_TRACE_RETURN_VAR(x) LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls) = LIB_DBG_API_CALL_TRACE_DEFAULT; return(LIB_DBG_NAMESPACE(dbg_lib, return_function_result)(#x, x, LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_PREFIX + DBG_OUTPUT_STRING, "%s", DBG_CODE_LOCATION_STRING, "%s"), __FUNCTION__))
#define DBG_MSG_NOTRACE_RETURN return
#define DBG_MSG_NOTRACE_RETURN_VAR(x) return(x)
// Debug comments
#define DBG_SET_UNINIT_REASON(x) LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason) = x;
#define DBG_MSG_UNINIT_RESOLVER if(_StopFlag) { DBG_MSG_VAR(_StopFlag); } LIB_DBG_NAMESPACE(dbg_lib, uninit_text)(__FUNCTION__);
#define DBG_STR_COMMENT(cmnt) cmnt
// File loading tracer
#ifndef __MQL4_COMPATIBILITY_CODE__
#define DBG_FILE_VARNAME(x) dbg_file_loader_##x
#define DBG_MSG_TRACE_FILE_LOADER static bool DBG_FILE_VARNAME(__COUNTER__) = LIB_DBG_NAMESPACE(dbg_lib, dbg_print_file_trace)(__FILE__);
#else
#define DBG_MSG_TRACE_FILE_LOADER
#endif
// Class and object polymorphism
#define DBG_STR_OBJ_RTTI DBG_STR(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%s %d", typename(this), &this))
#define DBG_MSG_OBJ_RTTI DBG_MSG(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("%s %d", typename(this), &this))
// Overloaded var_out function
#ifndef LIB_DEBUG_NAMESPACE
#ifndef __MQL4_COMPATIBILITY_CODE__
namespace dbg_lib
{
#endif
// 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)(const 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); }
long LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ChartID)() { return(ChartID()); }
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_DebugBreak)() { DebugBreak(); }
ulong LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_GetMicrosecondCount)() { return(GetMicrosecondCount()); }
ulong LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_GetTickCount)() { return(LIB_DBG_GETTICKCOUNT()); }
string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_IntegerToString)(const long p_in) { return(IntegerToString(p_in)); }
long LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_MQLInfoInteger)(const ENUM_MQL_INFO_INTEGER p_in) { return(MQLInfoInteger(p_in)); }
string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_MQLInfoString)(const ENUM_MQL_INFO_STRING p_in) { return(MQLInfoString(p_in)); }
int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_StringLen)(const string p_in) { return(StringLen(p_in)); }
datetime LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_StringToTime)(const string p_in) { return(StringToTime(p_in)); }
long LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_TerminalInfoInteger)(const ENUM_TERMINAL_INFO_INTEGER p_in) { return(TerminalInfoInteger(p_in)); }
string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_TerminalInfoString)(const ENUM_TERMINAL_INFO_STRING p_in) { return(TerminalInfoString(p_in)); }
datetime LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_TimeCurrent)() { return(TimeCurrent()); }
template <typename T>
string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_StringFormat)(const string p1, const T p2) { return(StringFormat(p1, p2)); }
template <typename T, typename U>
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>
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>
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>
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>
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)); }
// MQL Function return value message injection object
static class pass_through
{ public:
string _msg;
pass_through() : _msg (NULL) { };
pass_through(const pass_through& s) { _msg = s._msg; }
pass_through msg(const string in) { _msg = in; ResetLastError(); return(this); }
template <typename T> T operator=(T in) {
if(LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls))
{
const int err_no = GetLastError();
printf("%s", StringFormat(_msg, (err_no != ERR_SUCCESS) ? StringFormat("error: %i", err_no) : LIB_DBG_NAMESPACE(dbg_lib, var_out)("returns", in, NULL, "", 45)));
_msg = NULL;
}
return(in);
}
} LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mql_api_retval);
static class pass_through_ptr
{ public:
string _msg;
pass_through_ptr() : _msg (NULL) { };
pass_through_ptr(const pass_through_ptr& s) { _msg = s._msg; }
pass_through_ptr msg(const string in) { _msg = in; ResetLastError(); return(this); }
template <typename T> T* operator=(T in) {
if(LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls))
{
const int err_no = GetLastError();
printf("%s", StringFormat(_msg, (err_no != ERR_SUCCESS) ? StringFormat("error: %i", err_no) : LIB_DBG_NAMESPACE(dbg_lib, var_out)("returns", in, NULL, "", 45)));
_msg = NULL;
}
return(in);
}
} LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mql_api_retval_ptr);
// Auto en/disable api call tracing
static bool LIB_DBG_NAMESPACE_DEF(dbg_lib, trace_api_calls) = LIB_DBG_API_CALL_TRACE_DEFAULT;
// Debug mql function call resolver
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1)
#ifndef __MQL4_COMPATIBILITY_CODE__
{ if((p1 != NULL) && (p1 != "")) { printf(p1); } }
#else
{
static int ptr = NULL;
static string out_arr[];
if(LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls))
{
ArrayResize(out_arr, ptr + 1);
out_arr[ptr] = p1;
ptr++;
return;
}
if(ptr != NULL)
{
for(; (ptr > NULL) && !_StopFlag; ptr--) { printf(out_arr[ptr]); }
ptr = NULL;
ArrayFree(out_arr);
return;
}
printf(p1);
}
#endif
template <typename T>
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1, const T p2)
#ifndef __MQL4_COMPATIBILITY_CODE__
{ if((p1 != NULL) && (p1 != "")) { printf(p1, p2); } }
#else
{
static int ptr = NULL;
static string out_arr[];
if(LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls))
{
ArrayResize(out_arr, ptr + 1);
out_arr[ptr] = StringFormat(p1, p2);
ptr++;
return;
}
if(ptr != NULL)
{
for(; (ptr > NULL) && !_StopFlag; ptr--) { printf(out_arr[ptr]); }
ptr = NULL;
ArrayFree(out_arr);
return;
}
printf(p1, p2);
}
#endif
template <typename T, typename U>
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1, const T p2, const U p3)
#ifndef __MQL4_COMPATIBILITY_CODE__
{ if((p1 != NULL) && (p1 != "")) { printf(p1, p2, p3); } }
#else
{
static int ptr = NULL;
static string out_arr[];
if(LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls))
{
ArrayResize(out_arr, ptr + 1);
out_arr[ptr] = StringFormat(p1, p2, p3);
ptr++;
return;
}
if(ptr != NULL)
{
for(; (ptr > NULL) && !_StopFlag; ptr--) { printf(out_arr[ptr]); }
ptr = NULL;
ArrayFree(out_arr);
return;
}
printf(p1, p2, p3);
}
#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)
#ifndef __MQL4_COMPATIBILITY_CODE__
{ if((p1 != NULL) && (p1 != "")) { printf(p1, p2, p3, p4); } }
#else
{
static int ptr = NULL;
static string out_arr[];
if(LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls))
{
ArrayResize(out_arr, ptr + 1);
out_arr[ptr] = StringFormat(p1, p2, p3, p4);
ptr++;
return;
}
if(ptr != NULL)
{
for(; (ptr > NULL) && !_StopFlag; ptr--) { printf(out_arr[ptr]); }
ptr = NULL;
ArrayFree(out_arr);
return;
}
printf(p1, p2, p3, p4);
}
#endif
// Debug file loader trace function
const bool LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_print_file_trace)(const string _file) { static int cnt = NULL; printf("Loaded file: %s, count: %i", _file, cnt + 1); cnt++; return(true); }
// Debug code variables
static int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_uninit_reason) = NULL;
static int LIB_DBG_NAMESPACE_DEF(dbg_lib, trace_call_depth) = NULL;
// Helpers
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, flt_raw)(const float in) { union conv { float f; uint u; } c; c.f = in; return(StringFormat("0x%08X", c.u)); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbl_raw)(const double in) { union conv { double d; ulong u; } c; c.d = in; return(StringFormat("0x%016llX", c.u)); }
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" + ((ms) ? ".%03i" : ""), TimeToString(_val, TIME_DATE | TIME_SECONDS), (ms) ? val%1000 : NULL)); }
// Basic types
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const char val, const int shift = 0, const string prefix = "", const int offset = 0, const bool hex = true) { return(StringFormat("%s[chr] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %-25hd (%s)", prefix, name, val, (hex) ? StringFormat("0x%02hX", (uchar)val) : LIB_DBG_NAMESPACE(dbg_lib, bits_out)((uchar)val))); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const short val, const int shift = 0, const string prefix = "", const int offset = 0, const bool hex = true) { return(StringFormat("%s[shrt] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %-25hi (%s)", prefix, name, val, (hex) ? StringFormat("0x%04hX", val) : LIB_DBG_NAMESPACE(dbg_lib, bits_out)((ushort)val))); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const int val, const int shift = 0, const string prefix = "", const int offset = 0, const bool hex = true) { return(StringFormat("%s[int] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %-25i (%s)", prefix, name, val, (hex) ? StringFormat("0x%08X", val) : LIB_DBG_NAMESPACE(dbg_lib, bits_out)((uint)val))); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const long val, const int shift = 0, const string prefix = "", const int offset = 0, const bool hex = true) { return(StringFormat("%s[long] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %-25lli (%s)", prefix, name, val, (hex) ? StringFormat("0x%016llX", val) : LIB_DBG_NAMESPACE(dbg_lib, bits_out)((ulong)val))); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const uchar val, const int shift = 0, const string prefix = "", const int offset = 0, const bool hex = true) { return(StringFormat("%s[uchr] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %-25hu (%s)", prefix, name, val, (hex) ? StringFormat("0x%02hX", val) : LIB_DBG_NAMESPACE(dbg_lib, bits_out)(val))); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const ushort val, const int shift = 0, const string prefix = "", const int offset = 0, const bool hex = true) { return(StringFormat("%s[usht] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %-25hu (%s)", prefix, name, val, (hex) ? StringFormat("0x%04hX", val) : LIB_DBG_NAMESPACE(dbg_lib, bits_out)(val))); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const uint val, const int shift = 0, const string prefix = "", const int offset = 0, const bool hex = true) { return(StringFormat("%s[uint] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %-25u (%s)", prefix, name, val, (hex) ? StringFormat("0x%08X", val) : LIB_DBG_NAMESPACE(dbg_lib, bits_out)(val))); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const ulong val, const int shift = 0, const string prefix = "", const int offset = 0, const bool hex = true) { return(StringFormat("%s[ul] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %-25llu (%s)", prefix, name, val, (hex) ? StringFormat("0x%016llX", val) : LIB_DBG_NAMESPACE(dbg_lib, bits_out)(val))); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const string val, const int shift = 0, const string prefix = "", const int offset = 0) { return(StringFormat("%s[str] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = '%s'", prefix, name, (val == NULL) ? "NULL" : ((val == "") ? "" : val))); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const float val, const int shift = 0, const string prefix = "", const int offset = 0) { return(StringFormat("%s[flt] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %-25s (%s)", prefix, name, StringFormat("%." + IntegerToString(DBG_FLOAT_OUTPUT_DIGITS) + "f", val), LIB_DBG_NAMESPACE_DEF(dbg_lib, flt_raw)(val))); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const double val, const int shift = 0, const string prefix = "", const int offset = 0) { return(StringFormat("%s[dbl] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %-25s (%s)", prefix, name, StringFormat("%." + IntegerToString(DBG_DOUBLE_OUTPUT_DIGITS) + "f", val), LIB_DBG_NAMESPACE_DEF(dbg_lib, dbl_raw)(val))); }
#ifndef __MQL4_COMPATIBILITY_CODE__
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const complex val, const int shift = 0, const string prefix = "", const int offset = 0) { return(StringFormat("%s[cplx] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %-25s %s (r:%s i:%s)", prefix, name, StringFormat("r:%." + IntegerToString(DBG_DOUBLE_OUTPUT_DIGITS) + "f", val.real), StringFormat("r:%." + IntegerToString(DBG_DOUBLE_OUTPUT_DIGITS) + "f", val.imag), LIB_DBG_NAMESPACE_DEF(dbg_lib, dbl_raw)(val.real), LIB_DBG_NAMESPACE_DEF(dbg_lib, dbl_raw)(val.imag))); }
#endif
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const bool val, const int shift = 0, const string prefix = "", const int offset = 0) { return(StringFormat("%s[bool] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %s", prefix, name, (val) ? "true" : "false")); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const datetime val, const int shift = 0, const string prefix = "", const int offset = 0) { return(StringFormat("%s[dtm] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %s", prefix, name, (val == NULL) ? "NULL" : ((val < NULL) ? StringFormat("[NEGATIVE VALUE] %lli", val) : ((StringLen(LIB_DBG_NAMESPACE(dbg_lib, dbg_TimeToString)(val)) <= NULL) ? StringFormat("[NON DATE VALUE] %llu", val) : LIB_DBG_NAMESPACE(dbg_lib, dbg_TimeToString)(val)) ))); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const color val, const int shift = 0, const string prefix = "", const int offset = 0, const bool hex = true) { return(StringFormat("%s[clr] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = %-25s (%s)", prefix, name, ColorToString(val, true), (hex) ? StringFormat("0x%08X", val) : LIB_DBG_NAMESPACE(dbg_lib, bits_out)((uint)val))); }
// Pointers
template <typename T>
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const T* val, const int shift = 0, const string prefix = "", const int offset = 0) { return(StringFormat("%s[ptr] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL)) + "s = '%s'", prefix, name, (val == NULL) ? "NULL" : typename(val) + "*")); }
// Enumerations
template <typename T>
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const T val, const int shift = 0, const string prefix = "", const int offset = 0) { string enum_val = EnumToString((T)val); StringReplace(enum_val, typename(val), ""); const int idx = StringFind(name, typename(val)); return(StringFormat("%s[%s] %-" + IntegerToString(60 - ((offset < 60) ? offset : NULL) - ((idx == -1) ? (StringLen(typename(val)) - 4) : NULL)) + "s = %-25s (0x%08X)", prefix, (idx != -1) ? "enum" : typename(val), name, enum_val, (uint)(val))); }
// Arrays
template <typename T>
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const T& val[], const int shift = 0, const string prefix = "", const int offset = 0) { const int elements = ArraySize(val); string __out = NULL; for(int cnt = NULL; (cnt < elements) && (!_StopFlag); cnt++) { __out += "\n" + LIB_DBG_NAMESPACE(dbg_lib, var_out)(StringFormat("%s[%i]", name, cnt), val[cnt], shift, prefix); } return(__out); }
// Mql types
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const MqlDateTime& val, const int shift = 0, const string prefix = "{MqlDateTime} ", const int offset = 0)
{
const string _shift = StringFormat("%" + IntegerToString(shift) + "s", "");
return(StringFormat("%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s",
LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".year", val.year, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".mon", val.mon, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".day", val.day, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".hour", val.hour, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".min", val.min, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".sec", val.sec, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".day_of_week", val.day_of_week, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".day_of_year", val.day_of_year, NULL, prefix)
)); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const MqlRates& val, const int shift = 0, const string prefix = "{MqlRates} ", const int offset = 0)
{
const string _shift = StringFormat("%" + IntegerToString(shift) + "s", "");
return(StringFormat("%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s",
LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".time", val.time, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".open", val.open, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".high", val.high, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".low", val.low, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".close", val.close, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".tick_volume", val.tick_volume, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".spread", val.spread, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".real_volume", val.real_volume, NULL, prefix)
)); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const MqlTick& val, const int shift = 0, const string prefix = "{MqlTick} ", const int offset = 0)
{
const string _shift = StringFormat("%" + IntegerToString(shift) + "s", "");
return(
#ifndef __MQL4_COMPATIBILITY_CODE__
StringFormat("%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s",
#else
StringFormat("%s\n%s%s\n%s%s\n%s%s\n%s%s",
#endif
LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".time", val.time, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".bid", val.bid, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".ask", val.ask, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".last", val.last, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".volume", val.volume, NULL, prefix)
#ifndef __MQL4_COMPATIBILITY_CODE__
, _shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".time_msc", (datetime)val.time_msc, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".flags", (uchar)val.flags, NULL, prefix, NULL, false),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".volume_real", val.volume_real, NULL, prefix)
#endif
)); }
#ifndef __MQL4_COMPATIBILITY_CODE__
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const MqlParam& val, const int shift = 0, const string prefix = "{MqlParam} ", const int offset = 0)
{
const string _shift = StringFormat("%" + IntegerToString(shift) + "s", "");
return(StringFormat("%s\n%s%s\n%s%s\n%s%s",
LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".type", val.type, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".integer_value", val.integer_value, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".double_value", val.double_value, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".string_value", val.string_value, NULL, prefix)
)); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const MqlBookInfo& val, const int shift = 0, const string prefix = "{MqlBookInfo} ", const int offset = 0)
{
const string _shift = StringFormat("%" + IntegerToString(shift) + "s", "");
return(StringFormat("%s\n%s%s\n%s%s\n%s%s",
LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".type", val.type, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".price", val.price, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".volume", val.volume, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".volume_real", val.volume_real, NULL, prefix)
)); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const MqlTradeRequest& val, const int shift = 0, const string prefix = "{MqlTradeRequest} ", const int offset = 0)
{
const string _shift = StringFormat("%" + IntegerToString(shift) + "s", "");
return(StringFormat("%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s",
LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".action", val.action, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".magic", val.magic, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".order", val.order, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".symbol", val.symbol, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".volume", val.volume, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".price", val.price, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".stoplimit", val.stoplimit, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".sl", val.sl, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".tp", val.tp, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".deviation", val.deviation, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".type", val.type, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".type_filling", val.type_filling, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".type_time", val.type_time, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".expiration", val.expiration, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".comment", val.comment, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".position", val.position, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".position_by", val.position_by, NULL, prefix)
)); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const MqlTradeCheckResult& val, const int shift = 0, const string prefix = "{MqlTradeCheckResult} ", const int offset = 0)
{
const string _shift = StringFormat("%" + IntegerToString(shift) + "s", "");
return(StringFormat("%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s",
LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".retcode", val.retcode, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".balance", val.balance, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".equity", val.equity, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".profit", val.profit, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".margin", val.margin, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".margin_free", val.margin_free, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".margin_level", val.margin_level, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".comment", val.comment, NULL, prefix)
)); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const MqlTradeResult& val, const int shift = 0, const string prefix = "{MqlTradeResult} ", const int offset = 0)
{
const string _shift = StringFormat("%" + IntegerToString(shift) + "s", "");
return(StringFormat("%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s",
LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".retcode", val.retcode, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".deal", val.deal, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".order", val.order, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".volume", val.volume, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".price", val.price, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".bid", val.bid, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".ask", val.ask, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".comment", val.comment, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".request_id", val.request_id, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".retcode_external", val.retcode_external, NULL, prefix)
)); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const MqlTradeTransaction& val, const int shift = 0, const string prefix = "{MqlTradeTransaction} ", const int offset = 0)
{
const string _shift = StringFormat("%" + IntegerToString(shift) + "s", "");
return(StringFormat("%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s",
LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".deal", val.deal, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".order", val.order, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".symbol", val.symbol, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".type", val.type, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".order_type", val.order_type, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".order_state", val.order_state, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".deal_type", val.deal_type, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".time_type", val.time_type, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".time_expiration", val.time_expiration, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".price", val.price, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".price_trigger", val.price_trigger, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".price_sl", val.price_sl, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".price_tp", val.price_tp, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".volume", val.volume, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".position", val.position, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".position_by", val.position_by, NULL, prefix)
)); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const MqlCalendarCountry& val, const int shift = 0, const string prefix = "{MqlCalendarCountry} ", const int offset = 0)
{
const string _shift = StringFormat("%" + IntegerToString(shift) + "s", "");
return(StringFormat("%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s",
LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".id", val.id, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".name", val.name, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".code", val.code, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".currency", val.currency, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".currency_symbol", val.currency_symbol, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".url_name", val.url_name, NULL, prefix)
)); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const MqlCalendarEvent& val, const int shift = 0, const string prefix = "{MqlCalendarEvent} ", const int offset = 0)
{
const string _shift = StringFormat("%" + IntegerToString(shift) + "s", "");
return(StringFormat("%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s",
LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".id", val.id, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".type", val.type, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".sector", val.sector, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".frequency", val.frequency, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".time_mode", val.time_mode, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".country_id", val.country_id, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".unit", val.unit, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".importance", val.importance, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".multiplier", val.multiplier, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".digits", val.digits, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".source_url", val.source_url, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".event_code", val.event_code, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".url_name", val.name, NULL, prefix)
)); }
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, var_out)(const string name, const MqlCalendarValue& val, const int shift = 0, const string prefix = "{MqlCalendarValue} ", const int offset = 0)
{
const string _shift = StringFormat("%" + IntegerToString(shift) + "s", "");
return(StringFormat("%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s",
LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".id", val.id, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".event_id", val.event_id, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".time", val.time, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".period", val.period, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".revision", val.revision, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".actual_value", val.actual_value, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".prev_value", val.prev_value, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".revised_prev_value", val.revised_prev_value, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".forecast_value", val.forecast_value, NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".impact_type", val.impact_type, NULL, prefix),
#ifndef __MQLPUBLISHING__
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".HasActualValue", val.HasActualValue(), NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".HasPreviousValue", val.HasPreviousValue(), NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".HasRevisedValue", val.HasRevisedValue(), NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".HasForecastValue", val.HasForecastValue(), NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".GetActualValue", val.GetActualValue(), NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".GetPreviousValue", val.GetPreviousValue(), NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".GetRevisedValue", val.GetRevisedValue(), NULL, prefix),
_shift, LIB_DBG_NAMESPACE(dbg_lib, var_out)(name + ".GetForecastValue", val.GetForecastValue(), NULL, prefix)
#else
"", "", "", "", "", "", "", ""
#endif
)); }
#endif
// 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")); }
// Uninit code to string
void LIB_DBG_NAMESPACE_DEF(dbg_lib, uninit_text)(const string func_name)
{
LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason) = (LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason) != NULL) ? LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason) : _UninitReason;
if(func_name != "OnDeinit")
{ return; }
switch(LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason))
{
// Terminal built-in reasons
case REASON_PROGRAM: DBG_MSG(StringFormat("(_UninitReason) %i = REASON_PROGRAM: %s", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Expert Advisor terminated its operation by calling the ExpertRemove() function.")); return;
case REASON_REMOVE: DBG_MSG(StringFormat("(_UninitReason) %i = REASON_REMOVE: %s", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Program has been deleted from the chart.")); return;
case REASON_RECOMPILE: DBG_MSG(StringFormat("(_UninitReason) %i = REASON_RECOMPILE: %s", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Program has been recompiled.")); return;
case REASON_CHARTCHANGE: DBG_MSG(StringFormat("(_UninitReason) %i = REASON_CHARTCHANGE: %s", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Symbol or chart period has been changed.")); return;
case REASON_CHARTCLOSE: DBG_MSG(StringFormat("(_UninitReason) %i = REASON_CHARTCLOSE: %s", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Chart has been closed.")); return;
case REASON_PARAMETERS: DBG_MSG(StringFormat("(_UninitReason) %i = REASON_PARAMETERS: %s", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Input parameters have been changed by a user.")); return;
case REASON_ACCOUNT: DBG_MSG(StringFormat("(_UninitReason) %i = REASON_ACCOUNT: %s", (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.")); return;
case REASON_TEMPLATE: DBG_MSG(StringFormat("(_UninitReason) %i = REASON_TEMPLATE: %s", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "A new template has been applied.")); return;
case REASON_INITFAILED: DBG_MSG(StringFormat("(_UninitReason) %i = REASON_INITFAILED: %s", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "This value means that OnInit() handler has returned a nonzero value.")); return;
case REASON_CLOSE: DBG_MSG(StringFormat("(_UninitReason) %i = REASON_CLOSE: %s", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Terminal has been closed.")); return;
// MQLplus extended reasons
case REASON_MQLPLUS_EXPERT_KILL: DBG_MSG(StringFormat("(_UninitReason) %i = REASON_MQLPLUS_EXPERT_KILL: %s", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Program terminated its operation by calling the ExpertKill() function.")); return;
// Unknown reasons
default: DBG_MSG(StringFormat("Unknown reason: %i", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason)));
}
return;
}
template <typename T>
T LIB_DBG_NAMESPACE_DEF(dbg_lib, return_function_result)(const string name, const T value, const string msg, const string func_name)
{
printf(((LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) == 1) ? "" : DBG_OUTPUT_PREFIX) + DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX + msg, "", StringFormat("=> %s return(%s);", typename((value)), (LIB_DBG_NAMESPACE(dbg_lib, var_out)("(" + name + ")", value, NULL, "", StringLen(typename((value))) + 11))));
printf("%*s%s", LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2, "", StringFormat(msg, DBG_TRACE_END_MSG_TXT, StringFormat(DBG_OUTPUT_TRACE_END_FORMAT , dbg_lib::trace_call_depth, func_name))); printf("%s", " "); dbg_lib::trace_call_depth--; DBG_TRACE_EXEC_DELAY;
return(value);
}
#ifndef __MQL4_COMPATIBILITY_CODE__
};
#endif
#endif
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Vardump array
//
// Vardump pause execution
#ifdef DBG_VARDUMP_PAUSE
#undef DBG_VARDUMP_PAUSE_COMMAND
#define DBG_VARDUMP_PAUSE_COMMAND(x) DBG_MSG(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", typename((x)), #x, LIB_DBG_NAMESPACE(dbg_lib, dbg_ArraySize)(x), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE)
#else
#undef DBG_VARDUMP_PAUSE_COMMAND
#define DBG_VARDUMP_PAUSE_COMMAND(x) DBG_MSG(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("Vardump: %s %s[%i] done.", typename((x)), #x, LIB_DBG_NAMESPACE(dbg_lib, dbg_ArraySize)(x)));
#endif
// Dump function
#ifndef LIB_DEBUG_NAMESPACE
#ifndef __MQL4_COMPATIBILITY_CODE__
namespace dbg_lib
{
#endif
template <typename T>
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const T& _array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array type unknown: %s; %s[%]; type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const string &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %s ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, _array_[cnt]); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const double &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %.*f ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, DBG_DOUBLE_OUTPUT_DIGITS, _array_[cnt]); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const float &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %.*f ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, DBG_DOUBLE_OUTPUT_DIGITS, _array_[cnt]); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const bool &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %s ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, ((((int)_array_[cnt]) != NULL) ? "true" : "false")); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const datetime &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %s ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, TimeToString((datetime)_array_[cnt])); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const char &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %i ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, _array_[cnt]); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const short &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %i ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, _array_[cnt]); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const int &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %i ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, _array_[cnt]); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const long &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %i ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, _array_[cnt]); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const uchar &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %i ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, _array_[cnt]); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const ushort &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %i ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, _array_[cnt]); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const uint &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %i ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, _array_[cnt]); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const ulong &_array_[], const string _var_name_, const string _file_, const string _func_, const int _line_)
{
const string type = typename(_array_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump array: %s %s[%i] type: %s", type, _var_name_, ArraySize(_array_), ((ArrayIsDynamic(_array_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < ArraySize(_array_); cnt++) { printf("%s%s%s%s[%i] = %i ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, cnt, _array_[cnt]); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done. Execution delayed for %i seconds.", type, _var_name_, ArraySize(_array_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] done.", type, _var_name_, ArraySize(_array_))); }
return;
}
template <typename T>
string LIB_DBG_NAMESPACE_DEF(dbg_lib, VoidToString)(const T value)
{
const string type = typename(value);
if(type == "string")
{ return(StringFormat("%s", value)); }
else if(type == "double")
{ return(StringFormat("%.*f", DBG_DOUBLE_OUTPUT_DIGITS, value)); }
else if(type == "bool")
{ return(StringFormat("%s", ((((int)value) != NULL) ? "true" : "false"))); }
else if(type == "datetime")
{ return(StringFormat("%s", TimeToString((datetime)value))); }
return(StringFormat("%i", value));
}
template <typename T, typename U>
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const T& _array1_[], const string _var_name1_, const U& _array2_[], const string _var_name2_, const string _file_, const string _func_, const int _line_)
{
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump list: %s %s[%i] type: %s; %s %s[%i] type: %s", typename(_array1_), _var_name1_, ArraySize(_array1_), ((ArrayIsDynamic(_array1_)) ? "dynamic" : "static"), typename(_array2_), _var_name2_, ArraySize(_array2_), ((ArrayIsDynamic(_array2_)) ? "dynamic" : "static")));
for(int cnt = 0x00; cnt < MathMin(ArraySize(_array1_), ArraySize(_array2_)); cnt++) { printf("%s%s%s%s[%i], %30s[%i] = %-30s -> %s", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name1_, cnt, _var_name2_, cnt, VoidToString(_array1_[cnt]), VoidToString(_array2_[cnt])); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] -> %s %s[%i] done. Execution delayed for %i seconds.", typename(_array1_), _var_name1_, ArraySize(_array1_), typename(_array2_), _var_name2_, ArraySize(_array2_), DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s[%i] -> %s %s[%i] done.", typename(_array1_), _var_name1_, ArraySize(_array1_), typename(_array1_), _var_name1_, ArraySize(_array1_))); }
return;
}
template <typename T>
void LIB_DBG_NAMESPACE_DEF(dbg_lib, VarDump)(const T _value_, const string _var_name_, const string _file_, const string _func_, const int _line_)
{
string type = typename(_value_);
printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump value: %s %s", type, _var_name_));
if(type == "string")
{ printf("%s%s%s%s = %s ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, _value_); }
else if(type == "double")
{ printf("%s%s%s%s = %." + IntegerToString(DBG_DOUBLE_OUTPUT_DIGITS) + "f ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, _value_); }
else if(type == "bool")
{ printf("%s%s%s%s = %s ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, ((_value_ != NULL) ? "true" : "false")); }
else if(type == "datetime")
{ printf("%s%s%s%s = %s ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, TimeToString((datetime)_value_)); }
else
{ printf("%s%s%s%s = %i ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, _value_); }
if(!_DEBUG)
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s done. Execution delayed for %i seconds.", type, _var_name_, DBG_VARDUMP_PAUSE)); DBG_SLEEP_SECONDS(DBG_VARDUMP_PAUSE); }
else
{ printf(DBG_OUTPUT_STRING, "", _file_, _func_, _line_, StringFormat("Vardump: %s %s done.", type, _var_name_)); }
return;
}
#ifndef __MQL4_COMPATIBILITY_CODE__
};
#endif
#endif
// Var dump macro
#define DBG_MSG_VARDUMP(x) LIB_DBG_NAMESPACE(dbg_lib, VarDump)(x, #x, __FILE__, __FUNCSIG__, __LINE__)
#define DBG_MSG_LISTDUMP(x, y) LIB_DBG_NAMESPACE(dbg_lib, VarDump)(x, #x, y, #y, __FILE__, __FUNCSIG__, __LINE__)
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Assert support
//
// Generic assert definition
// #define DBG_GENERIC_ASSERT(condition, message) { if(!(condition)) { string msg = LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_FORMAT(#condition, message));
#define DBG_GENERIC_ASSERT(condition, message) { if(!(condition)) { string msg = LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)(DBG_OUTPUT_STRING, ((#condition == "") ? "" : #condition + " "), DBG_CODE_LOCATION_STRING, message);
// Call modal dialog and div/zero!
#define DBG_ASSERT(condition, message) DBG_GENERIC_ASSERT(condition, message) LIB_DBG_NAMESPACE(dbg_lib, dbg_Alert)(DBG_ASSERT_MSG_TXT + " " + msg); DBG_CRASH_CODE; } }
// Print out information
#define DBG_ASSERT_LOG(condition, message) DBG_GENERIC_ASSERT(condition, message) LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%s%s %s", DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX, DBG_ASSERT_MSG_TXT, msg); } }
// Print info and abort execution by return;
#define DBG_ASSERT_RETURN(condition, message) DBG_GENERIC_ASSERT(condition, message) LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%s%s %s", DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX, DBG_ASSERT_MSG_TXT, msg); return; } }
// Print info and abort execution by return;
#define DBG_ASSERT_RETURN_VAR(condition, message, return_value) DBG_GENERIC_ASSERT(condition, message) LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%s%s %s", DBG_OUTPUT_PREFIX + DBG_OUTPUT_PREFIX, DBG_ASSERT_MSG_TXT, msg); return(return_value); } }
// Array out of range stop macro
#ifndef __MQL4_COMPATIBILITY_CODE__
#define DBG_STOP_ARRAY_OUT_OF_RANGE(x, y) { const int arr_size = LIB_DBG_NAMESPACE(dbg_lib, dbg_ArraySize)(x); if(arr_size <= y) { LIB_DBG_NAMESPACE(dbg_lib, dbg_ArrayPrint)(x, _Digits, (arr_size < 5) ? NULL : (arr_size - 5), NULL); DBG_MSG_VAR(typename(x)); DBG_MSG_VAR(LIB_DBG_NAMESPACE(dbg_lib, dbg_ArraySize)(x)); DBG_MSG_VAR(y); LIB_DBG_NAMESPACE(dbg_lib, dbg_DebugBreak)(); } }
#else
#define DBG_STOP_ARRAY_OUT_OF_RANGE(x, y) { if(LIB_DBG_NAMESPACE(dbg_lib, dbg_ArraySize)(x) <= y) { DBG_MSG_VARDUMP(x); DBG_MSG_VAR(typename(x)); DBG_MSG_VAR(LIB_DBG_NAMESPACE(dbg_lib, dbg_ArraySize)(x)); DBG_MSG_VAR(y); LIB_DBG_NAMESPACE(dbg_lib, dbg_DebugBreak)(); } }
#endif
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Software inherited brakepoints
//
// Stop function
#ifndef LIB_DEBUG_NAMESPACE
#define LIB_DEBUG_NAMESPACE
#ifndef __MQL4_COMPATIBILITY_CODE__
namespace dbg_lib
{
#endif
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))));
}
#ifndef __MQL4_COMPATIBILITY_CODE__
};
#endif
#endif
// Debugging macros
#define DBG_SOFT_BREAKPOINT { LIB_DBG_NAMESPACE(dbg_lib, BreakPoint)(__LINE__, __FILE__); if(IS_DEBUG_MODE) { LIB_DBG_NAMESPACE(dbg_lib, dbg_DebugBreak)(); } else { DBG_SLEEP_SECONDS(DBG_SOFT_BKP_TIMEOUT); } }
#define DBG_SOFT_BREAKPOINT_TS(timestamp) { LIB_DBG_NAMESPACE(dbg_lib, BreakPoint)(__LINE__, __FILE__, LIB_DBG_NAMESPACE(dbg_lib, dbg_StringToTime)(timestamp)); DBG_SOFT_BREAKPOINT }
#define DBG_SOFT_BREAKPOINT_CONDITION(x) { if((x) && (LIB_DBG_NAMESPACE(dbg_lib, BreakPoint)(__LINE__, __FILE__, LIB_DBG_NAMESPACE(dbg_lib, dbg_TimeCurrent)() + DBG_SOFT_BKP_TIMEOUT))) { DBG_SOFT_BREAKPOINT; } }
#define DBG_SOFT_BREAKPOINT_EXEC_TIME(x) { DBG_SOFT_BREAKPOINT_CONDITION(LIB_DBG_NAMESPACE(dbg_lib, ExecTime)(x)); LIB_DBG_NAMESPACE(dbg_lib, ExecTime)(NULL); }
// Conditional break debugging macros
#ifndef __MQL4_COMPATIBILITY_CODE__
#define DBG_BREAK_CONDITION_CREATE(_id_, y) namespace dbg_lib { static bool dbg_cond_ID_state_##x = false; static bool dbg_cond_ID_enabled_##x = y; }
#define DBG_BREAK_CONDITION_ACTIVATE(x, y) namespace dbg_lib { static bool dbg_cond_ID_state_##x = (y); }
#define DBG_BREAK_CONDITION_DEACTIVATE(x, y) namespace dbg_lib { static bool dbg_cond_ID_state_##x = !(y); }
#define DBG_BREAK_CONDITION_ON_ID(x) { if(dbg_lib::dbg_cond_ID_state_##x && dbg_lib::dbg_cond_ID_enabled_##x) { LIB_DBG_NAMESPACE(dbg_lib, dbg_DebugBreak)(); } }
#else
#define DBG_BREAK_CONDITION_CREATE(_id_, y) static bool dbg_cond_ID_state_##x = false; static bool dbg_cond_ID_enabled_##x = y;
#define DBG_BREAK_CONDITION_ACTIVATE(x, y) dbg_cond_ID_state_##x = (y);
#define DBG_BREAK_CONDITION_DEACTIVATE(x, y) dbg_cond_ID_state_##x = !(y);
#define DBG_BREAK_CONDITION_ON_ID(x) { if(dbg_cond_ID_state_##x && dbg_cond_ID_enabled_##x) { LIB_DBG_NAMESPACE(dbg_lib, dbg_DebugBreak)(); } }
#endif
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Loop tracing
//
// Init loop trace
#define DBG_TRACE_LOOP_BEGIN_ID(x) int _dbg_loop_start##x = 0x00; int _dbg_loop_finish##x = 0x00; ulong _dbg_loop_runtime##x = LIB_DBG_NAMESPACE(dbg_lib, dbg_GetMicrosecondCount)();
#define DBG_TRACE_LOOP_BEGIN DBG_TRACE_LOOP_BEGIN_ID(__FUNCTION__)
// Count loop heads
#define DBG_TRACE_LOOP_START_ID(x) _dbg_loop_start##x++;
#define DBG_TRACE_LOOP_START DBG_TRACE_LOOP_START_ID(__FUNCTION__)
// Count loop footers
#define DBG_TRACE_LOOP_FINISH_ID(x) _dbg_loop_finish##x++;
#define DBG_TRACE_LOOP_FINISH DBG_TRACE_LOOP_FINISH_ID(__FUNCTION__)
// Print loop stats
#define DBG_TRACE_LOOP_END_ID(x) DBG_MSG(LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("Iterations begin: %i; Iterations end: %i; Runtime: %i microseconds.", _dbg_loop_start##x, _dbg_loop_finish##x, (LIB_DBG_NAMESPACE(dbg_lib, dbg_GetMicrosecondCount)() - _dbg_loop_runtime##x)));
#define DBG_TRACE_LOOP_END DBG_TRACE_LOOP_END_ID(__FUNCTION__)
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// MT4/5 API function call tracing
//
#ifndef LIB_MQLAPI_CALL_TRACING_DISABLE
#define AccountInfoDouble DBG_MSG_MQLFUNC_RETURN(AccountInfoDouble)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define AccountInfoInteger DBG_MSG_MQLFUNC_RETURN(AccountInfoInteger)
#endif
#define AccountInfoString DBG_MSG_MQLFUNC_RETURN(AccountInfoString)
#define acos DBG_MSG_MQLFUNC_RETURN(acos)
#define Alert DBG_MSG_MQLFUNC(Alert)
#define ArrayBsearch DBG_MSG_MQLFUNC_RETURN(ArrayBsearch)
#define ArrayCompare DBG_MSG_MQLFUNC_RETURN(ArrayCompare)
#define ArrayCopy DBG_MSG_MQLFUNC_RETURN(ArrayCopy)
#define ArrayFill DBG_MSG_MQLFUNC(ArrayFill)
#define ArrayFree DBG_MSG_MQLFUNC(ArrayFree)
#define ArrayGetAsSeries DBG_MSG_MQLFUNC_RETURN(ArrayGetAsSeries)
#define ArrayInitialize DBG_MSG_MQLFUNC_RETURN(ArrayInitialize)
#define ArrayIsDynamic DBG_MSG_MQLFUNC_RETURN(ArrayIsDynamic)
#define ArrayIsSeries DBG_MSG_MQLFUNC_RETURN(ArrayIsSeries)
#define ArrayMaximum DBG_MSG_MQLFUNC_RETURN(ArrayMaximum)
#define ArrayMinimum DBG_MSG_MQLFUNC_RETURN(ArrayMinimum)
#define ArrayRange DBG_MSG_MQLFUNC_RETURN(ArrayRange)
#define ArrayResize DBG_MSG_MQLFUNC_RETURN(ArrayResize)
#define ArraySetAsSeries DBG_MSG_MQLFUNC_RETURN(ArraySetAsSeries)
#define ArraySize DBG_MSG_MQLFUNC_RETURN(ArraySize)
#define ArraySort DBG_MSG_MQLFUNC_RETURN(ArraySort)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define ArrayPrint DBG_MSG_MQLFUNC(ArrayPrint)
#define ArrayInsert DBG_MSG_MQLFUNC_RETURN(ArrayInsert)
#define ArrayRemove DBG_MSG_MQLFUNC_RETURN(ArrayRemove)
#define ArrayReverse DBG_MSG_MQLFUNC_RETURN(ArrayReverse)
#define ArraySwap DBG_MSG_MQLFUNC_RETURN(ArraySwap)
#endif
#define asin DBG_MSG_MQLFUNC_RETURN(asin)
#define atan DBG_MSG_MQLFUNC_RETURN(atan)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define Bars DBG_MSG_MQLFUNC_RETURN(Bars)
#define BarsCalculated DBG_MSG_MQLFUNC_RETURN(BarsCalculated)
#define CalendarCountryById DBG_MSG_MQLFUNC_RETURN(CalendarCountryById)
#define CalendarEventById DBG_MSG_MQLFUNC_RETURN(CalendarEventById)
#define CalendarValueById DBG_MSG_MQLFUNC_RETURN(CalendarValueById)
#define CalendarCountries DBG_MSG_MQLFUNC_RETURN(CalendarCountries)
#define CalendarEventByCountry DBG_MSG_MQLFUNC_RETURN(CalendarEventByCountry)
#define CalendarEventByCurrency DBG_MSG_MQLFUNC_RETURN(CalendarEventByCurrency)
#define CalendarValueHistoryByEvent DBG_MSG_MQLFUNC_RETURN(CalendarValueHistoryByEvent)
#define CalendarValueHistory DBG_MSG_MQLFUNC_RETURN(CalendarValueHistory)
#define CalendarValueLastByEvent DBG_MSG_MQLFUNC_RETURN(CalendarValueLastByEvent)
#define CalendarValueLast DBG_MSG_MQLFUNC_RETURN(CalendarValueLast)
#endif
#define ceil DBG_MSG_MQLFUNC_RETURN(ceil)
#define CharArrayToString DBG_MSG_MQLFUNC_RETURN(CharArrayToString)
#define ChartApplyTemplate DBG_MSG_MQLFUNC_RETURN(ChartApplyTemplate)
#define ChartClose DBG_MSG_MQLFUNC_RETURN(ChartClose)
#define ChartFirst DBG_MSG_MQLFUNC_RETURN(ChartFirst)
#define ChartGetDouble DBG_MSG_MQLFUNC_RETURN(ChartGetDouble)
#define ChartGetInteger DBG_MSG_MQLFUNC_RETURN(ChartGetInteger)
#define ChartGetString DBG_MSG_MQLFUNC_RETURN(ChartGetString)
#define ChartID DBG_MSG_MQLFUNC_RETURN(ChartID)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define ChartIndicatorAdd DBG_MSG_MQLFUNC_RETURN(ChartIndicatorAdd)
#endif
#define ChartIndicatorDelete DBG_MSG_MQLFUNC_RETURN(ChartIndicatorDelete)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define ChartIndicatorGet DBG_MSG_MQLFUNC_RETURN(ChartIndicatorGet)
#endif
#define ChartIndicatorName DBG_MSG_MQLFUNC_RETURN(ChartIndicatorName)
#define ChartIndicatorsTotal DBG_MSG_MQLFUNC_RETURN(ChartIndicatorsTotal)
#define ChartNavigate DBG_MSG_MQLFUNC_RETURN(ChartNavigate)
#define ChartNext DBG_MSG_MQLFUNC_RETURN(ChartNext)
#define ChartOpen DBG_MSG_MQLFUNC_RETURN(ChartOpen)
#define CharToString DBG_MSG_MQLFUNC_RETURN(CharToString)
#define ChartPeriod DBG_MSG_MQLFUNC_RETURN(ChartPeriod)
#define ChartPriceOnDropped DBG_MSG_MQLFUNC_RETURN(ChartPriceOnDropped)
#define ChartRedraw DBG_MSG_MQLFUNC(ChartRedraw)
#define ChartSaveTemplate DBG_MSG_MQLFUNC_RETURN(ChartSaveTemplate)
#define ChartScreenShot DBG_MSG_MQLFUNC_RETURN(ChartScreenShot)
#define ChartSetDouble DBG_MSG_MQLFUNC_RETURN(ChartSetDouble)
#define ChartSetInteger DBG_MSG_MQLFUNC_RETURN(ChartSetInteger)
#define ChartSetString DBG_MSG_MQLFUNC_RETURN(ChartSetString)
#define ChartSetSymbolPeriod DBG_MSG_MQLFUNC_RETURN(ChartSetSymbolPeriod)
#define ChartSymbol DBG_MSG_MQLFUNC_RETURN(ChartSymbol)
#define ChartTimeOnDropped DBG_MSG_MQLFUNC_RETURN(ChartTimeOnDropped)
#define ChartTimePriceToXY DBG_MSG_MQLFUNC_RETURN(ChartTimePriceToXY)
#define ChartWindowFind DBG_MSG_MQLFUNC_RETURN(ChartWindowFind)
#define ChartWindowOnDropped DBG_MSG_MQLFUNC_RETURN(ChartWindowOnDropped)
#define ChartXOnDropped DBG_MSG_MQLFUNC_RETURN(ChartXOnDropped)
#define ChartXYToTimePrice DBG_MSG_MQLFUNC_RETURN(ChartXYToTimePrice)
#define ChartYOnDropped DBG_MSG_MQLFUNC_RETURN(ChartYOnDropped)
#define CheckPointer DBG_MSG_MQLFUNC_RETURN(CheckPointer)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define CLBufferCreate DBG_MSG_MQLFUNC_RETURN(CLBufferCreate)
#define CLBufferFree DBG_MSG_MQLFUNC(CLBufferFree)
#define CLBufferRead DBG_MSG_MQLFUNC_RETURN(CLBufferRead)
#define CLBufferWrite DBG_MSG_MQLFUNC_RETURN(CLBufferWrite)
#define CLContextCreate DBG_MSG_MQLFUNC_RETURN(CLContextCreate)
#define CLContextFree DBG_MSG_MQLFUNC(CLContextFree)
#define CLExecute DBG_MSG_MQLFUNC_RETURN(CLExecute)
#define CLGetDeviceInfo DBG_MSG_MQLFUNC_RETURN(CLGetDeviceInfo)
#define CLGetInfoInteger DBG_MSG_MQLFUNC_RETURN(CLGetInfoInteger)
#define CLHandleType DBG_MSG_MQLFUNC_RETURN(CLHandleType)
#define CLKernelCreate DBG_MSG_MQLFUNC_RETURN(CLKernelCreate)
#define CLKernelFree DBG_MSG_MQLFUNC(CLKernelFree)
#define CLProgramCreate DBG_MSG_MQLFUNC_RETURN(CLProgramCreate)
#define CLProgramFree DBG_MSG_MQLFUNC(CLProgramFree)
#define CLSetKernelArg DBG_MSG_MQLFUNC_RETURN(CLSetKernelArg)
#define CLSetKernelArgMem DBG_MSG_MQLFUNC_RETURN(CLSetKernelArgMem)
#endif
#define ColorToARGB DBG_MSG_MQLFUNC_RETURN(ColorToARGB)
#define ColorToString DBG_MSG_MQLFUNC_RETURN(ColorToString)
#define Comment DBG_MSG_MQLFUNC(Comment)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define CopyBuffer DBG_MSG_MQLFUNC_RETURN(CopyBuffer)
#endif
#define CopyClose DBG_MSG_MQLFUNC_RETURN(CopyClose)
#define CopyHigh DBG_MSG_MQLFUNC_RETURN(CopyHigh)
#define CopyLow DBG_MSG_MQLFUNC_RETURN(CopyLow)
#define CopyOpen DBG_MSG_MQLFUNC_RETURN(CopyOpen)
#define CopyRates DBG_MSG_MQLFUNC_RETURN(CopyRates)
#define CopyRealVolume DBG_MSG_MQLFUNC_RETURN(CopyRealVolume)
#define CopySpread DBG_MSG_MQLFUNC_RETURN(CopySpread)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define CopyTicks DBG_MSG_MQLFUNC_RETURN(CopyTicks)
#endif
#define CopyTickVolume DBG_MSG_MQLFUNC_RETURN(CopyTickVolume)
#define CopyTime DBG_MSG_MQLFUNC_RETURN(CopyTime)
#define cos DBG_MSG_MQLFUNC_RETURN(cos)
#define CryptDecode DBG_MSG_MQLFUNC_RETURN(CryptDecode)
#define CryptEncode DBG_MSG_MQLFUNC_RETURN(CryptEncode)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define CustomSymbolCreate DBG_MSG_MQLFUNC_RETURN(CustomSymbolCreate)
#define CustomSymbolDelete DBG_MSG_MQLFUNC_RETURN(CustomSymbolDelete)
#define CustomSymbolSetInteger DBG_MSG_MQLFUNC_RETURN(CustomSymbolSetInteger)
#define CustomSymbolSetDouble DBG_MSG_MQLFUNC_RETURN(CustomSymbolSetDouble)
#define CustomSymbolSetString DBG_MSG_MQLFUNC_RETURN(CustomSymbolSetString)
#define CustomSymbolSetMarginRate DBG_MSG_MQLFUNC_RETURN(CustomSymbolSetMarginRate)
#define CustomSymbolSetSessionQuote DBG_MSG_MQLFUNC_RETURN(CustomSymbolSetSessionQuote)
#define CustomSymbolSetSessionTrade DBG_MSG_MQLFUNC_RETURN(CustomSymbolSetSessionTrade)
#define CustomRatesDelete DBG_MSG_MQLFUNC_RETURN(CustomRatesDelete)
#define CustomRatesReplace DBG_MSG_MQLFUNC_RETURN(CustomRatesReplace)
#define CustomRatesUpdate DBG_MSG_MQLFUNC_RETURN(CustomRatesUpdate)
#define CustomTicksAdd DBG_MSG_MQLFUNC_RETURN(CustomTicksAdd)
#define CustomTicksDelete DBG_MSG_MQLFUNC_RETURN(CustomTicksDelete)
#define CustomTicksReplace DBG_MSG_MQLFUNC_RETURN(CustomTicksReplace)
#define CustomBookAdd DBG_MSG_MQLFUNC_RETURN(CustomBookAdd)
#define DatabaseOpen DBG_MSG_MQLFUNC_RETURN(DatabaseOpen)
#define DatabaseClose DBG_MSG_MQLFUNC(DatabaseClose)
#define DatabaseImport DBG_MSG_MQLFUNC_RETURN(DatabaseImport)
#define DatabaseExport DBG_MSG_MQLFUNC_RETURN(DatabaseExport)
#define DatabasePrint DBG_MSG_MQLFUNC_RETURN(DatabasePrint)
#define DatabaseTableExists DBG_MSG_MQLFUNC_RETURN(DatabaseTableExists)
#define DatabaseExecute DBG_MSG_MQLFUNC_RETURN(DatabaseExecute)
#define DatabasePrepare DBG_MSG_MQLFUNC_RETURN(DatabasePrepare)
#define DatabaseReset DBG_MSG_MQLFUNC_RETURN(DatabaseReset)
#define DatabaseBind DBG_MSG_MQLFUNC_RETURN(DatabaseBind)
#define DatabaseBindArray DBG_MSG_MQLFUNC_RETURN(DatabaseBindArray)
#define DatabaseRead DBG_MSG_MQLFUNC_RETURN(DatabaseRead)
#define DatabaseReadBind DBG_MSG_MQLFUNC_RETURN(DatabaseReadBind)
#define DatabaseFinalize DBG_MSG_MQLFUNC(DatabaseFinalize)
#define DatabaseTransactionBegin DBG_MSG_MQLFUNC_RETURN(DatabaseTransactionBegin)
#define DatabaseTransactionCommit DBG_MSG_MQLFUNC_RETURN(DatabaseTransactionCommit)
#define DatabaseTransactionRollback DBG_MSG_MQLFUNC_RETURN(DatabaseTransactionRollback)
#define DatabaseColumnsCount DBG_MSG_MQLFUNC_RETURN(DatabaseColumnsCount)
#define DatabaseColumnName DBG_MSG_MQLFUNC_RETURN(DatabaseColumnName)
#define DatabaseColumnType DBG_MSG_MQLFUNC_RETURN(DatabaseColumnType)
#define DatabaseColumnSize DBG_MSG_MQLFUNC_RETURN(DatabaseColumnSize)
#define DatabaseColumnText DBG_MSG_MQLFUNC_RETURN(DatabaseColumnText)
#define DatabaseColumnInteger DBG_MSG_MQLFUNC_RETURN(DatabaseColumnInteger)
#define DatabaseColumnLong DBG_MSG_MQLFUNC_RETURN(DatabaseColumnLong)
#define DatabaseColumnDouble DBG_MSG_MQLFUNC_RETURN(DatabaseColumnDouble)
#define DatabaseColumnBlob DBG_MSG_MQLFUNC_RETURN(DatabaseColumnBlob)
#endif
#define DebugBreak DBG_MSG_MQLFUNC(DebugBreak)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define Digits DBG_MSG_MQLFUNC_RETURN(Digits)
#endif
#define DoubleToString DBG_MSG_MQLFUNC_RETURN(DoubleToString)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define DXContextCreate DBG_MSG_MQLFUNC_RETURN(DXContextCreate)
#define DXContextSetSize DBG_MSG_MQLFUNC_RETURN(DXContextSetSize)
#define DXContextGetSize DBG_MSG_MQLFUNC_RETURN(DXContextGetSize)
#define DXContextClearColors DBG_MSG_MQLFUNC_RETURN(DXContextClearColors)
#define DXContextClearDepth DBG_MSG_MQLFUNC_RETURN(DXContextClearDepth)
#define DXContextGetColors DBG_MSG_MQLFUNC_RETURN(DXContextGetColors)
#define DXContextGetDepth DBG_MSG_MQLFUNC_RETURN(DXContextGetDepth)
#define DXBufferCreate DBG_MSG_MQLFUNC_RETURN(DXBufferCreate)
#define DXTextureCreate DBG_MSG_MQLFUNC_RETURN(DXTextureCreate)
#define DXInputCreate DBG_MSG_MQLFUNC_RETURN(DXInputCreate)
#define DXInputSet DBG_MSG_MQLFUNC_RETURN(DXInputSet)
#define DXShaderCreate DBG_MSG_MQLFUNC_RETURN(DXShaderCreate)
#define DXShaderSetLayout DBG_MSG_MQLFUNC_RETURN(DXShaderSetLayout)
#define DXShaderInputsSet DBG_MSG_MQLFUNC_RETURN(DXShaderInputsSet)
#define DXShaderTexturesSet DBG_MSG_MQLFUNC_RETURN(DXShaderTexturesSet)
#define DXDraw DBG_MSG_MQLFUNC_RETURN(DXDraw)
#define DXDrawIndexed DBG_MSG_MQLFUNC_RETURN(DXDrawIndexed)
#define DXPrimiveTopologySet DBG_MSG_MQLFUNC_RETURN(DXPrimiveTopologySet)
#define DXBufferSet DBG_MSG_MQLFUNC_RETURN(DXBufferSet)
#define DXShaderSet DBG_MSG_MQLFUNC_RETURN(DXShaderSet)
#define DXHandleType DBG_MSG_MQLFUNC_RETURN(DXHandleType)
#define DXRelease DBG_MSG_MQLFUNC_RETURN(DXRelease)
#endif
#define EnumToString DBG_MSG_MQLFUNC_RETURN(EnumToString)
#define EventChartCustom DBG_MSG_MQLFUNC_RETURN(EventChartCustom)
#define EventKillTimer DBG_MSG_MQLFUNC(EventKillTimer)
#define EventSetMillisecondTimer DBG_MSG_MQLFUNC_RETURN(EventSetMillisecondTimer)
#define EventSetTimer DBG_MSG_MQLFUNC_RETURN(EventSetTimer)
#define exp DBG_MSG_MQLFUNC_RETURN(exp)
#define ExpertRemove DBG_MSG_MQLFUNC(ExpertRemove)
#define fabs DBG_MSG_MQLFUNC_RETURN(fabs)
#define FileClose DBG_MSG_MQLFUNC(FileClose)
#define FileCopy DBG_MSG_MQLFUNC_RETURN(FileCopy)
#define FileDelete DBG_MSG_MQLFUNC_RETURN(FileDelete)
#define FileFindClose DBG_MSG_MQLFUNC(FileFindClose)
#define FileFindFirst DBG_MSG_MQLFUNC_RETURN(FileFindFirst)
#define FileFindNext DBG_MSG_MQLFUNC_RETURN(FileFindNext)
#define FileFlush DBG_MSG_MQLFUNC(FileFlush)
#define FileGetInteger DBG_MSG_MQLFUNC_RETURN(FileGetInteger)
#define FileIsEnding DBG_MSG_MQLFUNC_RETURN(FileIsEnding)
#define FileIsExist DBG_MSG_MQLFUNC_RETURN(FileIsExist)
#define FileIsLineEnding DBG_MSG_MQLFUNC_RETURN(FileIsLineEnding)
#define FileMove DBG_MSG_MQLFUNC_RETURN(FileMove)
#define FileOpen DBG_MSG_MQLFUNC_RETURN(FileOpen)
#define FileReadArray DBG_MSG_MQLFUNC_RETURN(FileReadArray)
#define FileReadBool DBG_MSG_MQLFUNC_RETURN(FileReadBool)
#define FileReadDatetime DBG_MSG_MQLFUNC_RETURN(FileReadDatetime)
#define FileReadDouble DBG_MSG_MQLFUNC_RETURN(FileReadDouble)
#define FileReadFloat DBG_MSG_MQLFUNC_RETURN(FileReadFloat)
#define FileReadInteger DBG_MSG_MQLFUNC_RETURN(FileReadInteger)
#define FileReadLong DBG_MSG_MQLFUNC_RETURN(FileReadLong)
#define FileReadNumber DBG_MSG_MQLFUNC_RETURN(FileReadNumber)
#define FileReadString DBG_MSG_MQLFUNC_RETURN(FileReadString)
#define FileReadStruct DBG_MSG_MQLFUNC_RETURN(FileReadStruct)
#define FileSeek DBG_MSG_MQLFUNC_RETURN(FileSeek)
#define FileSize DBG_MSG_MQLFUNC_RETURN(FileSize)
#define FileTell DBG_MSG_MQLFUNC_RETURN(FileTell)
#define FileWrite DBG_MSG_MQLFUNC_RETURN(FileWrite)
#define FileWriteArray DBG_MSG_MQLFUNC_RETURN(FileWriteArray)
#define FileWriteDouble DBG_MSG_MQLFUNC_RETURN(FileWriteDouble)
#define FileWriteFloat DBG_MSG_MQLFUNC_RETURN(FileWriteFloat)
#define FileWriteInteger DBG_MSG_MQLFUNC_RETURN(FileWriteInteger)
#define FileWriteLong DBG_MSG_MQLFUNC_RETURN(FileWriteLong)
#define FileWriteString DBG_MSG_MQLFUNC_RETURN(FileWriteString)
#define FileWriteStruct DBG_MSG_MQLFUNC_RETURN(FileWriteStruct)
#define floor DBG_MSG_MQLFUNC_RETURN(floor)
#define fmax DBG_MSG_MQLFUNC_RETURN(fmax)
#define fmin DBG_MSG_MQLFUNC_RETURN(fmin)
#define fmod DBG_MSG_MQLFUNC_RETURN(fmod)
#define FolderClean DBG_MSG_MQLFUNC_RETURN(FolderClean)
#define FolderCreate DBG_MSG_MQLFUNC_RETURN(FolderCreate)
#define FolderDelete DBG_MSG_MQLFUNC_RETURN(FolderDelete)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define FrameAdd DBG_MSG_MQLFUNC_RETURN(FrameAdd)
#define FrameFilter DBG_MSG_MQLFUNC_RETURN(FrameFilter)
#define FrameFirst DBG_MSG_MQLFUNC_RETURN(FrameFirst)
#define FrameInputs DBG_MSG_MQLFUNC_RETURN(FrameInputs)
#define FrameNext DBG_MSG_MQLFUNC_RETURN(FrameNext)
#endif
#define GetLastError DBG_MSG_MQLFUNC_RETURN(GetLastError)
#define GetMicrosecondCount DBG_MSG_MQLFUNC_RETURN(GetMicrosecondCount)
#define GetPointer DBG_MSG_MQLFUNC_PTR(GetPointer)
#define GetTickCount DBG_MSG_MQLFUNC_RETURN(GetTickCount)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define GetTickCount64 DBG_MSG_MQLFUNC_RETURN(GetTickCount64)
#endif
#define GlobalVariableCheck DBG_MSG_MQLFUNC_RETURN(GlobalVariableCheck)
#define GlobalVariableDel DBG_MSG_MQLFUNC_RETURN(GlobalVariableDel)
#define GlobalVariableGet DBG_MSG_MQLFUNC_RETURN(GlobalVariableGet)
#define GlobalVariableName DBG_MSG_MQLFUNC_RETURN(GlobalVariableName)
#define GlobalVariablesDeleteAll DBG_MSG_MQLFUNC_RETURN(GlobalVariablesDeleteAll)
#define GlobalVariableSet DBG_MSG_MQLFUNC_RETURN(GlobalVariableSet)
#define GlobalVariableSetOnCondition DBG_MSG_MQLFUNC_RETURN(GlobalVariableSetOnCondition)
#define GlobalVariablesFlush DBG_MSG_MQLFUNC(GlobalVariablesFlush)
#define GlobalVariablesTotal DBG_MSG_MQLFUNC_RETURN(GlobalVariablesTotal)
#define GlobalVariableTemp DBG_MSG_MQLFUNC_RETURN(GlobalVariableTemp)
#define GlobalVariableTime DBG_MSG_MQLFUNC_RETURN(GlobalVariableTime)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define HistoryDealGetDouble DBG_MSG_MQLFUNC_RETURN(HistoryDealGetDouble)
#define HistoryDealGetInteger DBG_MSG_MQLFUNC_RETURN(HistoryDealGetInteger)
#define HistoryDealGetString DBG_MSG_MQLFUNC_RETURN(HistoryDealGetString)
#define HistoryDealGetTicket DBG_MSG_MQLFUNC_RETURN(HistoryDealGetTicket)
#define HistoryDealSelect DBG_MSG_MQLFUNC_RETURN(HistoryDealSelect)
#define HistoryDealsTotal DBG_MSG_MQLFUNC_RETURN(HistoryDealsTotal)
#define HistoryOrderGetDouble DBG_MSG_MQLFUNC_RETURN(HistoryOrderGetDouble)
#define HistoryOrderGetInteger DBG_MSG_MQLFUNC_RETURN(HistoryOrderGetInteger)
#define HistoryOrderGetString DBG_MSG_MQLFUNC_RETURN(HistoryOrderGetString)
#define HistoryOrderGetTicket DBG_MSG_MQLFUNC_RETURN(HistoryOrderGetTicket)
#define HistoryOrderSelect DBG_MSG_MQLFUNC_RETURN(HistoryOrderSelect)
#define HistoryOrdersTotal DBG_MSG_MQLFUNC_RETURN(HistoryOrdersTotal)
#define HistorySelect DBG_MSG_MQLFUNC_RETURN(HistorySelect)
#define HistorySelectByPosition DBG_MSG_MQLFUNC_RETURN(HistorySelectByPosition)
#endif
#define iBars DBG_MSG_MQLFUNC_RETURN(iBars)
#define iBarShift DBG_MSG_MQLFUNC_RETURN(iBarShift)
#define iClose DBG_MSG_MQLFUNC_RETURN(iClose)
#define iHigh DBG_MSG_MQLFUNC_RETURN(iHigh)
#define iHighest DBG_MSG_MQLFUNC_RETURN(iHighest)
#define iLow DBG_MSG_MQLFUNC_RETURN(iLow)
#define iLowest DBG_MSG_MQLFUNC_RETURN(iLowest)
#define iOpen DBG_MSG_MQLFUNC_RETURN(iOpen)
#define iTime DBG_MSG_MQLFUNC_RETURN(iTime)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define iTickVolume DBG_MSG_MQLFUNC_RETURN(iTickVolume)
#define iRealVolume DBG_MSG_MQLFUNC_RETURN(iRealVolume)
#endif
#define iVolume DBG_MSG_MQLFUNC_RETURN(iVolume)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define iSpread DBG_MSG_MQLFUNC_RETURN(iSpread)
#endif
#define iAD DBG_MSG_MQLFUNC_RETURN(iAD)
#define iADX DBG_MSG_MQLFUNC_RETURN(iADX)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define iADXWilder DBG_MSG_MQLFUNC_RETURN(iADXWilder)
#endif
#define iAlligator DBG_MSG_MQLFUNC_RETURN(iAlligator)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define iAMA DBG_MSG_MQLFUNC_RETURN(iAMA)
#endif
#define iAO DBG_MSG_MQLFUNC_RETURN(iAO)
#define iATR DBG_MSG_MQLFUNC_RETURN(iATR)
#define iBands DBG_MSG_MQLFUNC_RETURN(iBands)
#define iBearsPower DBG_MSG_MQLFUNC_RETURN(iBearsPower)
#define iBullsPower DBG_MSG_MQLFUNC_RETURN(iBullsPower)
#define iBWMFI DBG_MSG_MQLFUNC_RETURN(iBWMFI)
#define iCCI DBG_MSG_MQLFUNC_RETURN(iCCI)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define iChaikin DBG_MSG_MQLFUNC_RETURN(iChaikin)
#endif
#define iCustom DBG_MSG_MQLFUNC_RETURN(iCustom)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define iDEMA DBG_MSG_MQLFUNC_RETURN(iDEMA)
#endif
#define iDeMarker DBG_MSG_MQLFUNC_RETURN(iDeMarker)
#define iEnvelopes DBG_MSG_MQLFUNC_RETURN(iEnvelopes)
#define iForce DBG_MSG_MQLFUNC_RETURN(iForce)
#define iFractals DBG_MSG_MQLFUNC_RETURN(iFractals)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define iFrAMA DBG_MSG_MQLFUNC_RETURN(iFrAMA)
#endif
#define iGator DBG_MSG_MQLFUNC_RETURN(iGator)
#define iIchimoku DBG_MSG_MQLFUNC_RETURN(iIchimoku)
#define iMA DBG_MSG_MQLFUNC_RETURN(iMA)
#define iMACD DBG_MSG_MQLFUNC_RETURN(iMACD)
#define iMFI DBG_MSG_MQLFUNC_RETURN(iMFI)
#define iMomentum DBG_MSG_MQLFUNC_RETURN(iMomentum)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define IndicatorCreate DBG_MSG_MQLFUNC_RETURN(IndicatorCreate)
#define IndicatorParameters DBG_MSG_MQLFUNC_RETURN(IndicatorParameters)
#define IndicatorRelease DBG_MSG_MQLFUNC_RETURN(IndicatorRelease)
#endif
#define IndicatorSetDouble DBG_MSG_MQLFUNC_RETURN(IndicatorSetDouble)
#define IndicatorSetInteger DBG_MSG_MQLFUNC_RETURN(IndicatorSetInteger)
#define IndicatorSetString DBG_MSG_MQLFUNC_RETURN(IndicatorSetString)
#define IntegerToString DBG_MSG_MQLFUNC_RETURN(IntegerToString)
#define iOBV DBG_MSG_MQLFUNC_RETURN(iOBV)
#define iOsMA DBG_MSG_MQLFUNC_RETURN(iOsMA)
#define iRSI DBG_MSG_MQLFUNC_RETURN(iRSI)
#define iRVI DBG_MSG_MQLFUNC_RETURN(iRVI)
#define iSAR DBG_MSG_MQLFUNC_RETURN(iSAR)
#define IsStopped DBG_MSG_MQLFUNC_RETURN(IsStopped)
#define iStdDev DBG_MSG_MQLFUNC_RETURN(iStdDev)
#define iStochastic DBG_MSG_MQLFUNC_RETURN(iStochastic)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define iTEMA DBG_MSG_MQLFUNC_RETURN(iTEMA)
#define iTriX DBG_MSG_MQLFUNC_RETURN(iTriX)
#define iVIDyA DBG_MSG_MQLFUNC_RETURN(iVIDyA)
#define iVolumes DBG_MSG_MQLFUNC_RETURN(iVolumes)
#define iWPR DBG_MSG_MQLFUNC_RETURN(iWPR)
#endif
#define log DBG_MSG_MQLFUNC_RETURN(log)
#define log10 DBG_MSG_MQLFUNC_RETURN(log10)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define MarketBookAdd DBG_MSG_MQLFUNC_RETURN(MarketBookAdd)
#define MarketBookGet DBG_MSG_MQLFUNC_RETURN(MarketBookGet)
#define MarketBookRelease DBG_MSG_MQLFUNC_RETURN(MarketBookRelease)
#endif
#define MathAbs DBG_MSG_MQLFUNC_RETURN(MathAbs)
#define MathArccos DBG_MSG_MQLFUNC_RETURN(MathArccos)
#define MathArcsin DBG_MSG_MQLFUNC_RETURN(MathArcsin)
#define MathArctan DBG_MSG_MQLFUNC_RETURN(MathArctan)
#define MathCeil DBG_MSG_MQLFUNC_RETURN(MathCeil)
#define MathCos DBG_MSG_MQLFUNC_RETURN(MathCos)
#define MathExp DBG_MSG_MQLFUNC_RETURN(MathExp)
#define MathFloor DBG_MSG_MQLFUNC_RETURN(MathFloor)
#define MathIsValidNumber DBG_MSG_MQLFUNC_RETURN(MathIsValidNumber)
#define MathLog DBG_MSG_MQLFUNC_RETURN(MathLog)
#define MathLog10 DBG_MSG_MQLFUNC_RETURN(MathLog10)
#define MathMax DBG_MSG_MQLFUNC_RETURN(MathMax)
#define MathMin DBG_MSG_MQLFUNC_RETURN(MathMin)
#define MathMod DBG_MSG_MQLFUNC_RETURN(MathMod)
#define MathPow DBG_MSG_MQLFUNC_RETURN(MathPow)
#define MathRand DBG_MSG_MQLFUNC_RETURN(MathRand)
#define MathRound DBG_MSG_MQLFUNC_RETURN(MathRound)
#define MathSin DBG_MSG_MQLFUNC_RETURN(MathSin)
#define MathSqrt DBG_MSG_MQLFUNC_RETURN(MathSqrt)
#define MathSrand DBG_MSG_MQLFUNC_RETURN(MathSrand)
#define MathTan DBG_MSG_MQLFUNC_RETURN(MathTan)
#define MessageBox DBG_MSG_MQLFUNC(MessageBox)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define MQLInfoInteger DBG_MSG_MQLFUNC_RETURN(MQLInfoInteger)
#endif
#define MQLInfoString DBG_MSG_MQLFUNC_RETURN(MQLInfoString)
#define NormalizeDouble DBG_MSG_MQLFUNC_RETURN(NormalizeDouble)
/*
#define ObjectCreate DBG_MSG_MQLFUNC_RETURN(ObjectCreate)
#define ObjectDelete DBG_MSG_MQLFUNC_RETURN(ObjectDelete)
#define ObjectFind DBG_MSG_MQLFUNC_RETURN(ObjectFind)
#define ObjectGetDouble DBG_MSG_MQLFUNC_RETURN(ObjectGetDouble)
#define ObjectGetInteger DBG_MSG_MQLFUNC_RETURN(ObjectGetInteger)
#define ObjectGetString DBG_MSG_MQLFUNC_RETURN(ObjectGetString)
#define ObjectGetTimeByValue DBG_MSG_MQLFUNC_RETURN(ObjectGetTimeByValue)
#define ObjectGetValueByTime DBG_MSG_MQLFUNC_RETURN(ObjectGetValueByTime)
#define ObjectMove DBG_MSG_MQLFUNC_RETURN(ObjectMove)
#define ObjectName DBG_MSG_MQLFUNC_RETURN(ObjectName)
#define ObjectsDeleteAll DBG_MSG_MQLFUNC_RETURN(ObjectsDeleteAll)
#define ObjectSetDouble DBG_MSG_MQLFUNC_RETURN(ObjectSetDouble)
#define ObjectSetInteger DBG_MSG_MQLFUNC_RETURN(ObjectSetInteger)
#define ObjectSetString DBG_MSG_MQLFUNC_RETURN(ObjectSetString)
#define ObjectsTotal DBG_MSG_MQLFUNC_RETURN(ObjectsTotal)
*/
#ifndef __MQL4_COMPATIBILITY_CODE__
#define OrderCalcMargin DBG_MSG_MQLFUNC_RETURN(OrderCalcMargin)
#define OrderCalcProfit DBG_MSG_MQLFUNC_RETURN(OrderCalcProfit)
#define OrderCheck DBG_MSG_MQLFUNC_RETURN(OrderCheck)
#endif
#define OrderGetDouble DBG_MSG_MQLFUNC_RETURN(OrderGetDouble)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define OrderGetInteger DBG_MSG_MQLFUNC_RETURN(OrderGetInteger)
#define OrderGetString DBG_MSG_MQLFUNC_RETURN(OrderGetString)
#define OrderGetTicket DBG_MSG_MQLFUNC_RETURN(OrderGetTicket)
#define OrderSelect DBG_MSG_MQLFUNC_RETURN(OrderSelect)
#endif
#define OrderSend DBG_MSG_MQLFUNC_RETURN(OrderSend)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define OrderSendAsync DBG_MSG_MQLFUNC_RETURN(OrderSendAsync)
#define OrdersTotal DBG_MSG_MQLFUNC_RETURN(OrdersTotal)
#define ParameterGetRange DBG_MSG_MQLFUNC_RETURN(ParameterGetRange)
#define ParameterSetRange DBG_MSG_MQLFUNC_RETURN(ParameterSetRange)
#endif
#define Period DBG_MSG_MQLFUNC_RETURN(Period)
#define PeriodSeconds DBG_MSG_MQLFUNC_RETURN(PeriodSeconds)
#define PlaySound DBG_MSG_MQLFUNC_RETURN(PlaySound)
#define PlotIndexGetInteger DBG_MSG_MQLFUNC_RETURN(PlotIndexGetInteger)
#define PlotIndexSetDouble DBG_MSG_MQLFUNC_RETURN(PlotIndexSetDouble)
#define PlotIndexSetInteger DBG_MSG_MQLFUNC_RETURN(PlotIndexSetInteger)
#define PlotIndexSetString DBG_MSG_MQLFUNC_RETURN(PlotIndexSetString)
#define Point DBG_MSG_MQLFUNC_RETURN(Point)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define PositionGetDouble DBG_MSG_MQLFUNC_RETURN(PositionGetDouble)
#define PositionGetInteger DBG_MSG_MQLFUNC_RETURN(PositionGetInteger)
#define PositionGetString DBG_MSG_MQLFUNC_RETURN(PositionGetString)
#define PositionGetSymbol DBG_MSG_MQLFUNC_RETURN(PositionGetSymbol)
#define PositionGetTicket DBG_MSG_MQLFUNC_RETURN(PositionGetTicket)
#define PositionSelect DBG_MSG_MQLFUNC_RETURN(PositionSelect)
#define PositionSelectByTicket DBG_MSG_MQLFUNC_RETURN(PositionSelectByTicket)
#define PositionsTotal DBG_MSG_MQLFUNC_RETURN(PositionsTotal)
#endif
#define pow DBG_MSG_MQLFUNC_RETURN(pow)
#define Print DBG_MSG_MQLFUNC(Print)
#define PrintFormat DBG_MSG_MQLFUNC(PrintFormat)
#define rand DBG_MSG_MQLFUNC_RETURN(rand)
#define ResetLastError DBG_MSG_MQLFUNC(ResetLastError)
#define ResourceCreate DBG_MSG_MQLFUNC_RETURN(ResourceCreate)
#define ResourceFree DBG_MSG_MQLFUNC_RETURN(ResourceFree)
#define ResourceReadImage DBG_MSG_MQLFUNC_RETURN(ResourceReadImage)
#define ResourceSave DBG_MSG_MQLFUNC_RETURN(ResourceSave)
#define round DBG_MSG_MQLFUNC_RETURN(round)
#define SendFTP DBG_MSG_MQLFUNC_RETURN(SendFTP)
#define SendMail DBG_MSG_MQLFUNC_RETURN(SendMail)
#define SendNotification DBG_MSG_MQLFUNC_RETURN(SendNotification)
#define SeriesInfoInteger DBG_MSG_MQLFUNC_RETURN(SeriesInfoInteger)
#define SetIndexBuffer DBG_MSG_MQLFUNC_RETURN(SetIndexBuffer)
#define ShortArrayToString DBG_MSG_MQLFUNC_RETURN(ShortArrayToString)
#define ShortToString DBG_MSG_MQLFUNC_RETURN(ShortToString)
#define SignalBaseGetDouble DBG_MSG_MQLFUNC_RETURN(SignalBaseGetDouble)
#define SignalBaseGetInteger DBG_MSG_MQLFUNC_RETURN(SignalBaseGetInteger)
#define SignalBaseGetString DBG_MSG_MQLFUNC_RETURN(SignalBaseGetString)
#define SignalBaseSelect DBG_MSG_MQLFUNC_RETURN(SignalBaseSelect)
#define SignalBaseTotal DBG_MSG_MQLFUNC_RETURN(SignalBaseTotal)
#define SignalInfoGetDouble DBG_MSG_MQLFUNC_RETURN(SignalInfoGetDouble)
#define SignalInfoGetInteger DBG_MSG_MQLFUNC_RETURN(SignalInfoGetInteger)
#define SignalInfoGetString DBG_MSG_MQLFUNC_RETURN(SignalInfoGetString)
#define SignalInfoSetDouble DBG_MSG_MQLFUNC_RETURN(SignalInfoSetDouble)
#define SignalInfoSetInteger DBG_MSG_MQLFUNC_RETURN(SignalInfoSetInteger)
#define SignalSubscribe DBG_MSG_MQLFUNC_RETURN(SignalSubscribe)
#define SignalUnsubscribe DBG_MSG_MQLFUNC_RETURN(SignalUnsubscribe)
#define sin DBG_MSG_MQLFUNC_RETURN(sin)
#define Sleep DBG_MSG_MQLFUNC(Sleep)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define SocketCreate DBG_MSG_MQLFUNC_RETURN(SocketCreate)
#define SocketClose DBG_MSG_MQLFUNC_RETURN(SocketClose)
#define SocketConnect DBG_MSG_MQLFUNC_RETURN(SocketConnect)
#define SocketIsConnected DBG_MSG_MQLFUNC_RETURN(SocketIsConnected)
#define SocketIsReadable DBG_MSG_MQLFUNC_RETURN(SocketIsReadable)
#define SocketIsWritable DBG_MSG_MQLFUNC_RETURN(SocketIsWritable)
#define SocketTimeouts DBG_MSG_MQLFUNC_RETURN(SocketTimeouts)
#define SocketRead DBG_MSG_MQLFUNC_RETURN(SocketRead)
#define SocketSend DBG_MSG_MQLFUNC_RETURN(SocketSend)
#define SocketTlsHandshake DBG_MSG_MQLFUNC_RETURN(SocketTlsHandshake)
#define SocketTlsCertificate DBG_MSG_MQLFUNC_RETURN(SocketTlsCertificate)
#define SocketTlsRead DBG_MSG_MQLFUNC_RETURN(SocketTlsRead)
#define SocketTlsReadAvailable DBG_MSG_MQLFUNC_RETURN(SocketTlsReadAvailable)
#define SocketTlsSend DBG_MSG_MQLFUNC_RETURN(SocketTlsSend)
#endif
#define sqrt DBG_MSG_MQLFUNC_RETURN(sqrt)
#define srand DBG_MSG_MQLFUNC(srand)
#define StringAdd DBG_MSG_MQLFUNC_RETURN(StringAdd)
#define StringBufferLen DBG_MSG_MQLFUNC_RETURN(StringBufferLen)
#define StringCompare DBG_MSG_MQLFUNC_RETURN(StringCompare)
#define StringConcatenate DBG_MSG_MQLFUNC_RETURN(StringConcatenate)
#define StringFill DBG_MSG_MQLFUNC_RETURN(StringFill)
#define StringFind DBG_MSG_MQLFUNC_RETURN(StringFind)
#define StringFormat DBG_MSG_MQLFUNC_RETURN(StringFormat)
#define StringGetCharacter DBG_MSG_MQLFUNC_RETURN(StringGetCharacter)
#define StringInit DBG_MSG_MQLFUNC_RETURN(StringInit)
#define StringLen DBG_MSG_MQLFUNC_RETURN(StringLen)
#define StringReplace DBG_MSG_MQLFUNC_RETURN(StringReplace)
#define StringSetCharacter DBG_MSG_MQLFUNC_RETURN(StringSetCharacter)
#define StringSplit DBG_MSG_MQLFUNC_RETURN(StringSplit)
#define StringSubstr DBG_MSG_MQLFUNC_RETURN(StringSubstr)
#define StringToCharArray DBG_MSG_MQLFUNC_RETURN(StringToCharArray)
#define StringToColor DBG_MSG_MQLFUNC_RETURN(StringToColor)
#define StringToDouble DBG_MSG_MQLFUNC_RETURN(StringToDouble)
#define StringToInteger DBG_MSG_MQLFUNC_RETURN(StringToInteger)
#define StringToLower DBG_MSG_MQLFUNC_RETURN(StringToLower)
#define StringToShortArray DBG_MSG_MQLFUNC_RETURN(StringToShortArray)
#define StringToTime DBG_MSG_MQLFUNC_RETURN(StringToTime)
#define StringToUpper DBG_MSG_MQLFUNC_RETURN(StringToUpper)
#define StringTrimLeft DBG_MSG_MQLFUNC_RETURN(StringTrimLeft)
#define StringTrimRight DBG_MSG_MQLFUNC_RETURN(StringTrimRight)
#define StructToTime DBG_MSG_MQLFUNC_RETURN(StructToTime)
#define Symbol DBG_MSG_MQLFUNC_RETURN(Symbol)
#define SymbolInfoDouble DBG_MSG_MQLFUNC_RETURN(SymbolInfoDouble)
#define SymbolInfoInteger DBG_MSG_MQLFUNC_RETURN(SymbolInfoInteger)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define SymbolInfoMarginRate DBG_MSG_MQLFUNC_RETURN(SymbolInfoMarginRate)
#endif
#define SymbolInfoSessionQuote DBG_MSG_MQLFUNC_RETURN(SymbolInfoSessionQuote)
#define SymbolInfoSessionTrade DBG_MSG_MQLFUNC_RETURN(SymbolInfoSessionTrade)
#define SymbolInfoString DBG_MSG_MQLFUNC_RETURN(SymbolInfoString)
#define SymbolInfoTick DBG_MSG_MQLFUNC_RETURN(SymbolInfoTick)
#define SymbolIsSynchronized DBG_MSG_MQLFUNC_RETURN(SymbolIsSynchronized)
#define SymbolName DBG_MSG_MQLFUNC_RETURN(SymbolName)
#define SymbolSelect DBG_MSG_MQLFUNC_RETURN(SymbolSelect)
#define SymbolsTotal DBG_MSG_MQLFUNC_RETURN(SymbolsTotal)
#define tan DBG_MSG_MQLFUNC_RETURN(tan)
#define TerminalClose DBG_MSG_MQLFUNC_RETURN(TerminalClose)
#define TerminalInfoDouble DBG_MSG_MQLFUNC_RETURN(TerminalInfoDouble)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define TerminalInfoInteger DBG_MSG_MQLFUNC_RETURN(TerminalInfoInteger)
#endif
#define TerminalInfoString DBG_MSG_MQLFUNC_RETURN(TerminalInfoString)
#define TesterStatistics DBG_MSG_MQLFUNC_RETURN(TesterStatistics)
#define TextGetSize DBG_MSG_MQLFUNC_RETURN(TextGetSize)
#define TextOut DBG_MSG_MQLFUNC_RETURN(TextOut)
#define TextSetFont DBG_MSG_MQLFUNC_RETURN(TextSetFont)
#define TimeCurrent DBG_MSG_MQLFUNC_RETURN(TimeCurrent)
#define TimeDaylightSavings DBG_MSG_MQLFUNC_RETURN(TimeDaylightSavings)
#define TimeGMT DBG_MSG_MQLFUNC_RETURN(TimeGMT)
#define TimeGMTOffset DBG_MSG_MQLFUNC_RETURN(TimeGMTOffset)
#define TimeLocal DBG_MSG_MQLFUNC_RETURN(TimeLocal)
#define TimeToString DBG_MSG_MQLFUNC_RETURN(TimeToString)
#define TimeToStruct DBG_MSG_MQLFUNC_RETURN(TimeToStruct)
#ifndef __MQL4_COMPATIBILITY_CODE__
#define TimeTradeServer DBG_MSG_MQLFUNC_RETURN(TimeTradeServer)
#endif
#define UninitializeReason DBG_MSG_MQLFUNC_RETURN(UninitializeReason)
#define WebRequest DBG_MSG_MQLFUNC_RETURN(WebRequest)
#define ZeroMemory DBG_MSG_MQLFUNC(ZeroMemory)
#endif
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Runtime code setup
//
#else
// Define runtime mode
#define LIB_DBG_DEBUG_MQH_RUNTIME_MODE
// Clear any existing definitions
#ifdef DBG_CODE_LOCATION
#undef DBG_CODE_LOCATION
#endif
#ifdef DBG_DEBUGGER_FLAG_STATE
#undef DBG_DEBUGGER_FLAG_STATE
#endif
#ifdef DBG_STR_EX45_FILEINFO
#undef DBG_STR_EX45_FILEINFO
#endif
#ifdef DBG_STR
#undef DBG_STR
#endif
#ifdef DBG_STR_PERSIST
#undef DBG_STR_PERSIST
#endif
#ifdef DBG_STR_VAR
#undef DBG_STR_VAR
#endif
#ifdef DBG_STR_BOOL
#undef DBG_STR_BOOL
#endif
#ifdef DBG_MSG
#undef DBG_MSG
#endif
#ifdef DBG_MSG_SHIFT
#undef DBG_MSG_SHIFT
#endif
#ifdef DBG_MSG_PERSIST
#undef DBG_MSG_PERSIST
#endif
#ifdef DBG_MSG_VAR
#undef DBG_MSG_VAR
#endif
#ifdef DBG_MSG_VAR_IF
#undef DBG_MSG_VAR_IF
#endif
#ifdef DBG_MSG_VARDUMP
#undef DBG_MSG_VARDUMP
#endif
#ifdef DBG_MSG_LISTDUMP
#undef DBG_MSG_LISTDUMP
#endif
#ifdef DBG_MSG_TRACE_BEGIN
#undef DBG_MSG_TRACE_BEGIN
#endif
#ifdef DBG_MSG_TRACE_END
#undef DBG_MSG_TRACE_END
#endif
#ifdef DBG_MSG_TRACE_RETURN
#undef DBG_MSG_TRACE_RETURN
#endif
#ifdef DBG_MSG_TRACE_RETURN_VAR
#undef DBG_MSG_TRACE_RETURN_VAR
#endif
#ifdef DBG_MSG_NOTRACE_RETURN
#undef DBG_MSG_NOTRACE_RETURN
#endif
#ifdef DBG_MSG_NOTRACE_RETURN_VAR
#undef DBG_MSG_NOTRACE_RETURN_VAR
#endif
#ifdef DBG_SET_UNINIT_REASON
#undef DBG_SET_UNINIT_REASON
#endif
#ifdef DBG_MSG_UNINIT_RESOLVER
#undef DBG_MSG_UNINIT_RESOLVER
#endif
#ifdef DBG_STR_COMMENT
#undef DBG_STR_COMMENT
#endif
#ifdef DBG_FILELOADER_VARNAME
#undef DBG_FILELOADER_VARNAME
#endif
#ifdef DBG_MSG_TRACE_FILE_LOADER
#undef DBG_MSG_TRACE_FILE_LOADER
#endif
#ifdef DBG_ASSERT
#undef DBG_ASSERT
#endif
#ifdef DBG_ASSERT_LOG
#undef DBG_ASSERT_LOG
#endif
#ifdef DBG_ASSERT_RETURN
#undef DBG_ASSERT_RETURN
#endif
#ifdef DBG_ASSERT_RETURN_VAR
#undef DBG_ASSERT_RETURN_VAR
#endif
#ifdef DBG_STOP_ARRAY_OUT_OF_RANGE
#undef DBG_STOP_ARRAY_OUT_OF_RANGE
#endif
#ifdef DBG_SLEEP_SECONDS
#undef DBG_SLEEP_SECONDS
#endif
#ifdef DBG_SOFT_BREAKPOINT
#undef DBG_SOFT_BREAKPOINT
#endif
#ifdef DBG_SOFT_BREAKPOINT_TS
#undef DBG_SOFT_BREAKPOINT_TS
#endif
#ifdef DBG_SOFT_BREAKPOINT_CONDITION
#undef DBG_SOFT_BREAKPOINT_CONDITION
#endif
#ifdef DBG_SOFT_BREAKPOINT_EXEC_TIME
#undef DBG_SOFT_BREAKPOINT_EXEC_TIME
#endif
#ifdef DBG_BREAK_CONDITION_CREATE
#undef DBG_BREAK_CONDITION_CREATE
#endif
#ifdef DBG_BREAK_CONDITION_ACTIVATE
#undef DBG_BREAK_CONDITION_ACTIVATE
#endif
#ifdef DBG_BREAK_CONDITION_DEACTIVATE
#undef DBG_BREAK_CONDITION_DEACTIVATE
#endif
#ifdef DBG_BREAK_CONDITION_ON_ID
#undef DBG_BREAK_CONDITION_ON_ID
#endif
#ifdef DBG_TRACE_LOOP_BEGIN
#undef DBG_TRACE_LOOP_BEGIN
#endif
#ifdef DBG_TRACE_LOOP_START
#undef DBG_TRACE_LOOP_START
#endif
#ifdef DBG_TRACE_LOOP_FINISH
#undef DBG_TRACE_LOOP_FINISH
#endif
#ifdef DBG_TRACE_LOOP_END
#undef DBG_TRACE_LOOP_END
#endif
#ifdef DBG_TRACE_LOOP_BEGIN_ID
#undef DBG_TRACE_LOOP_BEGIN_ID
#endif
#ifdef DBG_TRACE_LOOP_START_ID
#undef DBG_TRACE_LOOP_START_ID
#endif
#ifdef DBG_TRACE_LOOP_FINISH_ID
#undef DBG_TRACE_LOOP_FINISH_ID
#endif
#ifdef DBG_TRACE_LOOP_END_ID
#undef DBG_TRACE_LOOP_END_ID
#endif
// EX5 File info string
#define DBG_DEBUGGER_FLAG_STATE "[RELEASE]"
#define DBG_STR_EX45_FILEINFO StringFormat("MQL5 build: %i %s", __MQL5BUILD__, DBG_DEBUGGER_FLAG_STATE)
// Remove debug output and comments
// Location string
#define DBG_CODE_LOCATION(x)
// Debug to string functions
#define DBG_STR(x)
#define DBG_STR_PERSIST(x) x
#define DBG_STR_VAR(x)
#define DBG_STR_BOOL(x)
// Debug std out
#define DBG_MSG(x)
#define DBG_MSG_SHIFT
#define DBG_MSG_PERSIST(x) printf(x)
#define DBG_MSG_VAR(x)
#define DBG_MSG_VAR_IF(x, y)
#define DBG_MSG_VARDUMP(x)
#define DBG_MSG_LISTDUMP(x, y)
// Code tracing helpers
#define DBG_MSG_TRACE_BEGIN
#define DBG_MSG_TRACE_END
#define DBG_MSG_TRACE_RETURN PERF_COUNTER_END return
#define DBG_MSG_TRACE_RETURN_VAR(x) PERF_COUNTER_END return(x)
#define DBG_MSG_NOTRACE_RETURN PERF_COUNTER_END return
#define DBG_MSG_NOTRACE_RETURN_VAR(x) PERF_COUNTER_END return(x)
// Debug comments
#define DBG_SET_UNINIT_REASON(x)
#define DBG_MSG_UNINIT_RESOLVER
#define DBG_STR_COMMENT(x) NULL
#define DBG_MSG_TRACE_FILE_LOADER
// Remove asserts
#define DBG_ASSERT(condition, message)
#define DBG_ASSERT_LOG(condition, message)
#define DBG_ASSERT_RETURN_VOID(condition, message)
#define DBG_ASSERT_RETURN(condition, message, return_value)
#define DBG_STOP_ARRAY_OUT_OF_RANGE(x, y)
// Remove soft break points
#define DBG_SLEEP_SECONDS(x)
#define DBG_SOFT_BREAKPOINT
#define DBG_SOFT_BREAKPOINT_TS(x)
#define DBG_SOFT_BREAKPOINT_CONDITION(x)
#define DBG_SOFT_BREAKPOINT_EXEC_TIME(x)
#define DBG_BREAK_CONDITION_CREATE(x, y)
#define DBG_BREAK_CONDITION_ACTIVATE(x, y)
#define DBG_BREAK_CONDITION_DEACTIVATE(x, y)
#define DBG_BREAK_CONDITION_ON_ID(x)
// Loop tracing
#define DBG_TRACE_LOOP_BEGIN
#define DBG_TRACE_LOOP_START
#define DBG_TRACE_LOOP_FINISH
#define DBG_TRACE_LOOP_END
#define DBG_TRACE_LOOP_BEGIN_ID(x)
#define DBG_TRACE_LOOP_START_ID(x)
#define DBG_TRACE_LOOP_FINISH_ID(x)
#define DBG_TRACE_LOOP_END_ID(x)
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Performance profiling support
//
#ifdef LIB_PERF_PROFILING
// Internal global counters
#ifndef LIB_PERF_NAMESPACE
#define LIB_PERF_NAMESPACE
#ifndef __MQL4_COMPATIBILITY_CODE__
namespace lib_perf
{
#endif
static ulong LIB_DBG_NAMESPACE(lib_perf, perf_counters) = 0x00;
static ulong LIB_DBG_NAMESPACE(lib_perf, perf_array)[];
static ulong LIB_DBG_NAMESPACE(lib_perf, perf_min)[];
static ulong LIB_DBG_NAMESPACE(lib_perf, perf_max)[];
#ifndef __MQL4_COMPATIBILITY_CODE__
};
#endif
#endif
// Performance output format string
#define PERF_OUTPUT_FORMAT(x) printf("%s() Runtime: %i microseconds; average(%i), min(%i), max(%i); total calls: %i", __FUNCTION__, _perf_runtime_##x, (LIB_DBG_NAMESPACE(lib_perf, perf_array)[(int)_perf_id_##x] / _perf_calls_##x), LIB_DBG_NAMESPACE(lib_perf, perf_min)[(int)_perf_id_##x], LIB_DBG_NAMESPACE(lib_perf, perf_max)[(int)_perf_id_##x], _perf_calls_##x);
// Performance arrays
#define PERF_SET_ARRAYS ((ulong)((ArrayResize(LIB_DBG_NAMESPACE(lib_perf, perf_array), (int)LIB_DBG_NAMESPACE(lib_perf, perf_counters)) > NULL) && (ArrayResize(LIB_DBG_NAMESPACE(lib_perf, perf_min), (int)LIB_DBG_NAMESPACE(lib_perf, perf_counters)) > NULL) && ((LIB_DBG_NAMESPACE(lib_perf, perf_min)[(int)LIB_DBG_NAMESPACE(lib_perf, perf_counters) - 1] = ((ulong)0x01 << 60)) > 0x00) && (ArrayResize(LIB_DBG_NAMESPACE(lib_perf, perf_max), (int)LIB_DBG_NAMESPACE(lib_perf, perf_counters)) > 0x00)))
#define PERF_UPDATE_COUNTERS(x) LIB_DBG_NAMESPACE(lib_perf, perf_array)[(int)_perf_id_##x] += _perf_runtime_##x; LIB_DBG_NAMESPACE(lib_perf, perf_min)[(int)_perf_id_##x] = (((LIB_DBG_NAMESPACE(lib_perf, perf_min)[(int)_perf_id_##x] > _perf_runtime_##x) || (LIB_DBG_NAMESPACE(lib_perf, perf_min)[(int)_perf_id_##x] == 0x00)) ? _perf_runtime_##x : LIB_DBG_NAMESPACE(lib_perf, perf_min)[(int)_perf_id_##x]); LIB_DBG_NAMESPACE(lib_perf, perf_max)[(int)_perf_id_##x] = ((LIB_DBG_NAMESPACE(lib_perf, perf_max)[(int)_perf_id_##x] < _perf_runtime_##x) ? _perf_runtime_##x : LIB_DBG_NAMESPACE(lib_perf, perf_max)[(int)_perf_id_##x]);
// Counter init
#define PERF_COUNTER_DEFINE_ID(x) const static ulong _perf_id_##x = LIB_DBG_NAMESPACE(lib_perf, perf_counters)++; static ulong _perf_start_##x = PERF_SET_ARRAYS; static ulong _perf_calls_##x = (LIB_DBG_NAMESPACE(lib_perf, perf_array)[(int)_perf_id_##x] = 0x00); _perf_calls_##x++;
// Counter start
#define PERF_COUNTER_SET_ID(x) _perf_start_##x = GetMicrosecondCount();
// Display performance counter
#define PERF_COUNTER_CLOSE_ID(x) { const ulong _perf_runtime_##x = (GetMicrosecondCount() - _perf_start_##x); PERF_UPDATE_COUNTERS(x); PERF_OUTPUT_FORMAT(x) }
// Predefined function global performance counter
#define PERF_COUNTER_BEGIN PERF_COUNTER_DEFINE_ID(__FUNCTION__) PERF_COUNTER_SET_ID(__FUNCTION__)
#define PERF_COUNTER_END PERF_COUNTER_CLOSE_ID(__FUNCTION__)
#endif
#endif
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Remove performance profiling support
//
#ifndef LIB_PERF_PROFILING
// Remove all performance collector code
#ifndef PERF_COUNTER_DEFINE_ID
#define PERF_COUNTER_DEFINE_ID(x)
#endif
#ifndef PERF_COUNTER_SET_ID
#define PERF_COUNTER_SET_ID(x)
#endif
#ifndef PERF_COUNTER_CLOSE_ID
#define PERF_COUNTER_CLOSE_ID(x)
#endif
#ifndef PERF_COUNTER_BEGIN
#define PERF_COUNTER_BEGIN
#endif
#ifndef PERF_COUNTER_END
#define PERF_COUNTER_END
#endif
#endif
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// END Debugging support
//*********************************************************************************************************************************************************/
#endif // LIB_DEBUG_MQH_INCLUDED