Libraries: MQL Plus Enhanced Debugging Support - page 7

 
amrali #:

I have re-tested with the latest version "4.9997" in cloud storage.

Still, the same issues with the above 2 examples in #54

Edit: another problem

New Beta update available in cloud-storage.

I addressed all issues you have reported and as far as I can see from early testing, it seems to be corrected now. 

I addressd both issues, the if() - condition statement as well as un-braced if, for and while statements, and any other like that.


All but GetPointer are as far as I am aware of issues, currently addressed and should finally be persistent...

I will begin testing later, I need a break (and a new keyboard...) 

 
amrali #:

I have re-tested with the latest version "4.9997" in cloud storage.

Still, the same issues with the above 2 examples in #54

Edit: another problem

I am sorry, but it is not working as expected....

It breaks on more complex statements. And on cast-operations at the moment.

I am not sure if it's doable at all. In any case this needs more tinkering.



 
Dominik Christian Egert #:
I am sorry, but it is not working as expected....

It breaks on more complex statements. And on cast-operations at the moment.

I am not sure if it's doable at all. In any case this needs more tinkering.



You are making great progress, definitely! Now, it is a stable Beta that needs some refinements. I am always looking for some api-tracer for mql (even if not working 100%). 

I added these overloads starting at line #1213 in header "lib_debug.mqh" to overcome compiler errors:

                string operator=(string in)                                                     {
                                                                                                    return(in);
                                                                                                };
                double operator=(double in)                                                     {   switch(_rtol_op)
                                                                                                    {
                                                                                                        case 1:     _rtol_op = 0; return(!in);
                                                                                                        case 3:     _rtol_op = 0; return(-in);
                                                                                                        case 4:     _rtol_op = 0; return(--in);
                                                                                                        case 5:     _rtol_op = 0; return(++in);
                                                                                                    }
                                                                                                    return(in);
                                                                                                };
                float operator=(float in)                                                       {   switch(_rtol_op)
                                                                                                    {
                                                                                                        case 1:     _rtol_op = 0; return(!in);
                                                                                                        case 3:     _rtol_op = 0; return(-in);
                                                                                                        case 4:     _rtol_op = 0; return(--in);
                                                                                                        case 5:     _rtol_op = 0; return(++in);
                                                                                                    }
                                                                                                    return(in);
                                                                                                };

Now running this demo script (that considers many test cases) through your api-tracer works as expected. Great! 

Un-resolved bug: for explicit cast, additional parenthesis must be added around the expression to be casted.

#define LIB_DEBUG
#define LIB_DEBUG_MQLAPI
#include "lib_debug.mqh"
void OnStart()
  {
   if(!MathIsValidNumber(1.23))
      Print("number is non valid");
   else
      Print("valid");

// Usage scenario #2
   if(MathIsValidNumber(MathRand()))
      Print("number is valid");

   if(!MathIsValidNumber(MathRand()))
      Print("number is non valid");

   Print(MathRand() + MathRand());

   for(int i = 0; i < 2; i++)
    //(int) floor(log(rand()));      // explicit cast -> does not compile
      (int)(floor(log(rand())));     // except if enclosed in parenthesis
  }


//      >test.mq5< OnStart(){ @6: MQL5-API Function => () MathIsValidNumber                  [bool]   = true }
// valid
//      >test.mq5< OnStart(){ @9: MQL5-API Function => Print() [void]  }
//      >test.mq5< OnStart(){ @12: MQL5-API Function => () MathRand                           [int]    = 24392                     (0x00005F48) }
//      >test.mq5< OnStart(){ @12: MQL5-API Function => () MathIsValidNumber                  [bool]   = true }
// number is valid
//      >test.mq5< OnStart(){ @13: MQL5-API Function => Print() [void]  }
//      >test.mq5< OnStart(){ @15: MQL5-API Function => () MathRand                           [int]    = 11356                     (0x00002C5C) }
//      >test.mq5< OnStart(){ @15: MQL5-API Function => () MathIsValidNumber                  [bool]   = true }
//      >test.mq5< OnStart(){ @18: MQL5-API Function => () MathRand                           [int]    = 12866                     (0x00003242) }
//      >test.mq5< OnStart(){ @18: MQL5-API Function => () MathRand                           [int]    = 10142                     (0x0000279E) }
// 23008
//      >test.mq5< OnStart(){ @18: MQL5-API Function => Print() [void]  }
//      >test.mq5< OnStart(){ @22: MQL5-API Function => () rand                               [int]    = 1809                      (0x00000711) }
//      >test.mq5< OnStart(){ @22: MQL5-API Function => () log                                [dbl]    = 7.5005294853952948        (0x401E008ACD29D375) }
//      >test.mq5< OnStart(){ @22: MQL5-API Function => () floor                              [dbl]    = 7.0000000000000000        (0x401C000000000000) }
//      >test.mq5< OnStart(){ @22: MQL5-API Function => () rand                               [int]    = 27666                     (0x00006C12) }
//      >test.mq5< OnStart(){ @22: MQL5-API Function => () log                                [dbl]    = 10.2279595014347606       (0x402474B71B96F314) }
//      >test.mq5< OnStart(){ @22: MQL5-API Function => () floor                              [dbl]    = 10.0000000000000000       (0x4024000000000000) }


Edit:

I found errors in the display of double -> string.

Better to use string(dblValue) function instead of FormatString("%f", dblValue) because the string() function bug was fixed in build 3194  https://www.mql5.com/en/forum/367839/page3#comment_27477157

Here are the fixes:

// replacement at line #3370
            const string    LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const float       val)                { return(StringFormat("%s",             string(val))); }
            const string    LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const double      val)                { return(StringFormat("%s",             string(val))); }

// replacement at line #3395
            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, LIB_DBG_NAMESPACE(dbg_lib, dbg_remove_leading_namespace)(name), string(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, LIB_DBG_NAMESPACE(dbg_lib, dbg_remove_leading_namespace)(name), string(val), LIB_DBG_NAMESPACE_DEF(dbg_lib, dbl_raw)(val))); }

// replacement at line #4118
                { LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%s%s%s%s = %s ", DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, DBG_OUTPUT_PREFIX, _var_name_, string(_value_));


Now, tracing this script displays accurate decimal strings, as the non-traced version.

#define LIB_DEBUG
#define LIB_DEBUG_MQLAPI
#include "lib_debug.mqh"
void OnStart()
  {
   Print(0.3);
   Print(0.1 + 0.2);
  }

// 0.3
//      >test - Copy.mq5< OnStart(){ @6: MQL5-API Function => Print() [void]  }
// 0.30000000000000004
//      >test - Copy.mq5< OnStart(){ @7: MQL5-API Function => Print() [void]  }
 
amrali #:

You are making great progress, definitely! Now, it is a stable Beta that needs some refinements. I am always looking for some api-tracer for mql (even if not working 100%). 

I added these overloads starting at line #1213 in header "lib_debug.mqh" to overcome compiler errors:

Now running this demo script (that considers many test cases) through your api-tracer works as expected. Great! 

Un-resolved bug: for explicit cast, additional parenthesis must be added around the expression to be casted.


Edit:

I found errors in the display of double -> string.

Better to use string(dblValue) function instead of FormatString("%f", dblValue) because the string() function bug was fixed in build 3194  https://www.mql5.com/en/forum/367839/page3#comment_27477157

Here are the fixes:


Now, tracing this script displays accurate decimal strings, as the non-traced version.

Wow... That's great input.

As I was thinking about the cast operation and how to make valid code for it, I came up with a model that might even work in all cases.

It will use up another keyboard, but I am confident this approach will work in all cases.

The idea is to actively replace every API call with a custom function-scheme...

The idea is a variance of what I did with the functions Alert, Print, Comment...

In the end, there will be 2 consecutive function calls from the object "pass_through".

Something like this:

obj.msg().mql_api_func(... users parameters ...)

Thank you for the hint with the doubles, I will integrate that.

 

I think eventually the api-tracer need to over-ride all mql API functions with custom stubs, something similar to post #49, but I like more your idea of "method chaining" of the object "pass_through" for intercepting calls to mql "void" functions and redirecting them to your custom function stubs.

Now, the api-tracer macros will expand to one expression (as opposed to multiple statements). It will be tedious (but doable) to implement the same idea for other non-void functions. But, with the benefit that it will work with all operators in complex expressions.

 
amrali #:

I think eventually the api-tracer need to over-ride all mql API functions with custom stubs, something similar to post #49, but I like more your idea of "method chaining" of the object "pass_through" for intercepting calls to mql "void" functions and redirecting them to your custom function stubs.

Now, the api-tracer macros will expand to one expression (as opposed to multiple statements). It will be tedious (but doable) to implement the same idea for other non-void functions. But, with the benefit that it will work with all operators in complex expressions.

Yes, exactly.

I'll try a function router, so I might be able to reduce the amount of code a bit. - Excessive use of templating and let the compiler do the actual expansions.

 
lib_debug_mqlapi_tracer_overwrite_macros.mqh              

Missing #endif at the end

 
LibDebug_Performance.mq5 
Compilation fails: '_perf_calls_108' - undeclared identifier LibDebug_Performance.mq5 108 5

 
hini #:
LibDebug_Performance.mq5 
Compilation fails: '_perf_calls_108' - undeclared identifier LibDebug_Performance.mq5 108 5

Hi, yes, I am very sorry for the broken version currently online, I have a new version already ready, currently testing...

I will upload it within the next few days. I still need to write the documentation.

But thank you for your interest.

Edit:

It has a bunch of new features, and it is much easier to use now.
 
hini #:
LibDebug_Performance.mq5 
Compilation fails: '_perf_calls_108' - undeclared identifier LibDebug_Performance.mq5 108 5

Lots of changes by MQ to the preprocessor made some macros break the code. This is one of the effects, but I have fixed that, will be in the next update.