uncrustify: can I control where it decides to break apart lines? - uncrustify

I've been trying out uncrustify and while I've gotten a lot of mileage out of how configurable it is, I found it occasionally decides to break apart lines in ways I don't agree with.
Some examples:
void functionWithLongName(int parameter1, int parameter2, int parameter3, int parameter4) {
}
..becomes:
void functionWithLongName(int parameter1, int parameter2, int parameter3, int
parameter4) {
}
I'd rather have it be:
void functionWithLongName(int parameter1, int parameter2, int parameter3,
int parameter4) {
}
...as I'd prefer for it not to break apart the type and variable name, as well as any qualifiers.
Another example:
ClassName::ClassName(int importantValue) : memberVariable1(0), memberVariable2(importantValue), memberVariable3(0) {}
...becomes:
ClassName::ClassName(int importantValue) : memberVariable1(0), memberVariable2(
importantValue), memberVariable3(0) {}
But I don't want it to break between the parentheses of one of these initializers. I'd much prefer something like:
ClassName::ClassName(int importantValue) : memberVariable1(0),
memberVariable2(importantValue), memberVariable3(0) {}
Going through crustify's docs I haven't found settings that lets me specify this. Is there a way to do this?
In case it helps, here is my current uncrustify config file.

It looks like the problem was having ls_code_width set to true. Once I set it to false, uncrustify now seems to try to maintain groupings.

Related

uncrustify: function definition argument indenting on separate line

I have this:
char *
foo(a,b)
int a;
int b;
{
...
}
I want this:
char *
foo(a,b)
int a;// indented
int b;// indented
{
...
}
The indenting works for function body code but I cannot find an option to make this style of argument (old style code being resurrected) indented.
Which directive can do this? I have tried all that seem remotely appropriate.

How to use DLLs to exchange values between MQL4 programs?

First of all I need to say I don't know much about DLLs.
I am trying to send data from one program to another, using functions from kernel32.dll. My programs are coded in MQL4.
This is the code I use for the server part, which is supposed to save the data:
#define INVALID_HANDLE_VALUE -1
#define BUF_SIZE 256
#define PAGE_READWRITE 0x0004
#define FILE_MAP_ALL_ACCESS 0xf001F
#import "kernel32.dll"
int CreateFileMappingA(int hFile, int lpAttributes, int flProtect, int dwMaximumSizeHigh, int dwMaximumSizeLow, string lpName);
int MapViewOfFile(int hFileMappingObject, int dwDesiredAccess, int dwFileOffsetHigh, int dwFileOffsetLow, int dwNumberOfBytesToMap);
int UnmapViewOfFile(int lpBaseAddress);
int RtlMoveMemory(int DestPtr, string s, int Length);
int CloseHandle(int hwnd);
int CreateMutexA(int attr, int owner, string mutexName);
int ReleaseMutex(int hnd);
int WaitForSingleObject(int hnd, int dwMilliseconds);
bool started = False;
int hMapFile = 0;
int pBuf=0;
int hMutex;
int OnInit()
{
if(!started) {
started = true;
string szName="Global\\Value1";
int hMapFile = CreateFileMappingA(INVALID_HANDLE_VALUE,0,PAGE_READWRITE,0,BUF_SIZE,szName);
if(hMapFile==0) {
Alert("CreateFileMapping failed!");
return;
}
pBuf = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE);
if(pBuf==0) {
Alert("Map View failed!");
return;
}
hMutex = CreateMutexA(0,0,"PriceMapMutex");
}
}
void OnTick()
{
WaitForSingleObject(hMutex,1000);
if(pBuf==0) return;
string szMsg = DoubleToStr(Bid,Digits);
Comment("Data: ",szMsg);
RtlMoveMemory(pBuf, szMsg, StringLen(szMsg)+1);
ReleaseMutex(hMutex);
return(0);
}
int deinit()
{
switch(UninitializeReason()) {
case REASON_CHARTCLOSE:
case REASON_REMOVE:
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
break;
}
return(0);
}
This is what I use for my client part, which is supposed to pick up the data:
#define INVALID_HANDLE_VALUE -1
#define BUF_SIZE 1024
#define FILE_MAP_READ 4
extern int BufferSize = 1024;
#import "kernel32.dll"
int OpenFileMappingA(int dwDesiredAccess, bool bInheritHandle, string lpName);
string MapViewOfFile(int hFileMappingObject, int dwDesiredAccess, int dwFileOffsetHigh, int dwFileOffsetLow, int dwNumberOfBytesToMap);
int UnmapViewOfFile(string lpBaseAddress);
int CloseHandle(int hwnd);
int CreateMutexA(int attr, int owner, string mutexName);
int ReleaseMutex(int hnd);
int WaitForSingleObject(int hnd, int dwMilliseconds);
string szName;
int hMapFile;
string obj;
string data;
int hMutex;
double dd;
int OnInit()
{
szName="Global\\Value1";
hMapFile = OpenFileMappingA(FILE_MAP_READ,False,szName);
if(hMapFile==0) {
Alert("CreateFile Failed!");
return;
}
obj="data";
ObjectCreate(obj,OBJ_HLINE,0,0,0);
ObjectSet(obj,OBJPROP_COLOR,Gold);
hMutex = CreateMutexA(0,0,"PriceMapMutex");
}
void OnDeinit(const int reason)
{
CloseHandle(hMapFile);
Comment("");
ObjectDelete(obj);
return(0);
}
void start()
{
getsignal();
Comment("Data: ",DoubleToStr(dd,Digits));
Sleep(50);
}
void getsignal() {
WaitForSingleObject(hMutex,333);
data = MapViewOfFile(hMapFile,FILE_MAP_READ,0,0,BUF_SIZE);
dd = StrToDouble(data);
ReleaseMutex(hMutex);
UnmapViewOfFile(data);
ObjectMove(obj,0,Time[0],dd);
}
The code basically works. However I am facing 2 major problems with it.
Problem number 1:
I want to exchange multiple values ( value1, value2, value3, ... ). For some reason it seems to be irrelevant which name I use for szName="Global\\Value1". The server saves the value and the client picks it up no matter what names I use szName="Global\\Value1", szName="Global\\Value2" or szName="Global\\Value3". So for example in the server code I use szName="Global\\Value1" and in my client code I use szName="Global\\Value3" the client still picks up the value which the server writes to szName="Global\\Value1".
Problem number 2:
my client is only stable for about 5 hours. After that I get a message in the client programme saying
"There is a problem and the program needs to be closed...".
Then I close and restart my client and its again working for the next 5 hours.
Has anyone any idea?
FILE MEDIUM
I agree that Kernel32 is not a good option if you need to do MT4-to-MT4 interfacing. The reason is that Kernel32 is Windows specific. The EA won't work on Mac. Also, messing around with Kernel32 DLL might cause memory leaks (eg, your 5hr live). Plus, it requires user to know how to enable DLL (you'd be surprise how many users have no idea how to enable it).
Recommendation:
If you only need SAME MT4 exchange (EAs between charts), then use the GlobalVariableGet(), GlobalVariableSet(), etc.
If you need exchange between 2 different MT4s (on the same PC) --even if it is across different broker MT4, then use the FILE system: Files\FilePipe.mqh which allows you to write to the common MT4 folder:
#include <Files\FilePipe.mqh>
CFilePipe voPipeOut;
voPipeOut.Open("yourFileName.txt", FILE_WRITE|FILE_COMMON|FILE_BIN);
voPipeOut.WriteString("WhatEverMessage, probably some CSV value here");
voPipeOut.Close();
and subsequently
CFilePipe voPipeFile;
string vsInString = "";
voPipeFile.Open("yourFileName.txt", FILE_SHARE_READ|FILE_COMMON|FILE_BIN);
voPipeFile.Seek(0,SEEK_SET);
voPipeFile.ReadString( vsInString );
voPipeFile.Close();
This way, your EA won't depend on DLLs and also works in a wide range of environments. It is very fast (under 2ms for a 1Mb pipe). It works even for cross-broker interfacing (exchanging info [feed?] between 2 different brokers).
The best idea?
The best thing I can advise you is to stop trying to tweak KERNEL32.DLL published API to make it use with MetaTrader Terminal 4 code-execution ecosystem and to rather start designing a professional distributed system, independently of injecting objects into the O/S pagefile and hassling with semaphores and MUTEX-es.
Besides the best next step:
MQL4 code ought NEVER block. A MUTEX-signalling turned into a non-blocking state is a must
MQL4 code / API mapper ought respect the data-types and their actual memory sizes in MQL4
MQL4 code ought conform to the recent New-MQL4 rules ( sections are in "old"-MQL4 )
MQL4 declared string is not a C-lang string, but rather a struct! Handle with care!
MQL4 code violated in several places syntax rules, just test with #property strict
MQL4 code is "shooting itself in leg" when ignoring namespace boundaries / scopes of declaration
MQL4 code ignores potential error states, not inspecting any GetLastError() to handle such collision(s)
MQL4 code does not gracefully return resources ( forgets to clear 'em )
MQL4 code proposed exposes itself into an immense risk of KERNEL32.DLL API usage unlocked stealth security flaw / enabling a run-time hijacking hack
better use separation of concerns, using ZeroMQ or nanomsg messaging to "exchange values between ( not only ) MQL4 programs"

What are the benefits of self encapsulation?

While reading some refactoring practices I stumbled upon this article
The author arguments to modify below code with getter and setters, I think they should be private but anyways what's the benefit in doing so? aren't we introducing the function call overhead?
Before:
private int _low, _high;
boolean includes (int arg) {
return arg >= _low && arg <= _high;
}
After:
private int _low, _high;
boolean includes (int arg) {
return arg >= getLow() && arg <= getHigh();
}
int getLow() {return _low;}
int getHigh() {return _high;}
Let's say, for some reason you need to change the names of your class attributes from _low, _high to _min, _max. In the 1st version, you need to modify the includes() function as well. In the 2nd version you only need to modify the getters. In your example the benefit is small, but in a bigger class it could save you a lot of work.
A slightly more complex example where the upper value is no longer stored but derived from the lower value and an interval:
private int _low, _interval;
boolean includes (int arg) {
return arg >= getLow() && arg <= getHigh();
}
int getLow() {return _low;}
int getHigh() {return _low + _interval;}
Again you only need to modify the getter.
Concerning the overhead: Depending on the language you are using, your compiler will optimize the function call away.

How to use the value of a return statement in a different method?

I recently started codeing java, so this question might be a little, well, stupid, but i created a small program that averages 5 numbers. I know the program is very over complicated, i have just been trying out some of the new things i've learned.My problem is i would like to get the variable "Answer" up in my main program. I dont want to change around the program if i dont have to.I have returned the value in the average method, and set this answer to the variable Answer, but how can i use System.out.print(Answer) or print the return. Heres the code! Sorry if its not in a code block, i indented 4 spaces, but it doesnt say anything.
package Tests;
import java.util.*;
public class average_Test {
static double Total=0;
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int temp;
int count[]={5,1,2,3,4};
for(int x:count){
System.out.print("Please enter 5 numbers: ");
temp=scan.nextInt();
average(temp);
}
}
public static double average(int n){
for(int c=0;c<1;c++){
Total+=n;
}
double average=Total/5;
System.out.println(average);
double Answer = Total/5;
return Total/5;
}
}
You can use variable binding, or print result of function:
double a = average(temp);
System.out.println(a);
or:
System.out.println(average(temp));
At the end it will look like this:
double result = 0;
System.out.print("Please enter 5 numbers: ");
for (int x : count) {
temp = scan.nextInt();
result = average(temp);
}
System.out.println(result);
P.S. code looks weird, consider implementing double average(int[] numbers)

Kcachegrind/callgrind is inaccurate for dispatcher functions?

I have a model code on which kcachegrind/callgrind reports strange results. It is kind of dispatcher function. The dispatcher is called from 4 places; each call says, which actual do_J function to run (so the first2 will call only do_1 and do_2 and so on)
Source (this is a model of actual code)
#define N 1000000
int a[N];
int do_1(int *a) { int i; for(i=0;i<N/4;i++) a[i]+=1; }
int do_2(int *a) { int i; for(i=0;i<N/2;i++) a[i]+=2; }
int do_3(int *a) { int i; for(i=0;i<N*3/4;i++) a[i]+=3; }
int do_4(int *a) { int i; for(i=0;i<N;i++) a[i]+=4; }
int dispatcher(int *a, int j) {
if(j==1) do_1(a);
else if(j==2) do_2(a);
else if(j==3) do_3(a);
else do_4(a);
}
int first2(int *a) { dispatcher(a,1); dispatcher(a,2); }
int last2(int *a) { dispatcher(a,4); dispatcher(a,3); }
int inner2(int *a) { dispatcher(a,2); dispatcher(a,3); }
int outer2(int *a) { dispatcher(a,1); dispatcher(a,4); }
int main(){
first2(a);
last2(a);
inner2(a);
outer2(a);
}
Compiled with gcc -O0; Callgrinded with valgrind --tool=callgrind; kcachegrinded with kcachegrind and qcachegrind-0.7.
Here is a full callgraph of the application. All paths to do_J go through dispatcher and this is good (the do_1 is just hided as too fast, but it is here really, just left to do_2)
Lets focus on do_1 and check, who called it (this picture is incorrect):
And this is very strange, I think, only first2 and outer2 called do_1 but not all.
Is it a limitation of callgrind/kcachegrind? How can I get accurate callgraph with weights (proportional to running time of every function, with and without its childs)?
Yes, this is limitation of callgrind format. It doesn't store full trace; it only stores parent-child calls information.
There is a google-perftools project with pprof/libprofiler.so CPU profiler, http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html . libprofiler.so can get profile with calltraces and it will store every trace event with full backtrace. pprof is converter of libprofile's output to graphic formats or to callgrind format. In full view the result will be the same as in kcachegrind; but if you will focus on some function, e.g. do_1 using pprof's option focus; it will show accurate calltree when focused on function.