#ifndef LIB_DBG_DEBUG_MQLAPI_CUSTOM_BASE_TRACER_MQH_INCLUDED #define LIB_DBG_DEBUG_MQLAPI_CUSTOM_BASE_TRACER_MQH_INCLUDED #property version "5.10" /********************************************************************************** * Copyright (C) 2020 Dominik Egert * * This file is the MQL-API base tracer stub include file. * * Lisence applied: GPLv2 * https://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Author Dominik Egert / Freie Netze UG. ********************************************************************************** * * Version: 5.10 * State: public * * File information * ================ * */ //*********************************************************************************************************************************************************/ // BEGIN MQLAPI tracer custom stub // ///////////////////////////////////////////////////////////////////////////////////////////////////// // // Check custom config setup type // // Having custom config #ifndef LIB_DBG_DEBUG_MQH_INCLUDED #define LIB_DEBUG_CUSTOM_CONFIG #endif // Autoenable LIB_DEBUG #ifdef _DEBUG #ifdef LIB_DEBUG_AUTOENABLE #ifndef LIB_DEBUG #define LIB_DEBUG #endif #endif #endif // Disable all DEBUG_* features in runtime #ifdef LIB_DEBUG_AUTOENABLE #ifndef LIB_DEBUG #undef LIB_DEBUG_LOGFILE #undef LIB_DEBUG_NO_JOURNAL_OUTPUT #undef LIB_DEBUG_MQLAPI_TRACE #undef LIB_MQLAPI_TRACE #endif #endif // Check if library debugging is disabled #ifdef LIB_DEBUG #define LIB_EXTENSIONS_ENABLED #endif #ifdef LIB_DEBUG_MQLAPI_TRACE #undef LIB_EXTENSIONS_ENABLED #define LIB_EXTENSIONS_ENABLED #ifndef LIB_DEBUG #define LIB_DEBUG #define LIB_DEBUG_INCLUDE_STUB #define LIB_MQLAPI_CALL_TRACING_ENABLED #endif #endif #ifdef LIB_MQLAPI_TRACE #undef LIB_EXTENSIONS_ENABLED #define LIB_EXTENSIONS_ENABLED #ifndef LIB_DEBUG #define LIB_DEBUG #define LIB_DEBUG_INCLUDE_STUB #define LIB_MQLAPI_CALL_TRACING_ENABLED #endif #endif #ifndef LIB_EXTENSIONS_ENABLED #undef LIB_MQLAPI_TRACE_CUSTOM_EXTENSION #endif // ///////////////////////////////////////////////////////////////////////////////////////////////////// #ifdef LIB_EXTENSIONS_ENABLED ///////////////////////////////////////////////////////////////////////////////////////////////////// // // Initial setup // // Environment check #ifndef __MQL5__ #ifndef __MQL4_COMPATIBILITY_CODE__ #ifndef __NO_MQL4_COMPATIBILITY_CODE__ #define __NO_MQL4_COMPATIBILITY_CODE__ #endif #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 // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // MQL API tracer stub inclusion // #ifndef LIB_DBG_DEBUG_FUNCTION_TRACE_MACROS_MQH_INCLUDED #include #endif // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // MQL API output option settings // #ifdef LIB_MQLAPI_TRACE_SHOW_PARAMS #undef LIB_MQLAPI_TRACE_SHOW_PARAMS #define LIB_MQLAPI_TRACE_SHOW_PARAMS true #else #undef LIB_MQLAPI_TRACE_SHOW_PARAMS #define LIB_MQLAPI_TRACE_SHOW_PARAMS false #endif #ifdef LIB_MQLAPI_TRACE_SHOW_RESULT #undef LIB_MQLAPI_TRACE_SHOW_RESULT #define LIB_MQLAPI_TRACE_SHOW_RESULT true #else #undef LIB_MQLAPI_TRACE_SHOW_RESULT #define LIB_MQLAPI_TRACE_SHOW_RESULT false #endif // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // MQL API tracer output helper macros // // Simpple output macros #define DBG_MQLAPI_TRACE_STR(x) (LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_context_msg)(DBG_OUTPUT_PREFIX, _file, _function, _line, x)) #define DBG_MQLAPI_TRACE_MSG(x) printf("%s", DBG_MQLAPI_TRACE_STR((x))) #define DBG_MQLAPI_TRACE_STR_INP(x) (LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_context_msg)(DBG_OUTPUT_PREFIX, _file, _function, _line, LIB_DBG_NAMESPACE(dbg_lib, var_out)(#x, (x), 0, DBG_MQLAPI_FUNCTION_ID_PREFIX_IN), "=", DBG_MSG_FORMAT_RIGHT_COLUMN_SPACER)) #define DBG_MQLAPI_TRACE_STR_OUT(x) (LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_context_msg)(DBG_OUTPUT_PREFIX, _file, _function, _line, LIB_DBG_NAMESPACE(dbg_lib, var_out)(#x, (x), 0, DBG_MQLAPI_FUNCTION_ID_PREFIX_OUT), "=", DBG_MSG_FORMAT_RIGHT_COLUMN_SPACER)) #define DBG_MQLAPI_TRACE_MSG_VAR(x) printf("%s", DBG_MQLAPI_TRACE_STR_OUT((x))) #ifdef LIB_MQLAPI_TRACE_PERFORMANCE #define DBG_MQLAPI_FUNCTION_ID_PREFIX_IN StringFormat("%s >>> %s(%ssec: %llu) ", _api_name_, _mqlapi_funcname, ShortToString(0x00B5), _perf_runtime_) #define DBG_MQLAPI_FUNCTION_ID_PREFIX_OUT StringFormat("%s %s(%ssec: %llu) >>> ", _api_name_, _mqlapi_funcname, ShortToString(0x00B5), _perf_runtime_) #else #define DBG_MQLAPI_FUNCTION_ID_PREFIX_IN StringFormat("%s >>> %s() ", _api_name_, _mqlapi_funcname) #define DBG_MQLAPI_FUNCTION_ID_PREFIX_OUT StringFormat("%s %s() >>> ", _api_name_, _mqlapi_funcname) #endif #define DBG_MQLAPI_FUNCTION_ID_MSG_RETURN LIB_DBG_NAMESPACE(dbg_lib, var_out)(" ", retval, 0, DBG_MQLAPI_FUNCTION_ID_PREFIX_OUT) #define DBG_MQLAPI_FUNCTION_ID_MSG_VOID StringFormat("%s returns(void)", DBG_MQLAPI_FUNCTION_ID_PREFIX_OUT) #define DBG_MQLAPI_FUNCTION_ID_MSG ((_return_type == "void") ? DBG_MQLAPI_FUNCTION_ID_MSG_VOID : DBG_MQLAPI_FUNCTION_ID_MSG_RETURN) #define DBG_MSG_MQLAPI_FUNCTION LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)(LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_context_msg)(DBG_OUTPUT_PREFIX, _file, _function, _line, DBG_MQLAPI_FUNCTION_ID_MSG, (_return_type == "void") ? NULL : "=", DBG_MSG_FORMAT_RIGHT_COLUMN_SPACER)) // Precheck error code state #define DBG_MQLAPI_TRACE_FUNC_ERROR_CODE_STATE if(_prev_err_state != DBG_ERR_SUCCESS) { DBG_MQLAPI_TRACE_MSG(StringFormat("_LastError previously set (%i); Clearing!", _prev_err_state)); ResetLastError(); } // Check for errors #define DBG_MQLAPI_TRACE_FUNC_CALL_ERROR if(_LastError != DBG_ERR_SUCCESS) { \ DBG_MQLAPI_TRACE_MSG_VAR(_LastError); \ if(_params_in != NULL) { LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%s", _params_in); } \ if(_params_out != NULL) { LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%s", _params_out); } } \ else if(_print_params_ || _print_result_) { \ if((_print_params_) && (_params_in != NULL)) { LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%s", _params_in); } \ if((_print_result_) && (_params_out != NULL)) { LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%s", _params_out); } } // Stringify function input macro #define DBG_MQLAPI_TRACE_FUNC_PARAMS_STR(nr, a, b, c, d, e, f, g) switch(nr) { case 7: _params_in = DBG_MQLAPI_TRACE_STR_INP(g) + "\n" + _params_in; case 6: _params_in = DBG_MQLAPI_TRACE_STR_INP(f) + "\n" + _params_in; case 5: _params_in = DBG_MQLAPI_TRACE_STR_INP(e) + "\n" + _params_in; case 4: _params_in = DBG_MQLAPI_TRACE_STR_INP(d) + "\n" + _params_in; case 3: _params_in = DBG_MQLAPI_TRACE_STR_INP(c) + "\n" + _params_in; case 2: _params_in = DBG_MQLAPI_TRACE_STR_INP(b) + "\n" + _params_in; case 1: _params_in = DBG_MQLAPI_TRACE_STR_INP(a) + "\n" + _params_in; } // Stringify function output from reference parameter macro #define DBG_MQLAPI_TRACE_FUNC_PARAM_RESULTS_STR(nr, a, b, c, d, e, f, g) switch(nr) { case 7: _params_out = DBG_MQLAPI_TRACE_STR_OUT(g) + "\n" + _params_out; case 6: _params_out = DBG_MQLAPI_TRACE_STR_OUT(f) + "\n" + _params_out; case 5: _params_out = DBG_MQLAPI_TRACE_STR_OUT(e) + "\n" + _params_out; case 4: _params_out = DBG_MQLAPI_TRACE_STR_OUT(d) + "\n" + _params_out; case 3: _params_out = DBG_MQLAPI_TRACE_STR_OUT(c) + "\n" + _params_out; case 2: _params_out = DBG_MQLAPI_TRACE_STR_OUT(b) + "\n" + _params_out; case 1: _params_out = DBG_MQLAPI_TRACE_STR_OUT(a) + "\n" + _params_out; } // Performance tracing macros #ifdef LIB_MQLAPI_TRACE_PERFORMANCE #define DBG_MQLAPI_TRACE_FUNC_BEFORE _perf_runtime_ = GetMicrosecondCount() #define DBG_MQLAPI_TRACE_FUNC_AFTER _perf_runtime_ = (GetMicrosecondCount() - _perf_runtime_) #else #define DBG_MQLAPI_TRACE_FUNC_BEFORE #define DBG_MQLAPI_TRACE_FUNC_AFTER #endif // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // MQL API tracer main inclue macros // // Primary insertion macro for trace setup #define DBG_MQLAPI_TRACE_FUNCTION_CALL_SETUP if((LIB_DBG_NAMESPACE_DEF(dbg_lib, trace_api_calls)) || (LIB_DBG_API_CALL_TRACE_FORCE_ON)) { DBG_MQLAPI_TRACE_FUNC_ERROR_CODE_STATE; } // Primary insertion macro for trace finalize #define DBG_MQLAPI_TRACE_FUNCTION_CALL_FINALIZE if((LIB_DBG_NAMESPACE_DEF(dbg_lib, trace_api_calls)) || (LIB_DBG_API_CALL_TRACE_FORCE_ON)) { DBG_MSG_MQLAPI_FUNCTION; DBG_MQLAPI_TRACE_FUNC_CALL_ERROR; _api_name_ = NULL; } // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // USER API tracer macros // // Return type definition #define DBG_USERAPI_RETURN_TYPE(x) x retval; _return_type = typename((retval)); #define DBG_USERAPI_RETURN_TYPE_VOID string retval = "NV"; _return_type = "void"; // Setup macro #define DBG_USERAPI_TRACE_SETUP(x) DBG_MQLAPI_TRACE_FUNCTION_CALL_SETUP; _api_name_ = x; // Input parameters #define DBG_USERAPI_PARAMS(nr, a, b, c, d, e, f, g) DBG_MQLAPI_TRACE_FUNC_PARAMS_STR(nr, a, b, c, d, e, f, g) // Output variables #define DBG_USERAPI_RESULTS(nr, a, b, c, d, e, f, g) DBG_MQLAPI_TRACE_FUNC_PARAM_RESULTS_STR(nr, a, b, c, d, e, f, g) // Flags for printing #define DBG_USERAPI_PRINT_PARAMS _print_params_ = true; #define DBG_USERAPI_PRINT_RESULT _print_result_ = true; // Call finalize code #define DBG_USERAPI_TRACE_FINALIZE DBG_MQLAPI_TRACE_FUNCTION_CALL_FINALIZE // Tracer macro #define DBG_USERAPI_TRACE_FUNCTION(x) DBG_MSG_TRACE_CUSTOM_FUNC(x) // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // MQL API tracer main inclue macros // #ifdef LIB_MQLAPI_TRACE_CUSTOM_EXTENSION #ifdef __MQL5__ namespace dbg_lib { #endif // MQLAPI tracer base object data class LIB_DBG_NAMESPACE_DEF(dbg_lib, mqlapi_call_tracer_object_data) { protected: // Local storage ulong _perf_runtime_; int _prev_err_state; int _line; char _rtol_op; bool _print_params_; bool _print_result_; string _api_name_; string _file; string _function; string _mqlapi_funcname; string _params_in; string _params_out; string _return_type; public: // Constructor LIB_DBG_NAMESPACE_DEF(dbg_lib, mqlapi_call_tracer_object_data)() : _perf_runtime_ (0), _prev_err_state (0), _line (0), _rtol_op (0), _print_params_ (false), _print_result_ (false), _api_name_ (NULL), _file (NULL), _function (NULL), _mqlapi_funcname (NULL), _params_in (NULL), _params_out (NULL), _return_type (NULL) {}; }; #ifdef __MQL5__ }; // Namespace dbg_lib #endif #endif // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // MQL API tracer main include macros // #ifdef LIB_MQLAPI_TRACE_CUSTOM_EXTENSION // Include basic requirements #include #include // Define custom object name #define LIB_DBG_MQLAPI_TRACER_CUSTOM_OBJECT LIB_DBG_NAMESPACE_DEF(dbg_lib, userapi_call_tracer_custom_object) : public LIB_DBG_NAMESPACE_DEF(dbg_lib, mqlapi_call_tracer_object_data) // Version specific adoption #ifdef __MQL5__ // Define replacement #define LIB_DBG_MQLAPI_TRACER_BASE_OBJECT LIB_DBG_NAMESPACE(dbg_lib, mqlapi_call_tracer_object_mql5) #define LIB_DBG_MQLAPI_TRACER_OBJECT LIB_DBG_NAMESPACE_DEF(dbg_lib, userapi_call_tracer_custom_object) #else // Define replacement #define LIB_DBG_MQLAPI_TRACER_BASE_OBJECT LIB_DBG_NAMESPACE(dbg_lib, mqlapi_call_tracer_object_mql4) #define LIB_DBG_MQLAPI_TRACER_OBJECT LIB_DBG_NAMESPACE_DEF(dbg_lib, userapi_call_tracer_custom_object) #endif #endif // ///////////////////////////////////////////////////////////////////////////////////////////////////// #endif // // END Debugging support //*********************************************************************************************************************************************************/ #endif // LIB_DBG_DEBUG_MQLAPI_CUSTOM_BASE_TRACER_MQH_INCLUDED