#ifndef LIB_DBG_DEBUG_MQLAPI_TRACER_MQH_INCLUDED #define LIB_DBG_DEBUG_MQLAPI_TRACER_MQH_INCLUDED #property version "5.10" /********************************************************************************** * Copyright (C) 2020 Dominik Egert * * This file is the MQL-API base tracer object 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 // ///////////////////////////////////////////////////////////////////////////////////////////////////// // // MQL API general function scheme // // // This function wrapping scheme is used for all mql-api-functions. // // In basic there are three types of function wrapping methods to be used. // - Functions of VOID-Type // - Functions of RETURN-Type // - Variable input parameter functions // // Representation of the original function signature as documented was most important, to prevent differences // by the wrapper and the original function. - In case of doubt, the more reliable option was chosen. // // // Example function wrapper for RETURN-Type: // // Original function signature from documentation: // // int WebRequest( // const string method, // HTTP method // const string url, // URL // const string headers, // headers // int timeout, // timeout // const char &data[], // the array of the HTTP message body // char &result[], // an array containing server response data // string &result_headers // headers of server response // ); // // Wrapper replacement: // // int dbg_mqlapi_trace_func_WebRequest(const string method, const string url, const string headers, int timeout, const char& data[], char& result[], string& result_headers) // { // // Trace call setup // DBG_MQLAPI_TRACE_FUNCTION_CALL_SETUP; // // // All input variables are stringified to "_params_in"-member variable. // DBG_MQLAPI_TRACE_FUNC_PARAMS_STR(7, method, url, headers, timeout, data, result, result_headers); // // // The actual wrapped MQL api function call // int retval = WebRequest(method, url, headers, timeout, data, result, result_headers); // // // In case output is provided by parameter references, output-print is avialable in "_params_out" member variable. // DBG_MQLAPI_TRACE_FUNC_PARAM_RESULTS_STR(2, result, result_headers, NULL, NULL, NULL, NULL, NULL); // // // Output return value given by mql function // DBG_MQLAPI_TRACE_PRINT_RETURN(retval); // // // Finalize call tracing // DBG_MQLAPI_TRACE_FUNCTION_CALL_FINALIZE; // return(retval); // }; // // // Example function wrapper for VOID-Type: // // Original function signature form documentation: // // void ArrayPrint( // const void& array[], // printed array // uint digits=_Digits, // number of decimal places // const string separator=NULL, // separator of the structure field values // ulong start=0, // first printed element index // ulong count=WHOLE_ARRAY, // number of printed elements // ulong flags=ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN // ); // // Wrapper replacement: // // template // void dbg_mqlapi_trace_ArrayPrint(const T& arr[], uint digits = UINT_MAX, const string separator = NULL, ulong start = 0, ulong count = WHOLE_ARRAY, ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) // { // // Trace call setup // DBG_MQLAPI_TRACE_FUNCTION_CALL_SETUP; // // // Additional setup to ensure function compatibility to the original signature. // int _digits = (digits == UINT_MAX) ? _Digits : digits; // // // All input variables are stringified to "_params_in"-member variable. // DBG_MQLAPI_TRACE_FUNC_PARAMS_STR(6, arr, _digits, separator, start, count, flags); // // // The actual wrapped MQL api function call // ArrayPrint(arr, _digits, separator, start, count, flags); // // // Output void type function // DBG_MQLAPI_TRACE_PRINT; // // // FInalize call tracing // DBG_MQLAPI_TRACE_FUNCTION_CALL_FINALIZE; // return; // }; // // // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // MQL API tracer special function definitions // // MQL API Function IDs for variable inputs #define DBG_MQL_API_TRACING_FUNCTION_ID_ALERT -1 #define DBG_MQL_API_TRACING_FUNCTION_ID_COMMENT -2 #define DBG_MQL_API_TRACING_FUNCTION_ID_PRINT -3 #define DBG_MQL_API_TRACING_FUNCTION_ID_PRINTF -4 #define DBG_MQL_API_TRACING_FUNCTION_ID_PRINTFORMAT -5 #define DBG_MQL_API_TRACING_FUNCTION_ID_STRINGFORMAT -6 #define DBG_MQL_API_TRACING_FUNCTION_ID_PRINTFORMAT_ERROR -126 // Rerouting (c/c++) standard functions to MQL-version Math* #define DBG_MQL_API_TRACING_FUNCTION_ID_ACOS -7 #define DBG_MQL_API_TRACING_FUNCTION_ID_ASIN -8 #define DBG_MQL_API_TRACING_FUNCTION_ID_ATAN -9 #define DBG_MQL_API_TRACING_FUNCTION_ID_CEIL -10 #define DBG_MQL_API_TRACING_FUNCTION_ID_COS -11 #define DBG_MQL_API_TRACING_FUNCTION_ID_EXP -12 #define DBG_MQL_API_TRACING_FUNCTION_ID_FABS -13 #define DBG_MQL_API_TRACING_FUNCTION_ID_FLOOR -14 #define DBG_MQL_API_TRACING_FUNCTION_ID_FMAX -15 #define DBG_MQL_API_TRACING_FUNCTION_ID_FMIN -16 #define DBG_MQL_API_TRACING_FUNCTION_ID_FMOD -17 #define DBG_MQL_API_TRACING_FUNCTION_ID_LOG -18 #define DBG_MQL_API_TRACING_FUNCTION_ID_LOG10 -19 #define DBG_MQL_API_TRACING_FUNCTION_ID_POW -20 #define DBG_MQL_API_TRACING_FUNCTION_ID_RAND -21 #define DBG_MQL_API_TRACING_FUNCTION_ID_ROUND -22 #define DBG_MQL_API_TRACING_FUNCTION_ID_SIN -23 #define DBG_MQL_API_TRACING_FUNCTION_ID_SQRT -24 #define DBG_MQL_API_TRACING_FUNCTION_ID_SRAND -25 #define DBG_MQL_API_TRACING_FUNCTION_ID_TAN -26 // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // MT4/5 API function call meta object // #ifdef __MQL5__ namespace dbg_lib { #endif #ifndef LIB_MQLAPI_TRACE_CUSTOM_EXTENSION class LIB_DBG_NAMESPACE_DEF(dbg_lib, mqlapi_call_tracer_object) { 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)() : _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) #else class LIB_DBG_NAMESPACE_DEF(dbg_lib, mqlapi_call_tracer_object) : public LIB_DBG_NAMESPACE_DEF(dbg_lib, userapi_call_tracer_custom_object) { public: // Constructor LIB_DBG_NAMESPACE_DEF(dbg_lib, mqlapi_call_tracer_object)() #endif { ::printf(" >>> LIB_DEBUG: MQLAPI-Tracer enabled <<< \n - Note: initially clearing _LastError variable now.\n"); ::ResetLastError(); }; LIB_DBG_NAMESPACE_DEF(dbg_lib, mqlapi_call_tracer_object)(const LIB_DBG_NAMESPACE_DEF(dbg_lib, mqlapi_call_tracer_object)& p_in) { _rtol_op = p_in._rtol_op; _prev_err_state = p_in._prev_err_state; _line = p_in._line; _print_params_ = p_in._print_params_; _print_result_ = p_in._print_result_; _perf_runtime_ = p_in._perf_runtime_; _api_name_ = p_in._api_name_; _file = p_in._file; _function = p_in._function; _params_in = p_in._params_in; _params_out = p_in._params_out; _return_type = p_in._return_type; }; // Debug location recorder LIB_DBG_NAMESPACE_DEF(dbg_lib, mqlapi_call_tracer_object)* trace_call_details(const int _line_in, const char _func_id, const string _file_in, const string _function_in, const string _mqlapi_func, const string _api_name = NULL) { // Prestate setup _params_out = NULL; _params_in = NULL; _api_name_ = (_api_name_ == NULL) ? _api_name : _api_name_; _print_params_ = LIB_MQLAPI_TRACE_SHOW_PARAMS; _print_result_ = LIB_MQLAPI_TRACE_SHOW_RESULT; _perf_runtime_ = NULL; _prev_err_state = _LastError; // Trace setup details _line = _line_in; _rtol_op = _func_id; _file = _file_in; _function = _function_in; _mqlapi_funcname = _mqlapi_func; // Overwrite function name, if applicable switch(_rtol_op) { case DBG_MQL_API_TRACING_FUNCTION_ID_ALERT: _mqlapi_funcname = "Alert"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_COMMENT: _mqlapi_funcname = "Comment"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_PRINT: _mqlapi_funcname = "Print"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_PRINTF: _mqlapi_funcname = "printf"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_PRINTFORMAT_ERROR: case DBG_MQL_API_TRACING_FUNCTION_ID_PRINTFORMAT: _mqlapi_funcname = "PrintFormat"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_STRINGFORMAT: _mqlapi_funcname = "StringFormat"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_ACOS: _mqlapi_funcname = "acos"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_ASIN: _mqlapi_funcname = "asin"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_ATAN: _mqlapi_funcname = "atan"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_CEIL: _mqlapi_funcname = "ceil"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_COS: _mqlapi_funcname = "cos"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_EXP: _mqlapi_funcname = "exp"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_FABS: _mqlapi_funcname = "fabs"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_FLOOR: _mqlapi_funcname = "floor"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_FMAX: _mqlapi_funcname = "fmax"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_FMIN: _mqlapi_funcname = "fmin"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_FMOD: _mqlapi_funcname = "fmod"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_LOG: _mqlapi_funcname = "log"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_LOG10: _mqlapi_funcname = "log10"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_POW: _mqlapi_funcname = "pow"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_RAND: _mqlapi_funcname = "rand"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_ROUND: _mqlapi_funcname = "round"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_SIN: _mqlapi_funcname = "sin"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_SQRT: _mqlapi_funcname = "sqrt"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_SRAND: _mqlapi_funcname = "srand"; break; case DBG_MQL_API_TRACING_FUNCTION_ID_TAN: _mqlapi_funcname = "tan"; break; default: { string tmp[]; const int cnt = StringSplit(_mqlapi_func, 0x005F, tmp); _mqlapi_funcname = (cnt > 0) ? tmp[cnt - 1] : _mqlapi_funcname; } } // Clear error code ::ResetLastError(); // Return return(::GetPointer(this)); }; }; #ifdef __MQL5__ }; #endif // ///////////////////////////////////////////////////////////////////////////////////////////////////// // // END Debugging support //*********************************************************************************************************************************************************/ #endif // LIB_DBG_DEBUG_MQLAPI_TRACER_MQH_INCLUDED