/********************************************************************************** * Copyright (C) 2020 Dominik Egert * * This file is the lib_debug demonstration file. * * Lisence applied: Free, no license applied to this file. * * Author Dominik Egert / Freie Netze UG. ********************************************************************************** * * Version: 1.01 * State: public * * File information * ================ * */ #property version "1.01" /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Additional options for LIB_DEBUG // // LIB_DEBUG_AUTOENABLE // // This flag will make the library switch between runtime and debugging mode, depending on // the compiler target. (Automatically also defines LIB_DEBUG) // // Runtime mode: // Any program that is compiled in MetaEditor and then launched in Terminal, rather than // using "Start/resume debugging" buttons from MetaEditor. (CTRL-F5 or F5) // // Debugging mode: // When compiling the program in MEtaEditor and launching by one of the buttons // "Start/resume debugging" (CTRL-F5 or F5) // // Compiler-Target: // Depending on where a program has been launched, the target is defined either as // "debugging" or "runtime" environment. // // // LIB_DEBUG_LOGFILE // // Debugging library supports output logging to file. This feature can be enabled by defining // "LIB_DEBUG_LOGFILE" as shown below. (Automatically also defines LIB_DEBUG) // Logs will be written to Common/* directory. // // This feature supports debug logging within optimizer runs of the program. // // // LIB_DEBUG_NO_JOURNAL_OUTPUT // // Additionally the expert-journal output can be surpressed, separating the logs into two // targets. - This way logging debug output and logging terminal output is separated. // // Define "LIB_DEBUG_NO_JOURNAL_OUTPUT" to disable expert-journal output from this library. // (Can only be used if LIB_DEBUG_LOGFILE is defined) // // ///////////////////////////////////////// // // Include the library // #define LIB_DEBUG #include /////////////////////////////////////////////////////////////////////// // // In OnInit you can see a simple usage of the debugging macros. // // We will only use some stand-alone macros for quick debugging. // // DBG_MSG() // DBG_MSG_VAR() // DBG_MSG_BITS() // DBG_MSG_ERRCODE() // DBG_MSG_EVAL() // // Check example below for some variations. // // These macros support all built-in datatypes (also in form of arrays). // (unsigned) char, short, int, long // bool, datetime, color, complex, matrix(f/c), vector(f/c), // float, double, // string, enum, struct, class and interface as well as pointers. // // // And MQL structures: // MqlDateTime, MqlRates, MqlTick, MqlParam, MqlBookInfo, // MqlTradeRequest, MqlTradeCheckResult, MqlTradeResult, // MqlTradeTransaction, // MqlCalendarCountry, MqlCalendarEvent, MqlCalendarValue, // DXVector, DXVertexLayout // // How to make a custom enumeration resolvable // // This needs to be on global scope, will not work for // enumerations, you declare inside of a functions body. // // This works using namespaces as well. // enum custom_enum { SOME_ENUM_VAL1, SOME_ENUM_VAL2 }; DBG_ENUM_RESOLVER(custom_enum); //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { ////////////////////////////////////////////////////////////// // // Simple output macros // // Some initial debug message DBG_MSG("Example how to use lib_debug.mqh simple and quick debugging"); // Output details about current program // Available in debugging and runtime printf("%s", DBG_STR_EX45_FILEINFO); // Keep this message also in runtime builds DBG_MSG_PERSIST("Persistent message in debug and runtime (Runtime is without debug details)"); ////////////////////////////////////////////////////////////// // // All basic output macros available // ////////////////////////////////////////////////////////////// // // Direct value printing // int test_var = 12345; DBG_MSG("Test A"); DBG_MSG_PERSIST("Some message"); DBG_MSG_VAR(PRICE_CLOSE); DBG_MSG_VAR(1); DBG_MSG_VAR(true); DBG_MSG_VAR(TimeCurrent()); DBG_MSG_VAR(clrBlue); DBG_MSG_VAR("Print Me"); DBG_MSG_VAR(test_var); DBG_MSG_VAR_IF(true, test_var); DBG_MSG_VAR(_LastError); DBG_MSG_ERRCODE(5004); DBG_MSG_BITS((uint)123); DBG_MSG_BITS(test_var); ////////////////////////////////////////////////////////////// // // The flexibility of DBG_MSG_VAR // // Output primitive variables custom_enum my_enum = SOME_ENUM_VAL2; ENUM_APPLIED_PRICE e_val = PRICE_CLOSE; char c_val = 1; uchar uc_val = 2; short s_val = 3; int i_val = 4; long l_val = 5; bool b_val = true; datetime d_val = TimeCurrent(); float flt_val = (float)1.61; double dbl_val = 3.14; color clr_val = clrAqua; string str_val = "Some string"; DBG_MSG_VAR(my_enum); DBG_MSG_VAR(e_val); DBG_MSG_VAR(c_val); DBG_MSG_VAR(uc_val); DBG_MSG_VAR(s_val); DBG_MSG_VAR(i_val); DBG_MSG_VAR(l_val); DBG_MSG_VAR(b_val); DBG_MSG_VAR(d_val); DBG_MSG_VAR(flt_val); DBG_MSG_VAR(dbl_val); DBG_MSG_VAR(clr_val); DBG_MSG_VAR(str_val); #ifdef __MQL5__ complex cmplx_val = { 0.1, 0.2 }; vector v_val = { 0, 1, 2, 3 }; vectorf vf_val = { (float)0.1, (float)1.1, (float)2.1, (float)3.1 }; matrix m_val (1, 2); matrixf mf_val (1.3, 2.3); complex c1 = { DBL_MIN, 0.2 }; complex c2 = { 0.3, DBL_MAX }; complex c3 = { 0.5, 0.6 }; complex c4 = { 0.6, 0.7 }; matrixc mc_val {{c1, c2}, {c3, c4}}; vectorc vc_val = { c1, c2, c3, c4 }; DBG_MSG_VAR(cmplx_val); DBG_MSG_VAR(m_val); DBG_MSG_VAR(mf_val); DBG_MSG_VAR(mc_val); DBG_MSG_VAR(v_val); DBG_MSG_VAR(vf_val); DBG_MSG_VAR(vc_val); #endif ////////////////////////////////////////////////////////////// // // Print unknown objects, see function at the end. // // Example of printing objects class CObj { public: int test; CObj() : test(NULL) { }; CObj(const CObj& p_in) { test = p_in.test; }; } test_obj; DBG_MSG_VAR(test_obj); DBG_MSG_VAR(GetPointer(test_obj)); ////////////////////////////////////////////////////////////// // // Conditional execution of DBG_MSG() and DBG_MSG_VAR() macro // // Use DBG_MSG_IF() as shown below. // Use DBG_MSG_VAR_IF() as shown below. // // NOTE: The fist statement is a boolean evaluation. // It is encapuslated properly and therefore can // be anything that evaluates to "true" or "false". // Same rules apply as for an "if()" statement. bool printme = true; DBG_MSG_IF(printme, "This will only show, if a condition is true!"); DBG_MSG_VAR_IF(printme, TimeLocal()); ////////////////////////////////////////////////////////////// // // Print arrays // // Output arrays int i_arr[50]; for(int cnt = NULL; (cnt < 50) && !_StopFlag; cnt++) { i_arr[cnt] = MathRand(); } DBG_MSG_VAR(i_arr); string str_val_arr[3]; DBG_MSG_VAR(str_val_arr); #ifdef __MQL5__ matrixc mc_val1 {{c1, c2}, {c3, c4}}; matrixc mc_val2 {{c2, c1}, {c3, c4}}; matrixc mc_val3 {{c1, c2}, {c4, c3}}; matrixc mc_val_arr[3]; mc_val_arr[0] = mc_val1; mc_val_arr[1] = mc_val2; mc_val_arr[2] = mc_val3; DBG_MSG_VAR(mc_val_arr); #endif // Output two arrays side by side double d_arr[50]; for(int cnt = NULL; (cnt < 50) && !_StopFlag; cnt++) { d_arr[cnt] = MathRand(); } DBG_MSG_LISTDUMP(i_arr, d_arr); ///////////////////////////////////// // // Access an array // // Check if it is accessible // // These macros will be replaced // for runtime environment to their // normal usage. - No overhead applied. // DBG_MSG_ARRAY_OUT_OF_RANGE(i_arr, 50); ////////////////////////////////////////////////////////////// // // Print structures and arrays of structures // // Output MQL structures MqlDateTime mql_dtm; MqlRates mql_rates; MqlTick mql_tick; MqlParam mql_param; MqlBookInfo mql_book; DBG_MSG_VAR(mql_dtm); DBG_MSG_VAR(mql_rates); DBG_MSG_VAR(mql_tick); DBG_MSG_VAR(mql_param); DBG_MSG_VAR(mql_book); #ifdef __MQL5__ MqlTradeRequest mql_trade_request; MqlTradeCheckResult mql_tradecheckresult; MqlTradeResult mql_trade_result; MqlTradeTransaction mql_transaction; MqlCalendarCountry mql_cal_cntry; MqlCalendarEvent mql_cal_event; MqlCalendarValue mql_cal_value; DXVector mql_dxvector; DXVertexLayout mql_dxvertex; DBG_MSG_VAR(mql_trade_request); DBG_MSG_VAR(mql_tradecheckresult); DBG_MSG_VAR(mql_trade_result); DBG_MSG_VAR(mql_transaction); DBG_MSG_VAR(mql_cal_cntry); DBG_MSG_VAR(mql_cal_event); DBG_MSG_VAR(mql_cal_value); DBG_MSG_VAR(mql_dxvector); DBG_MSG_VAR(mql_dxvertex); #endif // See the difference in type printed DBG_MSG_VAR(EnumToString(mql_param.type)); DBG_MSG_VAR(mql_param.type); DBG_MSG_VAR(mql_param.integer_value); DBG_MSG_VAR(mql_param.double_value); // Output arrays of structures MqlDateTime arr_mql_dtm[3]; MqlRates arr_mql_rates[3]; MqlTick arr_mql_tick[3]; MqlParam arr_mql_param[3]; MqlBookInfo arr_mql_book[3]; DBG_MSG_VAR(arr_mql_dtm); DBG_MSG_VAR(arr_mql_rates); DBG_MSG_VAR(arr_mql_tick); DBG_MSG_VAR(arr_mql_param); DBG_MSG_VAR(arr_mql_book); #ifdef __MQL5__ MqlTradeRequest arr_mql_trade_request[3]; MqlTradeCheckResult arr_mql_tradecheckresult[3]; MqlTradeResult arr_mql_trade_result[3]; MqlTradeTransaction arr_mql_transaction[3]; MqlCalendarCountry arr_mql_cal_cntry[3]; MqlCalendarEvent arr_mql_cal_event[3]; MqlCalendarValue arr_mql_cal_value[3]; DBG_MSG_VAR(arr_mql_trade_request); DBG_MSG_VAR(arr_mql_tradecheckresult); DBG_MSG_VAR(arr_mql_trade_result); DBG_MSG_VAR(arr_mql_transaction); DBG_MSG_VAR(arr_mql_cal_cntry); DBG_MSG_VAR(arr_mql_cal_event); DBG_MSG_VAR(arr_mql_cal_value); #endif ////////////////////////////////////////////////////////////// // // Analyze condition statements // // Any complexity is supported. // Applicable to all condition evaluations. // if(), while(), for(), () ? : ; .... // // The last parameter will be always your condition, // you would have in your original ()-statement. // // All combinations are possible. // // Here are the available macros: if( (DBG_MSG_EVAL(0.1 + 0.2 == 0.3)) || (DBG_MSG_EVAL(0.7 - 0.4 == 0.3)) ) { Print("true"); } else { Print("false"); } if(DBG_MSG_EVAL_IF(printme, 0.1 + 0.2 == 0.3)) { Print("true"); } else { Print("false"); } if(DBG_MSG_EVAL_CMNT("Check equality", 0.1 + 0.2 == 0.3)) { Print("true"); } else { Print("false"); } if(DBG_MSG_EVAL_IF_CMNT(printme, "Check equality", 0.1 + 0.2 == 0.3)) { Print("true"); } else { Print("false"); } printme = false; if(DBG_MSG_EVAL_IF(printme, 0.1 + 0.2 == 0.3)) { Print("true"); } else { Print("false"); } if(DBG_MSG_EVAL_IF_CMNT(printme, "Check equality", 0.1 + 0.2 == 0.3)) { Print("true"); } else { Print("false"); } // Return return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert OnTick function | //+------------------------------------------------------------------+ void OnTIck() { return; }