Professional Documents
Culture Documents
As you may know there's no simple solution to put a macro because the
step of the preprocessor has to be the first to expand. So a macro is not
part of the source code and the best way is to set a macro always as a one
liner or somewhere else in comment.
The ratio of code to comment is also a well known metric which you can
predefine with a few procedures.
writeln(CommentLinesWithSlashes('this is a //comment for a
moment'))
Function CommentLinesWithSlashes(const S: String): String');
Function UncommentLinesWithSlashes(const S: String): String');
All macros and metrics are marked with yellow. One of my favour as I said
is #locs: means lines of code metric and you get always the certainty if
something has changed by the numbers of line. So the editor has a
programmatic macro system which allows the pre compiler to be extended
by user code I would say user tags. You find more macros at
All Functions List: maxbox_functions_all.pdf
Some macros produce simple combinations of one liner tags but at least
they replace the content by reference in contrary to templates which just
copy a content by value.
After the End. of the code section you can set a macro without comment
signs so you can enlarge your documentation with version and time
information like:
#tech:perf: 0:0:1.151 threads: 4 192.168.56.1 12:06:17 4.2.2.95
Or you put a macro behind a code-line, so this is not the end of the line, a
second time test is
maxcalcF('400000078669 / 2000123')
//#perf>0:0:1.163
and we get as float: 199987.740088485
maXbox4 568_U_BigFloatTestscript2.pas Compiled done: 6/18/2015
Generally you can categorize metrics in following groups:
Maintainability 29
Readability 25
Understandability 4
Modularity 3
Changeability 2
Data 1
Logic 1
Reliability 10
Architecture 1
Data 1
Exception handling 1
2
Fault tolerance 1
Instruction 5
Logic 1
Testability 1
Unit level 1
Uncharacterised 3
Lets go back to our performance metric example to close, which is one of
a non static metric:
2937127^(-1)17915749^(-1)2082607
maxcalcF('29*37*(127^-1)*179*(15749^-1)*2082607');
>> 199987.740088485
maxcalcF('29*37*(127^-1)*179*(15749^-1)*2082607');
//#tech>perf: 0:0:1.190 threads: 6 192.168.56.1 12:49:55 4.2.2.95
//>>> 199987.740088485
http://www.tiobe.com/_userdata/files/TIOBEQualityIndicator_v3_8.pdf
Now we step with a traceable real world function through the 8 points.
For example a DLL is a library, short for Dynamic Link Library, a library of
executable functions or data that can be used by a Windows or Linux
application. This is how we declare a function we want to use from a DLL:
Function OpenProcess2(dwDesiredAccess: DWORD;
bInheritHandle: BOOL; dwProcessId:DWORD): THandle;
External 'OpenProcess@kernel32.dll stdcall';
Suppose you want to use the function OpenProcess of the kernel32.dll.
All you have to do is to declare above statement and you get access to the
kernel! With external you made these functions available to callers
external to the DLL, so we must export them or at least say the function
we use is from External.
1. Functional suitability
This means for e.g. also to use the modifier stdcall because this is a C
convention. The function name OpenProcess2 is different from the original
name OpenProcess! This is an alias to prevent name conflicts or name it
4
you like because you do have conventions you are free to rename or reuse
a function in your script.
2. Reliability
For this we have to test the fault tolerance or correctness of the function
and to proof the correctness with a real call.
ProcessHandle:= OpenProcess2(PROCESS_QUERY_INFORMATION or
PROCESS_VM_READ, false, ProcessID);
Writeln('Process Handle inside: '+inttostr(ProcessHandle));
try
if GetProcessMemoryInfo(ProcessHandle,
MemCounts, sizeof(MemCounts))
then writeln('Working Set Mem KB: '+inttostr(MemCounts.WorkingSetSize div 1024));
finally
CloseHandle(ProcessHandle);
end;
The fault tolerance is covered with a try finally statement to free resources
and the result can be done with the help of the resource monitor:
As an output we get:
Process Id 12316
Process Handle inside: 3384
Working Set Memory KB: 108136
But is it the right result of 108136 at runtime, so lets open the resource
monitor and find to find and compare our process best with a screenshot:
By the way another test is Don't test floating point numbers for equality!
Of course those 2 numbers are Integers to compare but I had to divide the
result by 1024 to get Kbytes:
then Writeln('Working Set Mem KB: '+inttostr(MemCounts.WorkingSetSize div 1024));
Therefore, the use of the equality (== or = ) and inequality (!= or <>)
operators on float or double values is almost always an error. Instead the
best course is to avoid floating point comparisons altogether as in our case
with the div operator.
3. Performance efficiency
No problem at all because the performance relative to the amount of
resources used under this conditions is small, check it with
#tech: perf: 0:0:3.450 threads: 11 192.168.56.1 13:40:05 4.2.2.98
4. Operability
This one is not so easy. Operability for instance, with sub-attributes such
as Attractiveness and Ease of Use is not that clear to understand. How
to measure this and what is the unit of measurement?
For me global variables and possible side effects is a test to find and
global variables as well as direct output has to be prevented.
In our case we use 3 nasty variables:
ProcessHandle : THandle;
MemCounts : TProcessMemoryCounters;
ProcessID : DWORD;
Two of them are now local variables and the third one ProcessID is a
parameter of the function. Then we initialize the result with zero and we
delete the writeln as a dangerous direct output.
ProcessHandle:= OpenProcess2(PROCESS_QUERY_INFORMATION or
PROCESS_VM_READ, False, ProcessID);
6. Compatibility
The degree to which two or more systems or components can exchange
information and/or perform their required functions.
7
Built-in data types are written in lower case except the first letter.
Function arguments are separated by comma when calling the function.
Put a space after the comma but none before and so on.
To get more compatibility there's a template dll, write the word dll
maybe at the beginning or below or inside of your code and press <Ctrl>
j and it gets expanded to:
function MyGetTickCount: Longint;
external 'GetTickCount@kernel32.dll stdcall';
Now we can change it e.g. to 64bit:
function MyGetTickCount64: Longint;
external 'GetTickCount64@kernel32.dll stdcall';
7. Maintainability
Use modifying as a need like programming for change.
Comments describing function behaviour has to be put before the function
itself. Comments within the function body is aligned with code and is best
placed before the code if the comment apply to several lines, or is too long
to fit at the right of the code.
Result:= 0;
//PROCESS_VM_READ Required read memory in a process using ReadProcessMemory
ProcessHandle:= OpenProcess2(PROCESS_QUERY_INFORMATION or
PROCESS_VM_READ, False, ProcessID);
IP_MULTICAST_TTL = 3;
IP_MULTICAST_LOOP = 4;
IP_ADD_MEMBERSHIP = 5;
GClassCritSect : TRTLCriticalSection;
{$ENDIF}
Classes, Forms, Graphics, Controls, Types, KFunctions
{$IFDEF USE_THEMES}
, Themes
{$IFNDEF FPC}
, UxTheme
{$ENDIF}
{$ENDIF} ;
Lines of code
Code Complexity
Code Coverage
Rules Compliance
Document Comments
10
SonarQube is originally written for Java analysis at PMD and later added
C# and further support.
The SonarQube (web) server pulls the results from the database and
provides a UI for reviewing and managing them, as well as a UI for
managing configuration settings, user authentication, etc. The server also
has its own config file sonar.properties where you define database
settings, user authentication settings, etc.
The monitor shows then the following topics:
Duplicated code
Coding standards
Unit tests and Code Coverage
Complex code
Potential bugs and issues
Comments /API Documentation
Design and architecture
The defined Ruleset of SonarQube (web) 5.1.1 can be found at:
Important metrics to look for
duplicated_blocks
violations info_violations
public_undocumented_api
uncovered_complexity_by_tests (it is considered that 80% of coverage
is the objective)
function_complexity_distribution >= 8,
class_complexity_distribution >= 60 package_edges_weight
srlist:= TStringlist.create;
ConsoleCapture('C:\', 'cmd.exe', '/c dir *.*',srlist);
writeln(srlist.text)
srlist.Free;
But you can redirect the output srlist.text anywhere you want.
For example you can capture the output of a DOS console and input into a
textbox, or you want to capture the command start of demo app and input
into your app that will do further things.
ConsoleCapture('C:\', 'cmd.exe', '/c ipconfig',srlist);
ConsoleCapture('C:\', 'cmd.exe', '/c ping 127.0.0.1',srlist);
java -version
must be captured with different parameters like /k or in combination.
Here's the solution with GetDosOutput():
writeln('GetDosOut: '+GetDosOutput('java -version','c:\'));
or like the man-pages in Linux
writeln('GetDosOut: '+GetDosOutput('help dir','c:\'));
IFPS#
### mX3 byte code executed: 10.06.2015 13:53:20 Runtime:
0:0:1.577 Memoryload: 60% use ByteCode Success Message
of: 287_eventhandling2_primewordcount.psb
4. When testing is finished you send the byte-code to your client
14
1.8 Appendix
Wise men speak because they have something to say; Fools, because
they have to say something. -Plato
Something with the Internet of Thing ;-)
Feedback @ max@kleiner.com
Literature: Kleiner et al., Patterns konkret, 2003, Software & Support
https://github.com/maxkleiner/maXbox3/releases
Ref: TIOBEQualityIndicator_v3_8.pdf
http://www.tiobe.com/_userdata/files/TIOBEQualityIndicator_v3_8.pdf
[2] ISO, Systems and software engineering Systems and software Quality
Requirements and Evaluation (SquaRE) System and software quality models ,
ISO/IEC 25010:2011, 2011, obtainable from
http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?
csnumber=35733
15