デバッキング2

MQL5プログラムのデバッギング 7

トレーシング

 この章ではプログラムの中で、、
myfunc()関数が完全かどうかを追跡するための、
トレーシングという方法を説明しています。
原文の説明が分りにくいので、
先にプログラム全体を説明すると、
下記のようになります。

int OnInit()
{
//ここにTracingを記述
return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
//トレーシングファイルを作成
}

void myfunc()
{
//ここにTracingを記述
}

void OnTick()
{
//ここにTracingを記述
myfunc();
//ここにTracingを記述
}

-----------------------
原文の続き

 デバッギングでは、全ての関数を完全にすることは非常に重要です。
この方法は複雑なのでめったに使われません。
しかし、ポピュラーな他の方法はありません。

スタックのシーケンス構造で、何をしようとしているか、理解できないとき、
トレーシングは助けになります。
この方法はアプリケーションの構造、
シーケンスと呼ばれるオブジェクトを理解する手助けになります。
トレーシングを使い、プログラムの悪い箇所を理解します。
この方法はプロジェクトの外観を提供してくれます。

トレーシングは次のように行います。
先にマクロを作ります。

//オープン
#define zx Print(__FUNSIG__ + "{ ");

//クローズ
#define xz Print(" } ;");

これはオープニングのzxとクロージングのxzのマクロです。
これをトレースする関数の中に置きます。

void myfunc(int a,int b)
{

ZX

if(a != b){xz return ;}

xz

return;
}

ifコンデションを使うときは、
return の前にそれぞれクロージングのxzをセットする必要があります。
それはトレーシング構造が中断するのを防ぎます。

上記の例のマクロに注意してください。

トレーシングはファイルする方がベターですので、
自分のトリックを使います。

全体のトレーシング構造を見るため、
下記のシンタックス構成で関数名をラップします。

if(){...}

ファイルの結果はメタエデイターで、
FILEフォルダーの
.mqh拡張子のファイルをオープンします。
ファイルをクリックしオープンします。

 さらにコードあるいは上記ファイルの、
トレーシングストラクチャを見るため、
styler(Ctrl + ,)を使います。
(*:stylerの解説はこのメールの最後に記述しています。)

以下はトレーシングの全コードです。

string com=""; // declare global variable for storing debugging data
//--- opening substitution
#define zx com+="if("+__FUNCSIG__+"){\n";
//--- closing substitution
#define xz com+="};\n";


int OnInit()
{
//---

//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Program shutdown |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- //--- saving data to the file when closing the program
WriteFile();
}
//+------------------------------------------------------------------+
//| Example of the function tracing |
//+------------------------------------------------------------------+
void myfunc(int a,int b)
{
zx
//--- here is some code of the function itself
if(a!=b) { xz return; } // exit in the middle of the function
//--- here is some code of the function itself
xz return;
}
//+------------------------------------------------------------------+
//| Save data to file |
//+------------------------------------------------------------------+
void WriteFile(string name="Tracing")
{
//--- open the file
ResetLastError();
int han=FileOpen(name+".mqh",FILE_WRITE|FILE_TXT|FILE_ANSI," ");
//--- check if the file has opened
if(han!=INVALID_HANDLE)
{
FileWrite(han,com); // print data
FileClose(han); // close the file
}
else
Print("File open failed "+name+".mqh, error",GetLastError());
}

-----------------------------
stylerの解説

.mqlのコードで下記のように
stylerをおこなう範囲をカーソルで選択します。
メニューのツールから、スタイラーを選択しクリック、
または(Ctrl + ,)キーで操作します。

//操作前

void myFunction()
{
if (I < 10)
{
printf (“Hello\n”) ;
if (I < 5 )
{
printf (“i<5 br="" n=""> if (i < 3)
{
printf (“i<3 br="" n=""> if (i < 2)
{
}
}
}
}
}
--------------------------------
//操作後

void myFunction()
{
if(I<10 br=""> {
printf(“Hello\n”);
if(I<5 br=""> {
printf(“i<5 br="" n=""> if(i<3 br=""> {
printf(“i<3 br="" n=""> if(i<2 br=""> {
}
}
}
}
}


------------------------------
MQL5プログラムのデバッギング 8

前回の続き

 特別な場所でトレーシングするには、
if コンデションを加える必要があります。

bool trace = false ;

#define zx if(trace) com += "if("+__FUNCSIG__+"){\n";


#define xz if(trace) com += "}";\n";

 確実に設定した後、
"trace"変数に"true" あるいは"false"をセットすることで、
トレースの可/非が可能になります。
もし後で必要になるか、ソースを削除する十分な時間がない場合、
マクロ変数を"false"にし、
トレーシングを中止することができます。

 トレーシングを可能にすると、エキスパートアドバイザーに下記のようなファイルが添付されます。
トレーシングの結果はFILEデイレクトリで見ることができます。
(tracing.mql)

---------------------------------
if(int OnInit()){
};
if(void OnTick()){
if(void CheckForOpen()){
};
};
if(void OnTick()){
if(void CheckForOpen()){
};
};
...
---------------------------------

ファイルの生成のときクリアーにすることは出来ませんが、
コードstylerを使うと、全構造を見ることが出来るようになります。

---------------------------------
//+------------------------------------------------------------------+
//| ProjectName |
//| Copyright 2012, CompanyName |
//| http://www.companyname.net |
//+------------------------------------------------------------------+
if(int OnInit())
{
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
if(void OnTick())
{
if(void myfunc(int,int))
{
};
};

これは私の単なるトリック(工夫、手品)です。
トレーシングがどのようになされるかの例ではありません。
トレーシングは自由です。
大事なことはトレーシングが関数コールの構造を明らかにすると言うことです。