Blank Results while backtesting - algorithmic-trading

I am new to the world of MQL4-code.
I come from a C++ background and I am trying to learn MQL4 language & conventions.
I am writing a simple Expert Advisor (my first ever).It compiles but, when I am trying to test it, it ends with no results. I attach code to better illustrate what I am trying to do:
//+------------------------------------------------------------------+
//| MyFirstExpert.mq4 |
//| Leonardo |
//| http://investinmarkets.altervista.org |
//+------------------------------------------------------------------+
#property copyright "Leonardo "
#property link "http://investinmarkets.altervista.org"
#property version "1.00"
#property strict
input int BarCount = 3;
int Ticket = 0;
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {
int BarCountTemp = BarCount + 1;
double bars[];
ArrayResize( bars, BarCountTemp );
for ( int i = 0; i < BarCountTemp; i++ ) {
bars[i] = Close[i + 1];
}
int i = 0;
bool is_p;
do
{
if ( bars[i] > bars[i+1] && i < BarCountTemp ) is_p = true;
else is_p = false;
i++;
}
while ( is_p );
if ( is_p == true && Ticket == 0 ) {
Ticket = OrderSend(_Symbol,OP_SELL,0.1,Bid,0,0,0,"Sell Order Custom",110);
Alert("Sell order opened to match found.");
Comment("Sell order opened #"+Ticket+".");
}
if ( Ticket != 0 ) {
bool select = OrderSelect(Ticket,SELECT_BY_TICKET);
if ( Close[1] > Close[2] ) {
bool close = OrderClose(Ticket,OrderLots(),Ask,0,clrGreen);
Alert("Sell order closed.");
Comment("Sell order closed #"+Ticket+".");
Ticket = 0;
}
}
}
//+------------------------------------------------------------------+
I want to simply count bars (input by user) and then perform a check: if e.g. 3 bars are all positive then open a sell order (just this case for the moment). If opened, the next bar check if still positive, if not close the trade.
I am getting always blank results.
Thank you in advance!

Welcome to the MQL4-world, Leonardo
let's review the syntax:
for ( int i = 0; i < BarCountTemp; i++ ) {
bars[i] = Close[i + 1];
}
int i = 0;
bool is_p;
do
{
if ( bars[i] > bars[i+1] && i < BarCountTemp ) is_p = true;
else is_p = false;
i++;
}
while ( is_p );
could be merged / simplified into a single loop/break construct:
bool is_p = True; // FYI: FALSE if not initialised
// WARNING: "New"-MQL4 has changed variable visibility-scope to be limited just to the innermost syntax-construct and variables easily "cease" exist outside that syntax-construct boundary ... for(){bool is_p ...visible...} ...invisible...
for ( int i = 0; // .SET
i < BarCountTemp; // .TEST: [**]
i++ ) { // .INC
if ( Close[i+1] > Close[i+2] // avoid TimeSeries' replica(s)
// && i < BarCountTemp // ALWAYS TRUE [^**]
) continue; // ---------------------------- LOOP-^
else {
is_p = False;
break; // ---------------------------- EXIT-v
}
Next: got at least one Comment() remark on top of the chart window?
int Ticket = EMPTY; // Rather initialise as = EMPTY;
if ( is_p == True
&& Ticket == EMPTY // un-ambiguous meaning
) {
Ticket = OrderSend( _Symbol, // .SYM
OP_SELL, // .OP
0.1, // .LOTs check sizing, MarketInfo()
Bid, // .PRICE
0, // .SLIPPAGE
0, // .SL
0, // .TP
"Sell Order Custom",// .COMMENT
110 // .MAGNUM
);
if ( Ticket == EMPTY ){ // EXC. HANDLER
...
}
else {
Alert( "Sell order opened to match found." ); // .NOP if isTesting()
Comment( "Sell order opened #" + Ticket + "." ); // .GUI is visible????
}
}
Finally: include Exception handlers for cases, where error may appear
if ( Ticket != EMPTY // TEST 1st,
&& Close[1] > Close[2] // TEST 2nd, prevent dbPool-ops, if not True
) {
bool select = OrderSelect( Ticket, SELECT_BY_TICKET );
if (!select ){ // EXC. HANDLER
...
}
bool close = OrderClose( Ticket,
OrderLots(),
Ask,
0,
clrGreen
);
if (!close ){ // EXC. HANDLER
...
}
Alert( "Sell order closed." );
Comment( "Sell order closed #" + Ticket + "." );
Ticket = EMPTY; // .SET EMPTY
}
}

Related

How to prove a C program to LTL formulas with Frama-C Aoraï corresponding to my Promela program?

I have a test Promela program (a model of UI) that can be verified with Spin:
int secrets = 0;
int success = 0;
int fails = 0;
int total = 0;
//variables to control
bool windowLogin = false;
bool windowSecret = false;
bool windowNoSecret = false;
//ltl formulas
ltl secret_to_success_password { [] (secrets<=success)}
ltl check_total { [] (total == success + fails || total + 1 == success + fails)}
ltl we_open_nosecret { <> (windowNoSecret) }
ltl we_open_secret { <> (windowSecret) }
ltl we_open_any { [] <> (windowSecret || windowNoSecret)}
ltl login_check { <> windowLogin -> <> windowSecret}
ltl no_secret_nosecret { [] !(windowSecret && windowNoSecret) }
//channels
chan login=[0] of {short};
chan nonsecret = [0] of {short};
chan secret = [0] of {short};
//main
active proctype MainWindow(){
int buf;
printf("Main started");
do
//infinite loop
:: {
printf("Main: go to Login window");
login! 1;
login? buf;
if
:: buf == 1 -> {//ok
success++;
printf("Main: open secret window");
//"open" secret
secret ! 1;
secret ? buf;//и ждем его
}
:: buf == 0 -> {//fail
fails++;
printf("Main: open nosecret window");
//"open" nonsecret
nonsecret ! 1;
nonsecret ? buf
}
fi
}
od
}
active proctype LoginWindow(){
int buf;
printf("Login started");
do
:: {
login? buf;
windowLogin = true;
if
::true-> { printf("Login fail"); windowLogin = false; login ! 0 }
::true-> { printf("Login fail"); windowLogin = false; login ! 0 }
::true-> { printf("Login ok!"); windowLogin = false; login ! 1 }//p= 1/3
fi
}
od
}
active proctype NonSecretWindow(){
int buf;
printf("Non Secret started");
do
:: {
nonsecret ? buf;
printf("Non Secret window opened");
windowNoSecret = true;
total++;
windowNoSecret = false;
nonsecret ! 1;
printf("Non Secret window closed");
}
od
}
active proctype SecretWindow(){
int buf;
printf(" Secret started");
do
:: {
secret ? buf;
printf("Secret window opened");
windowSecret = true;
secrets++;
total++;
windowSecret = false;
secret ! 1;
printf("Secret window closed");
}
od
}
Then I created a corresponding C program (for first step, without a loop in Main Window):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
bool windowLogin = false;
bool windowNoSecret = false;
bool windowSecret = false;
int total = 0;
int secrets = 0;
int success = 0;
int fails = 0;
int LoginWindow();
int NonSecretWindow();
int SecretWindow();
int MainWindow() {
//printf("Main started\n");
{
//printf("Main: go to Login window\n");
int r = LoginWindow();
if (r == 1) {
//printf("Main: open secret window\n");
success++;
SecretWindow();
} else {
//printf("Main: open nosecret window\n");
fails++;
NonSecretWindow();
}
}
return 0;
}
int LoginWindow() {
//printf("Login started\n");
windowLogin = true;
if (rand() %3 ==0) {
// windowLogin = false;
return 1;
} else {
// windowLogin = false;
return 0;
}
return 0;
}
int NonSecretWindow() {
//printf("Non Secret started\n");
//printf("Non Secret window opened\n");
windowNoSecret = true;
total++;
//windowNoSecret = false; --- aorai will controll the variable change only in the end of function
//printf("Non Secret window closed\n");
return 0;
}
int SecretWindow() {
//printf("Secret window opened\n");
windowSecret = true;
secrets++;
total++;
//windowSecret = false;
//printf("Secret window closed\n");
return 0;
}
int main() {
MainWindow();
return 0;
}
I want to try using Aoraï LTL (don't want to create .ya by hand) in Frama-C and WP plugins.
First, I created a .ltl file
CALL(main) && _X_ (CALL (MainWindow) && _X_ (CALL (LoginWindow) && _X_ (RETURN (LoginWindow) &&
((_X_ (CALL(NonSecretWindow)))||(_X_ (CALL(SecretWindow)))))))
and can get 2 unknown goals:
[wp] [Alt-Ergo] Goal typed_MainWindow_call_NonSecretWindow_pre : Unknown (Qed:3ms) (81ms)
[wp] [Alt-Ergo] Goal typed_MainWindow_call_SecretWindow_pre : Unknown (Qed:4ms) (79ms)
Also I tried
CALL(main) && _X_ (CALL (MainWindow) && _X_ (CALL (LoginWindow) && _X_ (RETURN (LoginWindow) &&
((_X_ (CALL(NonSecretWindow)||CALL(SecretWindow)))))))
with the same result.
This one
CALL(main) && _X_ (CALL (MainWindow) && _X_ (CALL (LoginWindow) && _X_ (RETURN (LoginWindow) && (
(_F_ (CALL(NonSecretWindow)||CALL(SecretWindow)))))))
can be proved, but I belive that that one should be not correct:
CALL(main) && _X_ (CALL (MainWindow) && _X_ (CALL (LoginWindow) && _X_ (RETURN (LoginWindow) &&
((_F_ (CALL(NonSecretWindow)))))))
but it is correct (all goals were proved).
Also, I tried to test my LTL formulas like in Promela (without CALL/RETURN/X):
_G_ (windowLogin => _F_ (windowSecret || windowNoSecret))
and I got a lot of unproved goals or even for testing
_G_ (total == success + fails || total + 1 == success + fails)
an internal error
[aorai] Welcome to the Aorai plugin
[aorai] failure: Term cannot be transformed into exp.
[kernel] Current source was: test_ltl.c:112
The full backtrace is:
Raised at file "src/libraries/project/project.ml", line 402, characters 50-57
Called from file "src/plugins/aorai/aorai_register.ml", line 385, characters 4-31
...
I use the commandline
rm test_ltl_annot.c
frama-c test_ltl.c -aorai-ltl test_ltl.ltl
frama-c -wp test_ltl_annot.c
and Frama-C version is Phosphorus-20170501.
How should I use this plugin to verify my test program with respect to LTL?

boolean function for loop mql4

I would like to write a reiterated if condition
if (BOX_H1(1) && BOX_H1(2) && BOX_H1(3) && BOX_H1(4) && BOX_H1(5) && BOX_H1(6) && BOX_H1(7) && BOX_H1(8);)
In a for loop form, something like this:
if (
for (int x=1;x<=7; x++)
{
(BOX_H1(x));
})
where BOX_H1(1) si a boolean functions that takes int (shift parameter), but this code doesen't works.
Anyone knows how can i write it out?
EDIT:
My code is in this form:
bool Buy_H1 =0, ...
...
if(Buy_H1) {if(...)}
...
void Entry()
{
Buy_H1 =BOX_H1(1) && BOX_H1(2) && BOX_H1(3) && BOX_H1(4) &&
BOX_H1(5) && BOX_H1(6) && BOX_H1(7) && BOX_H1(8) ;
}
If, instead of the last code, I substitute
void Entry()
{
bool Buy_H1(const int parameter){
for(int i=1; i<=parameter; i++){
if(!BOX_H1(i))
return false; }
return true; }
}
I reach 'Buy_H1' - function can be declared only in the global scope
bool booleanFunction( const int parameter ){
for( int i = 1; i <= parameter; i++ ){
if ( !BOX_H1( i ) )
return false;
}
return true;
}
void OnStart(){
...
if ( booleanFunction( 8 ) ){
Print( "OK" );
} //edited, your code instead of this
...
}

ffmpeg avcodec_encode_video2 hangs when using Quick Sync h264_qsv encoder

When I use the mpeg4 or h264 encoders, I am able to successfully encode images to make a valid AVI file using the API for ffmpeg 3.1.0. However, when I use the Quick Sync encoder (h264_qsv), avcodec_encode_video2 will hang some of the time. I found that when using images that are 1920x1080, it was rare that avcodec_encode_video2 would hang. When using 256x256 images, it was very likely that the function would hang.
I have created the test code below that demonstrates the hang of avcodec_encode_video2. The code will create a 1000 frame, 256x256 AVI with a bit rate of 400000. The frames are simply allocated, so the output video should just be green frames.
The problem was observed using Windows 7 and Windows 10, using the 32-bit or 64-bit test application.
If anyone has any idea on how I can avoid the avcodec_encode_video2 hang I would be very grateful! Thanks in advance for any assistance.
extern "C"
{
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include "avcodec.h"
#include "avformat.h"
#include "swscale.h"
#include "avutil.h"
#include "imgutils.h"
#include "opt.h"
#include <rational.h>
}
#include <iostream>
// Globals
AVCodec* m_pCodec = NULL;
AVStream *m_pStream = NULL;
AVOutputFormat* m_pFormat = NULL;
AVFormatContext* m_pFormatContext = NULL;
AVCodecContext* m_pCodecContext = NULL;
AVFrame* m_pFrame = NULL;
int m_frameIndex;
// Output format
AVPixelFormat m_pixType = AV_PIX_FMT_NV12;
// Use for mpeg4
//AVPixelFormat m_pixType = AV_PIX_FMT_YUV420P;
// Output frame rate
int m_frameRate = 30;
// Output image dimensions
int m_imageWidth = 256;
int m_imageHeight = 256;
// Number of frames to export
int m_frameCount = 1000;
// Output file name
const char* m_fileName = "c:/test/test.avi";
// Output file type
const char* m_fileType = "AVI";
// Codec name used to encode
const char* m_encoderName = "h264_qsv";
// use for mpeg4
//const char* m_encoderName = "mpeg4";
// Target bit rate
int m_targetBitRate = 400000;
void addVideoStream()
{
m_pStream = avformat_new_stream( m_pFormatContext, m_pCodec );
m_pStream->id = m_pFormatContext->nb_streams - 1;
m_pStream->time_base = m_pCodecContext->time_base;
m_pStream->codec->pix_fmt = m_pixType;
m_pStream->codec->flags = m_pCodecContext->flags;
m_pStream->codec->width = m_pCodecContext->width;
m_pStream->codec->height = m_pCodecContext->height;
m_pStream->codec->time_base = m_pCodecContext->time_base;
m_pStream->codec->bit_rate = m_pCodecContext->bit_rate;
}
AVFrame* allocatePicture( enum AVPixelFormat pix_fmt, int width, int height )
{
AVFrame *frame;
frame = av_frame_alloc();
if ( !frame )
{
return NULL;
}
frame->format = pix_fmt;
frame->width = width;
frame->height = height;
int checkImage = av_image_alloc( frame->data, frame->linesize, width, height, pix_fmt, 32 );
if ( checkImage < 0 )
{
return NULL;
}
return frame;
}
bool initialize()
{
AVRational frameRate;
frameRate.den = m_frameRate;
frameRate.num = 1;
av_register_all();
m_pCodec = avcodec_find_encoder_by_name(m_encoderName);
if( !m_pCodec )
{
return false;
}
m_pCodecContext = avcodec_alloc_context3( m_pCodec );
m_pCodecContext->width = m_imageWidth;
m_pCodecContext->height = m_imageHeight;
m_pCodecContext->time_base = frameRate;
m_pCodecContext->gop_size = 0;
m_pCodecContext->pix_fmt = m_pixType;
m_pCodecContext->codec_id = m_pCodec->id;
m_pCodecContext->bit_rate = m_targetBitRate;
av_opt_set( m_pCodecContext->priv_data, "+CBR", "", 0 );
return true;
}
bool startExport()
{
m_frameIndex = 0;
char fakeFileName[512];
int checkAllocContext = avformat_alloc_output_context2( &m_pFormatContext, NULL, m_fileType, fakeFileName );
if ( checkAllocContext < 0 )
{
return false;
}
if ( !m_pFormatContext )
{
return false;
}
m_pFormat = m_pFormatContext->oformat;
if ( m_pFormat->video_codec != AV_CODEC_ID_NONE )
{
addVideoStream();
int checkOpen = avcodec_open2( m_pCodecContext, m_pCodec, NULL );
if ( checkOpen < 0 )
{
return false;
}
m_pFrame = allocatePicture( m_pCodecContext->pix_fmt, m_pCodecContext->width, m_pCodecContext->height );
if( !m_pFrame )
{
return false;
}
m_pFrame->pts = 0;
}
int checkOpen = avio_open( &m_pFormatContext->pb, m_fileName, AVIO_FLAG_WRITE );
if ( checkOpen < 0 )
{
return false;
}
av_dict_set( &(m_pFormatContext->metadata), "title", "QS Test", 0 );
int checkHeader = avformat_write_header( m_pFormatContext, NULL );
if ( checkHeader < 0 )
{
return false;
}
return true;
}
int processFrame( AVPacket& avPacket )
{
avPacket.stream_index = 0;
avPacket.pts = av_rescale_q( m_pFrame->pts, m_pStream->codec->time_base, m_pStream->time_base );
avPacket.dts = av_rescale_q( m_pFrame->pts, m_pStream->codec->time_base, m_pStream->time_base );
m_pFrame->pts++;
int retVal = av_interleaved_write_frame( m_pFormatContext, &avPacket );
return retVal;
}
bool exportFrame()
{
int success = 1;
int result = 0;
AVPacket avPacket;
av_init_packet( &avPacket );
avPacket.data = NULL;
avPacket.size = 0;
fflush(stdout);
std::cout << "Before avcodec_encode_video2 for frame: " << m_frameIndex << std::endl;
success = avcodec_encode_video2( m_pCodecContext, &avPacket, m_pFrame, &result );
std::cout << "After avcodec_encode_video2 for frame: " << m_frameIndex << std::endl;
if( result )
{
success = processFrame( avPacket );
}
av_packet_unref( &avPacket );
m_frameIndex++;
return ( success == 0 );
}
void endExport()
{
int result = 0;
int success = 0;
if (m_pFrame)
{
while ( success == 0 )
{
AVPacket avPacket;
av_init_packet( &avPacket );
avPacket.data = NULL;
avPacket.size = 0;
fflush(stdout);
success = avcodec_encode_video2( m_pCodecContext, &avPacket, NULL, &result );
if( result )
{
success = processFrame( avPacket );
}
av_packet_unref( &avPacket );
if (!result)
{
break;
}
}
}
if (m_pFormatContext)
{
av_write_trailer( m_pFormatContext );
if( m_pFrame )
{
av_frame_free( &m_pFrame );
}
avio_closep( &m_pFormatContext->pb );
avformat_free_context( m_pFormatContext );
m_pFormatContext = NULL;
}
}
void cleanup()
{
if( m_pFrame || m_pCodecContext )
{
if( m_pFrame )
{
av_frame_free( &m_pFrame );
}
if( m_pCodecContext )
{
avcodec_close( m_pCodecContext );
av_free( m_pCodecContext );
}
}
}
int main()
{
bool success = true;
if (initialize())
{
if (startExport())
{
for (int loop = 0; loop < m_frameCount; loop++)
{
if (!exportFrame())
{
std::cout << "Failed to export frame\n";
success = false;
break;
}
}
endExport();
}
else
{
std::cout << "Failed to start export\n";
success = false;
}
cleanup();
}
else
{
std::cout << "Failed to initialize export\n";
success = false;
}
if (success)
{
std::cout << "Successfully exported file\n";
}
return 1;
}
The problem no longer occurs now that I have updated to the latest Intel® Graphics Driver (version 15.45.10.4542)

How to return nullptr from a lambda function?

I have a small lambda function which shall find and return a QTreeWidgetItem. But if it does not find the given item, then it shall return a nullptr. But if I try to compile it then it gives me an error.
The function:
auto takeTopLevelItem = []( QTreeWidget* aTreeWidget, const QString& aText )
{
const int count = aTreeWidget->topLevelItemCount();
for ( int index = 0; index < count; ++index )
{
auto item = aTreeWidget->topLevelItem( index );
if ( item->text( 0 ) == aText )
{
return aTreeWidget->takeTopLevelItem( index );
}
}
return nullptr; // This causes a compilation error.
};
The error:
Error 1 error C3487: 'nullptr': all return expressions in a lambda must have the same type: previously it was 'QTreeWidgetItem *' cpp 251
I changed the mentioned line with this and now it compiles:
return (QTreeWidgetItem*)( nullptr );
but I would like to avoid this syntax. How can I solve this ?
I use Visual Studio 2012.
You can add an explicit return type annotation:
auto takeTopLevelItem = []( ... ) -> QTreeWidgetItem*
{
// ...
}
That way nullptr will be converted to your pointer type properly. You're getting that error because the lambda assumes no conversions should be made, and treats nullptr_t as a legitimate alternative return type.
As a side note, consider using (std::)optional instead. The nullability of pointers can be used to represent a missing return, but it doesn't mean it necessarily should be.
If you just want to avoid the syntax, rather than the casting, you could it like this:
static_cast<QTreeWidgetItem*>(nullptr);
I made a small example, on how Bartek's and mine's answer really work:
#include <iostream>
class A {
int a;
};
auto bla = [] (A* obj, bool flag) -> A* {
if(flag)
return obj;
return nullptr;
// return static_cast<A*>(nullptr);
};
int main() {
A obj;
A* ptr = &obj;
bool flag = false;
if( bla(ptr, flag) == nullptr)
std::cout << "ok\n";
return 0;
}
I had this very same issue with some Smart Pointers, so I found I could do this to avoid the issue:
auto myFunc= [](MyClass* class)
{
MyPointer* pointer = nullptr;
if( class && class->isValid() )
{
pointer = class->getPointerInstance()
}
return pointer;
}
Similarly, for shared pointer, just repleace MyPointer* by std::shared_ptr<MyPointer>.
So your code would looks like:
auto takeTopLevelItem = []( QTreeWidget* aTreeWidget, const QString& aText )
{
QTreeWidgetItem* item = nullptr;
const int count = aTreeWidget->topLevelItemCount();
for ( int index = 0; index < count; ++index )
{
auto item = aTreeWidget->topLevelItem( index );
if ( item->text( 0 ) == aText )
{
item = aTreeWidget->takeTopLevelItem( index );
break;
}
}
return item;
};

Use Visual Studio exception in C

I use С language in project. Eventually, I began to notice that most of the code is check. In the project the return type of the function bool. Because we are working with the media and if function read or write return false we must break programm,
Some time ago I learned that in Visual Studio has built-in exception (Use Visual Studio 2008)
__try
__finally
In the project, we use the log. All functions use log.
We decided to combine the Log and exception. Use preprocessor
#define try do \
{ \
Int32_T __FUNCTION__##ReturnValue = -1; \
LOG_BEGIN(); \
__try \
{
#define finally } \
__finally \
{
#define end_try } \
if( __FUNCTION__##ReturnValue != -1 ) \
{ \
return LOG_END_WITH(__FUNCTION__##ReturnValue); \
} \
else \
{ \
LOG_END(); \
return; \
} \
}while(0)
#define raise(e) RaiseException( e, EXCEPTION_NONCONTINUABLE, 0, NULL )
#define return_false __FUNCTION__##ReturnValue = 0; \
__leave
#define return_true ##__FUNCTION__##ReturnValue = 1; \
__leave
#define return_void ##__FUNCTION__##ReturnValue = -1; \
__leave
Example of use. Function return the bool value
Bool_T Node_Insert( IN OUT Tree_T * tree, IN Text_T fullPath, ... )
{
Text_T itemName = NULL;
int * delimiterPos = NULL;
try
{
// if tree is empty we should add ROOT_PATH
//
if( Tree_IsEmpty( IN *tree ) )
{
if( failed Tree_CreateRoot( IN OUT *tree, IN datafield ) )
{
LOG_ERROR( "Node_Insert FAILURE --> Tree_CreateRoot failed" );
return_false;
}
}
if( Text_Length( IN fullPath ) > 1 )
{
...
// Allocate memory for Text
//
item = Text_New();
// Allocate for delimeterPos array
//
delimiterPos = NEW(n, sizeof(elem));
...
while( i < nDelimiter )
{
...
...
...
}
}
else if ( Text_Length( IN fullPath ) == 1 )
{
// we have already added ROOT
//
return_true;
}else{
LOG_ERROR( "Node_Insert FAILURE --> Path length is not correct" );
return_false;
}
}
// In the end we need free allocated memory
//
finally
{
Text_Delete( IN OUT &itemName );
free( delimiterPos );
}
// in end_try preprocessor we write log and return true or false
//
end_try;
}
Example of use. Method that don't return value
void Ifo_ReadBufferHeader( IN Uint8_T * buffer, ... IN OUT Int32_T * position )
{
Text_T fullPath = NULL;
try
{
// getting buffer size
//
Uint32_T size = Buffer_GetSize( IN buffer );
// getting mode
//
Uint8_T writeMode = Buffer_GetWritingMode( IN buffer );
if( Ifo_IsAddMode( IN static_cast(DataIfoMode_T, writeMode) ) )
{
Uint32_T pos = 1 + Ifo_GetLabelLength() + 23;
// getting path length
//
fullPath = Text_New( IN "", IN mp );
Buffer_GetNameField( IN buffer, OUT &fullPath, IN OUT &pos );
*parentFolderPath = fullPath;
*position = pos;
} else if( Ifo_IsRenameMode( IN static_cast(DataIfoMode_T, writeMode ) )
{
*position = 1 + Ifo_GetLabelLength() + 23;
}
*bufferSize = size;
*mode = static_cast(DataIfoMode_T, writeMode);
// return_void preprocessor that use
//
return_void;
}
finally
{
// After run the main code you must free allocated memory
//
Text_Delete( IN OUT &fullPath );
}
end_try;
}
My question is. How do I design what would it would return a value? That is, the function will return a value, such as calculate buffer CRC return as a value. How do I do this by using these macros.
int GetCrcBuffer( IN Uint32_T buffer, IN Tree_T tree )
{
Text_T itemName = NULL;
int crc = 0;
try
{
...
...
itemName = Text_New();
if( crc != 12 )
{
return_value(crc); // ???? return value of crc and delete text??? how???
}
...
...
}
finally
{
Text_Delete( IN OUT itemName );
}
end_try;
}
How to make it run finally block and return value crc??
How write the preprocessor return_value() ???
Your finally block will properly delete itemname, so you don't have to worry about that part. The only trick is that your return value cannot be -1 (that is: -1 cannot be a legitimate return value) as that signals error in end_try. Then just like with raise(e), you can specify a parameter to the macro:
#define return_value(v) ##__FUNCTION__##ReturnValue = (v); \
__leave
If you want to write a function that can return nnon-integral types, you can do this trick: have the function actually return an int, signalling success/failure, and in the case of success, pass the actual "return value" (the non-integral type one) back via a pointer parameter:
#define return_value2(v) *ret_val=(v); \
##__FUNCTION__##ReturnValue = 1; \
__leave
int GetMyType( IN Uint32_T buffer, IN Tree_T tree, MyType* ret_val )
{
...
}
Note: the value ret_val points to is valid only if the function did not return -1

Resources