| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748 | 
							- <!DOCTYPE html>
 
- <!--
 
-     Metrix++, Copyright 2009-2013, Metrix++ Project
 
-     Link: http://metrixplusplus.sourceforge.net
 
-     
 
-     This file is part of Metrix++ Tool.
 
-     
 
-     Metrix++ is free software: you can redistribute it and/or modify
 
-     it under the terms of the GNU General Public License as published by
 
-     the Free Software Foundation, version 3 of the License.
 
-     
 
-     Metrix++ is distributed in the hope that it will be useful,
 
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
 
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
-     GNU General Public License for more details.
 
-     
 
-     You should have received a copy of the GNU General Public License
 
-     along with Metrix++.  If not, see <http://www.gnu.org/licenses/>.
 
- -->
 
- <html lang="en">
 
-   <head>
 
-     <meta charset="utf-8">
 
-     <title>Metrix++ Project</title>
 
-     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 
-     <meta name="description" content="">
 
-     <meta name="author" content="">
 
-     <!-- Le styles -->
 
-     <!--
 
-     <link href="../../style.css" rel="stylesheet">
 
-     -->
 
-     <link href="assets/css/bootstrap.css" rel="stylesheet">
 
-     <link href="assets/css/bootstrap-responsive.css" rel="stylesheet">
 
-     <link href="assets/css/docs.css" rel="stylesheet">
 
-     <link href="assets/js/google-code-prettify/prettify.css" rel="stylesheet">
 
-     
 
-     <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
 
-     <!--[if lt IE 9]>
 
-       <script src="assets/js/html5shiv.js"></script>
 
-     <![endif]-->
 
-     <!-- Le fav and touch icons -->
 
-     <link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/ico/apple-touch-icon-144-precomposed.png">
 
-     <link rel="apple-touch-icon-precomposed" sizes="114x114" href="assets/ico/apple-touch-icon-114-precomposed.png">
 
-     <link rel="apple-touch-icon-precomposed" sizes="72x72" href="assets/ico/apple-touch-icon-72-precomposed.png">
 
-     <link rel="apple-touch-icon-precomposed" href="assets/ico/apple-touch-icon-57-precomposed.png">
 
-     <link rel="shortcut icon" href="assets/ico/favicon.png">
 
- 	<!--
 
-     <script type="text/javascript">
 
-       var _gaq = _gaq || [];
 
-       _gaq.push(['_setAccount', 'UA-146052-10']);
 
-       _gaq.push(['_trackPageview']);
 
-       (function() {
 
-         var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
 
-         ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
 
-         var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
 
-       })();
 
-     </script>
 
-    -->
 
-   </head>
 
-   <body data-spy="scroll" data-target=".bs-docs-sidebar">
 
-     <!-- Navbar
 
-     ================================================== -->
 
-     <div class="navbar navbar-link navbar-fixed-top">
 
-       <div class="navbar-inner">
 
-         <div class="container">
 
-           <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
 
-             <span class="icon-bar"></span>
 
-             <span class="icon-bar"></span>
 
-             <span class="icon-bar"></span>
 
-           </button>
 
-           <a class="brand" href="./index.html">Metrix++</a>
 
-           <div class="nav-collapse collapse">
 
-             <ul class="nav">
 
-               <li class="">
 
-                 <a href="./index.html">Home</a>
 
-               </li>
 
-             </ul>
 
-           </div>
 
-         </div>
 
-       </div>
 
-     </div>
 
-     <!-- Subhead
 
-     ================================================== -->
 
-     <header class="jumbotron" id="overview">
 
-       <div id="myCarousel" class="carousel slide">
 
-         <div class="carousel-inner">
 
-           <div class="item active">
 
-             <img src="assets/img/slide-01.jpg" alt="">
 
-             <div class="container">
 
-               <div class="carousel-caption">
 
-                 <h2>Multiple languages</h2>
 
-                 <p class="lead">· C/C++, C# and Java.</p>
 
-                 <p class="lead">· Recognises classes, interfaces, namespaces, functions, comments, preprocessor and much more.</p>
 
-               </div>
 
-             </div>
 
-           </div>
 
-           <div class="item">
 
-             <img src="assets/img/slide-02.jpg" alt="">
 
-             <div class="container">
 
-               <div class="carousel-caption">
 
-                 <h2>Multiple metrics</h2>
 
-                 <p class="lead">· Complexity, size and other.</p>
 
-               </div>
 
-             </div>
 
-           </div>
 
-           <div class="item">
 
-             <img src="assets/img/slide-03.jpg" alt="">
 
-             <div class="container">
 
-               <div class="carousel-caption">
 
-                 <h2>High performance and scalability</h2>
 
-                 <p class="lead">· Applicable to huge code bases: thousands of files per minute.</p>
 
-                 <p class="lead">· Ultra-fast feedback on iterative re-run.</p>
 
-               </div>
 
-             </div>
 
-           </div>
 
-           <div class="item">
 
-             <img src="assets/img/slide-01.jpg" alt="">
 
-             <div class="container">
 
-               <div class="carousel-caption">
 
-                 <h2>Effortless application to legacy code</h2>
 
-                 <p class="lead">· Recognises legacy, modified and new code.</p>
 
-                 <p class="lead">· Prevents from negative trends. Encourages positive.</p>
 
-               </div>
 
-             </div>
 
-           </div>
 
-           <div class="item">
 
-             <img src="assets/img/slide-02.jpg" alt="">
 
-             <div class="container">
 
-               <div class="carousel-caption">
 
-                 <h2>Configurable</h2>
 
-                 <p class="lead">· Define and apply your rules and policies.</p>
 
-                 <p class="lead">· Integrate with your workflow.</p>
 
-               </div>
 
-             </div>
 
-           </div>
 
-           <div class="item">
 
-             <img src="assets/img/slide-03.jpg" alt="">
 
-             <div class="container">
 
-               <div class="carousel-caption">
 
-                 <h2>Extendable via plugins</h2>
 
-                 <p class="lead">· Define your custom metric.</p>
 
-                 <p class="lead">· Add new language parser.</p>
 
-                 <p class="lead">· Create advanced post-analysis tool.</p>
 
-               </div>
 
-             </div>
 
-           </div>
 
-         </div>
 
-         <a class="left carousel-control" href="#myCarousel" data-slide="prev">‹</a>
 
-         <a class="right carousel-control" href="#myCarousel" data-slide="next">›</a>
 
-       </div>      
 
-       <div class="container">
 
-         <div class="row">
 
-           <div class="span3">
 
-           </div>
 
-           <div class="span9">
 
-             <h5 class="text-right">Management of source code quality is possible.</h5>
 
-             <p class="text-right">
 
-                 <a href="https://sourceforge.net/projects/metrixplusplus/files/latest/download"
 
-                     ><button type="button"class="btn btn-danger">Download</button></a>
 
-                 <!--
 
-                 <button type="button"class="btn btn-warning">Donate</button>
 
-                 -->
 
-             </p>
 
-           </div>
 
-         </div>
 
-       </div>
 
-     </header>
 
-     <div class="container"><div class="row">
 
-       
 
-       <!-- Docs nav
 
- 	  ================================================== -->
 
-       <div class="span3 bs-docs-sidebar">
 
-         <ul class="nav nav-list bs-docs-sidenav">
 
-           <!--<li><img src="../../logo_project.png"/><p> </p></li>-->
 
-           <li><a href="#overview_section"><i class="icon-chevron-right"></i> Overview</a></li>
 
-           <li><a href="#download_section"><i class="icon-chevron-right"></i> Download & Install</a></li>
 
-           <li><a href="#workflow_collect_section"><i class="icon-chevron-right"></i> Workflow: Collect data</a></li>
 
-           <li><a href="#workflow_view_section"><i class="icon-chevron-right"></i> Workflow: View data</a></li>
 
-           <li><a href="#workflow_view_summary_section"><i class="icon-hand-right"></i> · summary & distributions</a></li>
 
-           <li><a href="#workflow_view_details_section"><i class="icon-hand-right"></i> · details per file/region</a></li>
 
-           <li><a href="#workflow_limit_section"><i class="icon-chevron-right"></i> Workflow: Apply thresholds</a></li>
 
-           <li><a href="#workflow_limit_hotspots_section"><i class="icon-hand-right"></i> · hotspots</a></li>
 
-           <li><a href="#workflow_limit_control_section"><i class="icon-hand-right"></i> · controlling trends</a></li>
 
-           <li><a href="#workflow_other_section"><i class="icon-chevron-right"></i> Workflow: Other applications</a></li>
 
-           <li><a href="#extend_section"><i class="icon-chevron-right"></i> Create plugin</a></li>
 
-           <li><a href="#contribute_section"><i class="icon-chevron-right"></i> Feedback & Contribute</a></li>
 
-         </ul>
 
-       </div>
 
-       
 
-       <!-- Sections
 
- 	  ================================================== -->
 
-       <div class="span9">
 
-         <!-- Overview
 
-         ================================================== -->
 
-         <section id="overview_section">
 
-           <div class="page-header">
 
-             <h1>Overview</h1>
 
-           </div>
 
-           <h3>Highlights</h3>
 
-           <p>Metrix++ is a tool to collect and analyse code metrics. Any metric is useless if it is not used.
 
-              Metrix++ offers ease of introduction and integration with a variety of application use cases.</p>
 
-           <ul>
 
-             <li>Monitoring trends (eg. on <strong>daily</strong> basis. In order to take actions or make right decisions earlier.)</li>
 
-             <li>Enforcing trends (eg. on <strong>hourly</strong> basis, at every commit of code changes.)</li>
 
-             <li>Automated asistance to review agains standards (eg. on <strong>per minute</strong> basis during code refactoring and code development.)</li>
 
-           </ul>
 
-           <p>The workflow sections below demonstarate these basic application usecases.</p>
 
-           <h3>Languages supported</h3>
 
-           <p>The tool can parse C/C++, C# and Java source code files. The parser identifies certain regions in the code,
 
-              such as classes, functions, namespaces, interfaces, etc. It detects comments, strings and code for the preprocessor.
 
-              The identified regions form a tree of nested source code blocks, which are subsequently refered to and scanned by metrics plugins.
 
-              Thus the tool attributes metrics to regions, which provides fine grained data to analysis tools.
 
-              The following example demonstrates the regions concept.</p>
 
-              
 
-           <table class="table">
 
-             <thead>
 
-               <tr>
 
-                 <th>Source code</th>
 
-                 <th>Regions tree [type: name: content type]</th>
 
-               </tr>
 
-             </thead>
 
-             <tbody>
 
-               <tr>
 
-                 <td>
 
- <pre class="prettyprint linenums">
 
- // simple C++ code
 
- #include <myapi.h>
 
- // I explain the following class
 
- class MyClass {
 
- public:
 
-     int m_var; // some member
 
-     // I explain the following function
 
-     MyClass(): m_var(0) {
 
-         char str[] = "unused string"
 
-         
 
-         // nested region for good measure
 
-         struct MyStruct {};
 
-     }
 
-     
 
-     // Do not judge ugly code below
 
- #define get_max(a,b) ((a)>(b)?(a):(b))
 
-     set_max(int b) {
 
-         m_var = get_max(m_var, b);
 
-     }
 
- };
 
- // this is the last line
 
- </pre>
 
-                 </td>
 
-                 <td>
 
- <pre class="prettyprint linenums">
 
- file: __global__: comment
 
- file: __global__: code
 
- file: __global__: preprocessor
 
- file: __global__: code
 
-     class: MyClass: comment
 
-     class: MyClass: code
 
-     class: MyClass: code
 
-     class: MyClass: code, comment
 
-     class: MyClass: code
 
-         function: MyClass: comment
 
-         function: MyClass: code
 
-         function: MyClass: code, string
 
-         function: MyClass: code
 
-             struct: MyStruct: comment
 
-             struct: MyStruct: code
 
-         function: MyClass: code
 
-     class: MyClass: code
 
-         function: set_max: comment
 
-         function: set_max: preprocessor
 
-         function: set_max: code
 
-         function: set_max: code
 
-         function: set_max: code
 
-     class: MyClass: code
 
- file: __global__: comment
 
- </pre>
 
-                 </td>
 
-               </tr>
 
-             </tbody>
 
-           </table>
 
-           <h3>Metrics</h3>
 
-           <p>The metrics highlighed in blue are <strong>per file</strong> metrics. The other metrics are <strong>per region</strong> metrics.</p>
 
-           <table class="table table-bordered">
 
-             <thead>
 
-               <tr>
 
-                 <th>Metric (enable option)</th>
 
-                 <th>Brief description</th>
 
-                 <th>Motivation / Potential use</th>
 
-               </tr>
 
-             </thead>
 
-             <tbody>
 
-               <tr class="info">
 
-                 <td>std.general.size</td>
 
-                 <td>Size of a file in bytes.</td>
 
-                 <td rowspan="4"><ul><li>Monitoring the growth of source code base.</li>
 
-                     <li>Normalizing other metrics.</li>
 
-                     <li>Preventing large files and regions (large things are difficult to maintain).</li>
 
-                     <li>Predicting delivery dates by comparing
 
-                         <a href="http://www.compaid.com/caiInternet/casestudies/kanarticle2.pdf">S-shaped code base growth / change curves</a>.</li></ul></td>
 
-               </tr>
 
-               <tr>
 
-                 <td>std.code.length.total</td>
 
-                 <td>The same as 'std.general.size' metric, but attributed to code regions.</td>
 
-                 <td></td>
 
-               </tr>
 
-               <tr>
 
-                 <td>std.code.lines.total</td>
 
-                 <td>Number of non-blank lines of code of any content type (exectuable, comments, etc.)</td>
 
-                 <td></td>
 
-               </tr>
 
-               <tr>
 
-                 <td>std.code.lines.code</td>
 
-                 <td>Number of non-blank lines of code excluding preprocessor and comments.</td>
 
-                 <td></td>
 
-               </tr>
 
-               <tr>
 
-                 <td>std.code.lines.preprocessor</td>
 
-                 <td>Number of non-blank lines of preprocessor code.</td>
 
-                 <td><ul><li>Enforcing localisation of preprocessor code in a single place.</li>
 
-                     <li>Encouraging usage of safer code structures instead of the preprocessor.</li></ul></td>
 
-               </tr>
 
-               <tr>
 
-                 <td>std.code.lines.comments</td>
 
-                 <td>Number of non-blank lines of comments.</td>
 
-                 <td><ul><li>Low number of comments may indicate maintainability problems.</li></ul></td>
 
-               </tr>
 
-               <tr>
 
-                 <td>std.code.complexity.cyclomatic</td>
 
-                 <td>McCabe cyclomatic complexity metric.</td>
 
-                 <td colspan="2"><ul><li>Identification of highly complex code for review and refactoring.</li>
 
-                     <li>Preventing complex functions (complexity is a reason of many defects and a reason of expensive maintaintenance).</li></ul></td>
 
-               </tr>
 
-               <tr>
 
-                 <td>std.code.complexity.maxindent</td>
 
-                 <td>Maximum level of indentation of blocks within a region. For example, the following class has got 
 
-                 	the metric equal to 1 and the function has got it equal to 2:
 
-                 	<pre class="prettyprint">
 
- class WeekClass {
 
-     int isWeekend(int day) {
 
-         if (day == SATURDAY ||
 
-             day == SUNDAY) {
 
-             return true;
 
-         }
 
-         return false;
 
-     }
 
- }
 
- </pre>
 
-                 	</td>
 
-               </tr>
 
-               <tr>
 
-                 <td>std.suppress</td>
 
-                 <td>An option enables collection of Metrix++ suppressions and 2 metrics: 'std.suppress:count' and 
 
-                     'std.suppress.file:count'. The first is number of suppressions per region.
 
-                     The second is the same but applies for file-scope metrics.</td>
 
-                 <td><ul><li>Suppressing false-positives.</li>
 
-                     <li>Managing the amount of suppressions. There should be no false-positives to suppress with the right metric,
 
-                         but there could be exceptions in specific cases. Managing suppressions is about managing exceptions.
 
-                         If there are many exceptional cases, maybe something is wrong with a metric or the application of a metric.</li></ul></td>
 
-               </tr>
 
-               <tr class="info">
 
-                 <td>std.general.procerrors</td>
 
-                 <td>Number of errors detected by Metrix++ code parser.</td>
 
-                 <td><ul><li>Cleaning up errors to ensure reliable code scanning.</li>
 
-                 	<li>Errors, like mismatched brackets, may result in bad identification of regions.</li>
 
-                 </ul></td>
 
-               </tr>
 
-               <tr class="info">
 
-                 <td>std.general.proctime</td>
 
-                 <td>Seconds spent on processing a file.</td>
 
-                 <td><ul><li>Monitor and profile Metrix++ tool's performance.</li></ul></td>
 
-               </tr>
 
-             </tbody>
 
-           </table>
 
-         </section>
 
-         <section id="download_section">
 
-           <div class="page-header">
 
-             <h1>Download & Install</h1>
 
-           </div>
 
-           <p>In order to get the tool working, <a href="https://sourceforge.net/projects/metrixplusplus/files/latest/download">dowload the archive</a> with the latest stable version
 
-              and unpack it to some folder. The first run of the tool will trigger the installation within the folder,
 
-              where it was launched.</p>
 
-           <p>In order to checkout the latest released version from the <a href="https://sourceforge.net/p/metrixplusplus/code">version control system</a> use this command:</p>
 
-           <pre>svn checkout <a href="https://sourceforge.net/p/metrixplusplus/code">svn://svn.code.sf.net/p/metrixplusplus/code</a>/releases/latest Metrix++</pre>
 
-           <p>In order to checkout the latest version under development, use this command:</p>
 
-           <pre>svn checkout <a href="https://sourceforge.net/p/metrixplusplus/code">svn://svn.code.sf.net/p/metrixplusplus/code</a>/mainline Metrix++</pre>
 
-           <h4>Prerequisites</h4>
 
-           <p>Python Runtime Environment (version 2.7.* or later. Version 3.* has not been tested)</p>
 
-           <h4>License</h4>
 
-           <p>This program is free software; you can redistribute it and/or modify it
 
-              under the terms of the GNU General Public License as published by the
 
-              Free Software Foundation; version 3 of the License.</p>
 
-           <p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 
-              without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
-              See the GNU General Public License for more details.</p>
 
-           <p>You should have received a copy of the GNU General Public License along with the Metrix++;
 
-              if not, contact <a href="mailto:avkonst@users.sourceforge.net?subject=Metrix%2B%2B License">Project Administrator</a></p>
 
-              
 
-         </section>
 
-         <div class="page-header">
 
-           <h1>Workflow</h1>
 
-         </div>
 
-         <p>The workflow and application usecases are demonstrated using source code from the 
 
-         	<a href="http://www.boost.org/doc/libs/1_54_0/doc/html/interprocess.html">boost/interprocess library</a>.
 
-         	Boost versions 1.52 and 1.54 are used and refered below as the 'previous' version and the 'current' version accordingly.</p>
 
-         <section id="workflow_collect_section">
 
-           <h2>Collect data</h2>
 
-           <p>The first step is to collect the data.
 
-              The 'collect' tool has got multiple options to enable various metrics plugins.
 
-              Let's collect the number of lines of code and cyclomatic complexity metrics
 
-              for the previous (1.52.0 version) boost interprocess library. Assuming that 2 versions of boost library
 
-              are unpacked in the current working directory:</p>
 
-           <pre>
 
- > cd boost_1_52_0
 
- > python "/path/to/metrix++.py" collect --std.code.lines.code --std.code.complexity.cyclomatic -- boost/interprocess
 
- > cd ../ # return back to working directory
 
- </pre>
 
-           <p>The list of arguments after '--' enumerates the paths to read the source files.
 
-           	As a result of execution of this command, a file metrixpp.db will be written in the current working directory.
 
-           	It can be redefined using the --db-file option.</p>
 
-           <p>Metrix++ can compare code bases which reduces processing scope to the modified or new code.
 
-           	So, let's collect the same data for the current (1.54.0 version) boost interprocess library.</p>
 
-           <pre>
 
- > cd boost_1_54_0
 
- > python "/path/to/metrix++.py" collect --std.code.lines.code --std.code.complexity.cyclomatic -- boost/interprocess --db-file-prev=../boost_1_52_0/metrixpp.db
 
- > cd ../ # return back to working directory
 
- </pre>
 
-           <p>The option --db-file-prev points to the file with the data collected in the previous step.
 
-           	So, eventually it executed iterative collection. It can speed up the exectuion significantly,
 
-           	depending on amount of changes between two version.</p>
 
-           <p>Check other options of the collect tool by executing:</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" collect --help
 
- </pre>
 
-         </section>
 
-         <section id="workflow_view_section">
 
-           <h2>View data</h2>
 
-         </section>
 
-         <section id="workflow_view_summary_section">
 
-           <h3>Summary metrics and distribution tables/graphs</h3>
 
-           <p>It is time to look at the data files collected (step above). The command:</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" view --db-file=boost_1_54_0/metrixpp.db
 
- </pre>
 
-           <p>prints summary metrics, like minimum/maximum, and distribution/frequency tables:</p>
 
-           <pre>
 
- :: info: Overall metrics for 'std.code.complexity:cyclomatic' metric
 
- 	Average        : 0.652902698283
 
- 	Minimum        : 0
 
- 	Maximum        : 37
 
- 	Total          : 1597.0
 
- 	Distribution   : 2446 regions in total (including 0 suppressed)
 
- 	  Metric value : Ratio : R-sum : Number of regions
 
- 	             0 : 0.771 : 0.771 : 1886	|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 
- 	             1 : 0.110 : 0.881 :  268	|||||||||||
 
- 	             2 : 0.044 : 0.925 :  108	||||
 
- 	             3 : 0.025 : 0.949 :   60	||
 
- 	             4 : 0.016 : 0.966 :   40	||
 
- 	             5 : 0.007 : 0.973 :   18	|
 
- 	             6 : 0.006 : 0.979 :   14	|
 
- 	             7 : 0.004 : 0.983 :   10	
 
- 	             8 : 0.003 : 0.986 :    8	
 
- 	             9 : 0.002 : 0.988 :    4	
 
- 	            10 : 0.004 : 0.991 :    9	
 
- 	            11 : 0.002 : 0.993 :    4	
 
- 	            12 : 0.001 : 0.994 :    3	
 
- 	            13 : 0.001 : 0.995 :    2	
 
- 	            14 : 0.001 : 0.996 :    2	
 
- 	         15-16 : 0.001 : 0.997 :    3	
 
- 	         17-18 : 0.001 : 0.998 :    3	
 
- 	            20 : 0.000 : 0.999 :    1	
 
- 	         23-25 : 0.001 : 1.000 :    2	
 
- 	            37 : 0.000 : 1.000 :    1	
 
- :: info: Overall metrics for 'std.code.lines:code' metric
 
- 	Average        : 6.64356984479
 
- 	Minimum        : 0
 
- 	Maximum        : 201
 
- 	Total          : 23970.0
 
- 	Distribution   : 3608 regions in total (including 0 suppressed)
 
- 	  Metric value : Ratio : R-sum : Number of regions
 
- 	           0-1 : 0.088 : 0.088 :  319	|||||||||
 
- 	             2 : 0.320 : 0.409 : 1155	||||||||||||||||||||||||||||||||
 
- 	             3 : 0.108 : 0.517 :  390	|||||||||||
 
- 	             4 : 0.081 : 0.598 :  294	||||||||
 
- 	             5 : 0.080 : 0.678 :  290	||||||||
 
- 	             6 : 0.061 : 0.739 :  220	||||||
 
- 	             7 : 0.049 : 0.788 :  176	|||||
 
- 	             8 : 0.030 : 0.818 :  109	|||
 
- 	             9 : 0.025 : 0.843 :   89	||
 
- 	         10-11 : 0.032 : 0.876 :  117	|||
 
- 	         12-13 : 0.020 : 0.895 :   71	||
 
- 	            14 : 0.012 : 0.907 :   43	|
 
- 	         15-16 : 0.017 : 0.924 :   61	||
 
- 	         17-19 : 0.015 : 0.939 :   55	||
 
- 	         20-22 : 0.013 : 0.952 :   46	|
 
- 	         23-26 : 0.011 : 0.963 :   40	|
 
- 	         27-30 : 0.009 : 0.972 :   33	|
 
- 	         31-39 : 0.009 : 0.981 :   33	|
 
- 	         40-65 : 0.009 : 0.991 :   34	|
 
- 	        66-201 : 0.009 : 1.000 :   33	|
 
- :: info: Directory content:
 
- 	Directory      : .
 
- </pre>
 
-           <p>The same command with --db-file-prev option enables comparision and change trends are shown in [] brackets:</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" view --db-file=boost_1_54_0/metrixpp.db --db-file-prev=boost_1_52_0/metrixpp.db
 
- </pre>
 
-           <pre>
 
- :: info: Overall metrics for 'std.code.complexity:cyclomatic' metric
 
- 	Average        : 0.652902698283 [+0.00362138411453]
 
- 	Minimum        : 0 [+0]
 
- 	Maximum        : 37 [+1]
 
- 	Total          : 1597.0 [+16.0]
 
- 	Distribution   : 2446 [+11] regions in total (including 0 [+0] suppressed)
 
- 	  Metric value : Ratio : R-sum : Number of regions
 
- 	             0 : 0.771 : 0.771 : 1886 [+5   ]	|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 
- 	             1 : 0.110 : 0.881 :  268 [+4   ]	|||||||||||
 
- 	             2 : 0.044 : 0.925 :  108 [+0   ]	||||
 
- 	             3 : 0.025 : 0.949 :   60 [+2   ]	||
 
- 	             4 : 0.016 : 0.966 :   40 [-1   ]	||
 
- 	             5 : 0.007 : 0.973 :   18 [-1   ]	|
 
- 	             6 : 0.006 : 0.979 :   14 [+1   ]	|
 
- 	             7 : 0.004 : 0.983 :   10 [+1   ]	
 
- 	             8 : 0.003 : 0.986 :    8 [+1   ]	
 
- 	             9 : 0.002 : 0.988 :    4 [+0   ]	
 
- 	            10 : 0.004 : 0.991 :    9 [-2   ]	
 
- 	            11 : 0.002 : 0.993 :    4 [+1   ]	
 
- 	            12 : 0.001 : 0.994 :    3 [+0   ]	
 
- 	            13 : 0.001 : 0.995 :    2 [+0   ]	
 
- 	            14 : 0.001 : 0.996 :    2 [+0   ]	
 
- 	         15-16 : 0.001 : 0.997 :    3 [-1   ]	
 
- 	         17-18 : 0.001 : 0.998 :    3 [+1   ]	
 
- 	            20 : 0.000 : 0.999 :    1 [+0   ]	
 
- 	         23-25 : 0.001 : 1.000 :    2 [+0   ]	
 
- 	         36-37 : 0.000 : 1.000 :    1 [+0   ]	
 
- :: info: Overall metrics for 'std.code.lines:code' metric
 
- 	Average        : 6.64356984479 [+0.012181964309]
 
- 	Minimum        : 0 [+0]
 
- 	Maximum        : 201 [+4]
 
- 	Total          : 23970.0 [+223.0]
 
- 	Distribution   : 3608 [+27] regions in total (including 0 [+0] suppressed)
 
- 	  Metric value : Ratio : R-sum : Number of regions
 
- 	           0-1 : 0.088 : 0.088 :  319 [+3   ]	|||||||||
 
- 	             2 : 0.320 : 0.409 : 1155 [+9   ]	||||||||||||||||||||||||||||||||
 
- 	             3 : 0.108 : 0.517 :  390 [-3   ]	|||||||||||
 
- 	             4 : 0.081 : 0.598 :  294 [+7   ]	||||||||
 
- 	             5 : 0.080 : 0.678 :  290 [+7   ]	||||||||
 
- 	             6 : 0.061 : 0.739 :  220 [-1   ]	||||||
 
- 	             7 : 0.049 : 0.788 :  176 [-2   ]	|||||
 
- 	             8 : 0.030 : 0.818 :  109 [-1   ]	|||
 
- 	             9 : 0.025 : 0.843 :   89 [+4   ]	||
 
- 	         10-11 : 0.032 : 0.876 :  117 [+9   ]	|||
 
- 	         12-13 : 0.020 : 0.895 :   71 [-9   ]	||
 
- 	            14 : 0.012 : 0.907 :   43 [+0   ]	|
 
- 	         15-16 : 0.017 : 0.924 :   61 [+0   ]	||
 
- 	         17-19 : 0.015 : 0.939 :   55 [+6   ]	||
 
- 	         20-22 : 0.013 : 0.952 :   46 [-3   ]	|
 
- 	         23-26 : 0.011 : 0.963 :   40 [+2   ]	|
 
- 	         27-30 : 0.009 : 0.972 :   33 [-3   ]	|
 
- 	         31-39 : 0.009 : 0.981 :   33 [+0   ]	|
 
- 	         40-65 : 0.009 : 0.991 :   34 [+1   ]	|
 
- 	        66-201 : 0.009 : 1.000 :   33 [+1   ]	|
 
- :: info: Directory content:
 
- 	Directory      : .
 
- </pre>
 
-           <h4>Reducing analysis scope</h4>
 
-           <p>There are two ways to reduce the analysis scope for the view tool. The first is to enumerate paths of interest.
 
-           	For example, the following command reduces scope to the 'allocators' sub-directory within the processed code.</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" view --db-file=boost_1_54_0/metrixpp.db -- ./boost/interprocess/allocators
 
- </pre>
 
-           <p>The second is to specify the --scope-mode option, which instructs the tool to process only modified and/or new files/regions.
 
-           	For example, to view the summary metrics for all modified and new regions:</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" view --db-file=boost_1_54_0/metrixpp.db  --db-file-prev=boost_1_52_0/metrixpp.db --scope-mode=touched
 
- </pre>
 
-           <pre>
 
- :: info: Overall metrics for 'std.code.complexity:cyclomatic' metric
 
- 	Average        : 1.84924623116 [-0.0230941943761]
 
- 	Minimum        : 0 [+0]
 
- 	Maximum        : 37 [+1]
 
- 	Total          : 368.0 [+16.0]
 
- 	Distribution   : 199 [+11] regions in total (including 0 [+0] suppressed)
 
- 	  Metric value : Ratio : R-sum : Number of regions
 
- 	             0 : 0.608 : 0.608 : 121 [+5  ]	|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 
- 	             1 : 0.131 : 0.739 :  26 [+4  ]	|||||||||||||
 
- 	             2 : 0.070 : 0.809 :  14 [+0  ]	|||||||
 
- 	             3 : 0.060 : 0.869 :  12 [+2  ]	||||||
 
- 	             4 : 0.015 : 0.884 :   3 [-1  ]	||
 
- 	             5 : 0.015 : 0.899 :   3 [-1  ]	||
 
- 	             6 : 0.005 : 0.905 :   1 [+1  ]	|
 
- 	             7 : 0.015 : 0.920 :   3 [+1  ]	||
 
- 	             8 : 0.015 : 0.935 :   3 [+1  ]	||
 
- 	             9 : 0.010 : 0.945 :   2 [+0  ]	|
 
- 	            10 : 0.010 : 0.955 :   2 [-2  ]	|
 
- 	            11 : 0.005 : 0.960 :   1 [+1  ]	|
 
- 	            12 : 0.005 : 0.965 :   1 [+0  ]	|
 
- 	            13 : 0.005 : 0.970 :   1 [+0  ]	|
 
- 	            16 : 0.005 : 0.975 :   1 [-1  ]	|
 
- 	            17 : 0.005 : 0.980 :   1 [+0  ]	|
 
- 	            18 : 0.010 : 0.990 :   2 [+1  ]	|
 
- 	            20 : 0.005 : 0.995 :   1 [+0  ]	|
 
- 	         36-37 : 0.005 : 1.000 :   1 [+0  ]	|
 
- :: info: Overall metrics for 'std.code.lines:code' metric
 
- 	Average        : 15.9645390071 [-0.815853149771]
 
- 	Minimum        : 0 [+0]
 
- 	Maximum        : 201 [+6]
 
- 	Total          : 4502.0 [+223.0]
 
- 	Distribution   : 282 [+27] regions in total (including 0 [+0] suppressed)
 
- 	  Metric value : Ratio : R-sum : Number of regions
 
- 	           0-1 : 0.053 : 0.053 :  15 [+3  ]	|||||
 
- 	             2 : 0.124 : 0.177 :  35 [+9  ]	||||||||||||
 
- 	             3 : 0.053 : 0.230 :  15 [-3  ]	|||||
 
- 	             4 : 0.060 : 0.291 :  17 [+7  ]	||||||
 
- 	             5 : 0.089 : 0.379 :  25 [+7  ]	|||||||||
 
- 	             6 : 0.060 : 0.440 :  17 [-1  ]	||||||
 
- 	             7 : 0.050 : 0.489 :  14 [-2  ]	|||||
 
- 	           8-9 : 0.074 : 0.564 :  21 [+3  ]	|||||||
 
- 	            10 : 0.035 : 0.599 :  10 [+5  ]	||||
 
- 	            11 : 0.082 : 0.681 :  23 [+4  ]	||||||||
 
- 	         12-13 : 0.043 : 0.723 :  12 [-9  ]	||||
 
- 	         14-15 : 0.039 : 0.762 :  11 [-1  ]	||||
 
- 	         16-18 : 0.028 : 0.791 :   8 [+4  ]	|||
 
- 	         19-22 : 0.039 : 0.830 :  11 [+0  ]	||||
 
- 	         23-26 : 0.039 : 0.869 :  11 [+2  ]	||||
 
- 	         27-32 : 0.028 : 0.897 :   8 [-3  ]	|||
 
- 	         38-50 : 0.025 : 0.922 :   7 [+0  ]	||
 
- 	         51-69 : 0.025 : 0.947 :   7 [+1  ]	||
 
- 	        71-100 : 0.032 : 0.979 :   9 [+2  ]	|||
 
- 	       101-201 : 0.021 : 1.000 :   6 [-1  ]	||
 
- :: info: Directory content:
 
- 	Directory      : .
 
- </pre>
 
-         </section>
 
-         <section id="workflow_view_details_section">
 
-           <h3>Detailed metrics per file/region</h3>
 
-           <p>The same view tool can print detailed metrics per file and per every region in the specified file.
 
-           	In order to get detailed metrics, enumerate files of interest after '--'. For example:</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" view --db-file=boost_1_54_0/metrixpp.db --db-file-prev=boost_1_52_0/metrixpp.db -- ./boost/interprocess/detail/managed_open_or_create_impl.hpp
 
- </pre>
 
-           <p>produces output similar to this (truncated to make the page shorter):</p>
 
-           <pre>
 
- ./interprocess/detail/managed_open_or_create_impl.hpp:302: info: Metrics per 'priv_open_or_create' region
 
- 	Region name    : priv_open_or_create
 
- 	Region type    : function
 
- 	Offsets        : 8314-14526
 
- 	Line numbers   : 301-467
 
- 	Modified       : True
 
- 	std.code.complexity:cyclomatic: 37 [+1]
 
- 	std.code.lines:code: 148 [+4]
 
- </pre>
 
-         </section>
 
-         <section>
 
-           <h3>More about the viewer</h3>
 
-           <p>The 'view' command has got an option to alter the output format. It is possible to get the same data
 
-           	in xml or python dictionary formats. This can be particularly useful for integration of the tool with
 
-           	other applications. For example, an editor may re-collect and show context based metrics when a file is saved.</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" view --db-file=boost_1_54_0/metrixpp.db --format=xml
 
- </pre>
 
-           <p>Check other options of the view tool by executing:</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" view --help
 
- </pre>
 
-         </section>
 
-         <section id="workflow_limit_section">
 
-           <h2>Apply thresholds</h2>
 
-           <p>The viewer shows (above) that there are functions with quite large cyclomatic complexities.
 
-           	 Growth of this metric can be considered as negative trend. The Metrix++ 'limit' tool offers the capability
 
-           	 to manage control over trends by applying limits to metric values.
 
-           	 Exceeded limits could be raised as alarms by quality management and control.</p>
 
-         </section>
 
-         <section id="workflow_limit_hotspots_section">
 
-           <h3>Hotspots</h3>
 
-           <p>The hotspots mode of the limit tool helps to identify top files/regions exceeding a metric threshold.
 
-           	Let's identify the top 3 functions in the boost interprocess library, which exceed a limit of 15 points of
 
-           	cyclomatic complexity:</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" limit --db-file=boost_1_54_0/metrixpp.db --max-limit=std.code.complexity:cyclomatic:15 --hotspots=3
 
- </pre>
 
-           <pre>
 
- ./interprocess/detail/managed_open_or_create_impl.hpp:302: warning: Metric 'std.code.complexity:cyclomatic' for region 'priv_open_or_create' exceeds the limit.
 
- 	Metric name    : std.code.complexity:cyclomatic
 
- 	Region name    : priv_open_or_create
 
- 	Metric value   : 37
 
- 	Modified       : None
 
- 	Change trend   : None
 
- 	Limit          : 15.0
 
- 	Suppressed     : False
 
- ./interprocess/streams/vectorstream.hpp:284: warning: Metric 'std.code.complexity:cyclomatic' for region 'seekoff' exceeds the limit.
 
- 	Metric name    : std.code.complexity:cyclomatic
 
- 	Region name    : seekoff
 
- 	Metric value   : 25
 
- 	Modified       : None
 
- 	Change trend   : None
 
- 	Limit          : 15.0
 
- 	Suppressed     : False
 
- ./interprocess/streams/bufferstream.hpp:174: warning: Metric 'std.code.complexity:cyclomatic' for region 'seekoff' exceeds the limit.
 
- 	Metric name    : std.code.complexity:cyclomatic
 
- 	Region name    : seekoff
 
- 	Metric value   : 23
 
- 	Modified       : None
 
- 	Change trend   : None
 
- 	Limit          : 15.0
 
- 	Suppressed     : False
 
- </pre>
 
-         </section>
 
-         <section id="workflow_limit_control_section">
 
-           <h3>Controlling trends</h3>
 
-           <p>The exit code of the 'limit' tool is equal to the number of warnings printed. This supports use of the tool
 
-           	as a static analysis tool during the software build process. In this case, a non-zero exit code means
 
-           	that there are violations to the agreed standards and it may fail the build. The same command
 
-           	without --hotspots option will print all regions/files exceeding the specified limit:</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" limit --db-file=boost_1_54_0/metrixpp.db --max-limit=std.code.complexity:cyclomatic:15
 
- </pre>
 
-           <h4>Modes to exclude old code from the considiration</h4>
 
-           <p>However, it is likely there are many warnings printed in this mode, especially if very old or legacy code is profiled 
 
-           	against new metrics and coding rules. Although all warnings can be removed 
 
-           	by re-factoring as a big task force activity, it is where many tools are rejected,
 
-           	because it is difficult to justify the initial cost of applying and integrating them.
 
-           	The Metrix++ 'limit' tool has got an option --warn-mode, which helps to overcome this problem.</p>
 
-           <p>--warn-mode=touched encourages re-factoring only for new and modified regions. It enables
 
-           	continuous refactoring. It does not matter how late the rule is applied or the
 
-           	coding standard is modified. It is possible to do it anytime with zero initial investment.
 
-           	For example, applying it to the boost interprocess library for a changes between 1.52 and 1.54 versions
 
-           	results in only 6 warnings:</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" limit --db-file=boost_1_54_0/metrixpp.db --db-file-prev=boost_1_52_0/metrixpp.db --max-limit=std.code.complexity:cyclomatic:15 --warn-mode=touched
 
- </pre>
 
-           <pre>
 
- ./interprocess/detail/managed_open_or_create_impl.hpp:302: warning: Metric 'std.code.complexity:cyclomatic' for region 'priv_open_or_create' exceeds the limit.
 
- 	Metric name    : std.code.complexity:cyclomatic
 
- 	Region name    : priv_open_or_create
 
- 	Metric value   : 37
 
- 	Modified       : True
 
- 	Change trend   : +1
 
- 	Limit          : 15.0
 
- 	Suppressed     : False
 
- ./interprocess/ipc/message_queue.hpp:375: warning: Metric 'std.code.complexity:cyclomatic' for region 'insert_at' exceeds the limit.
 
- 	Metric name    : std.code.complexity:cyclomatic
 
- 	Region name    : insert_at
 
- 	Metric value   : 16
 
- 	Modified       : True
 
- 	Change trend   : 0
 
- 	Limit          : 15.0
 
- 	Suppressed     : False
 
- ./interprocess/mapped_region.hpp:575: warning: Metric 'std.code.complexity:cyclomatic' for region 'mapped_region' exceeds the limit.
 
- 	Metric name    : std.code.complexity:cyclomatic
 
- 	Region name    : mapped_region
 
- 	Metric value   : 18
 
- 	Modified       : True
 
- 	Change trend   : +2
 
- 	Limit          : 15.0
 
- 	Suppressed     : False
 
- ./interprocess/mem_algo/detail/mem_algo_common.hpp:452: warning: Metric 'std.code.complexity:cyclomatic' for region 'priv_allocate_many' exceeds the limit.
 
- 	Metric name    : std.code.complexity:cyclomatic
 
- 	Region name    : priv_allocate_many
 
- 	Metric value   : 20
 
- 	Modified       : True
 
- 	Change trend   : 0
 
- 	Limit          : 15.0
 
- 	Suppressed     : False
 
- ./interprocess/mem_algo/rbtree_best_fit.hpp:787: warning: Metric 'std.code.complexity:cyclomatic' for region 'priv_expand_both_sides' exceeds the limit.
 
- 	Metric name    : std.code.complexity:cyclomatic
 
- 	Region name    : priv_expand_both_sides
 
- 	Metric value   : 17
 
- 	Modified       : True
 
- 	Change trend   : 0
 
- 	Limit          : 15.0
 
- 	Suppressed     : False
 
- ./interprocess/sync/windows/named_sync.hpp:98: warning: Metric 'std.code.complexity:cyclomatic' for region 'open_or_create' exceeds the limit.
 
- 	Metric name    : std.code.complexity:cyclomatic
 
- 	Region name    : open_or_create
 
- 	Metric value   : 18
 
- 	Modified       : True
 
- 	Change trend   : 0
 
- 	Limit          : 15.0
 
- 	Suppressed     : False
 
- </pre>
 
-           <p>If it is challenging or of little benefit to refactor everything touched, 
 
-           	--warn-mode=trends simplifies the control over modified regions and only makes sure
 
-           	that there are no regressions in modified code. In other words, a warning is printed about a modified region/file
 
-           	only if a metric exceeds the specified limit and the value of the metric has got a negative trend due to the modification.
 
-           	It is possible to apply it anytime with zero initial investment and almost zero on-going investment around old code.
 
-           	For example, applying it to the boost interprocess library for a changes between 1.52 and 1.54 versions
 
-           	results in only 2 warnings:</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" limit --db-file=boost_1_54_0/metrixpp.db --db-file-prev=boost_1_52_0/metrixpp.db --max-limit=std.code.complexity:cyclomatic:15 --warn-mode=trend
 
- </pre>
 
-           <pre>
 
- ./interprocess/detail/managed_open_or_create_impl.hpp:302: warning: Metric 'std.code.complexity:cyclomatic' for region 'priv_open_or_create' exceeds the limit.
 
- 	Metric name    : std.code.complexity:cyclomatic
 
- 	Region name    : priv_open_or_create
 
- 	Metric value   : 37
 
- 	Modified       : True
 
- 	Change trend   : +1
 
- 	Limit          : 15.0
 
- 	Suppressed     : False
 
- ./interprocess/mapped_region.hpp:575: warning: Metric 'std.code.complexity:cyclomatic' for region 'mapped_region' exceeds the limit.
 
- 	Metric name    : std.code.complexity:cyclomatic
 
- 	Region name    : mapped_region
 
- 	Metric value   : 18
 
- 	Modified       : True
 
- 	Change trend   : +2
 
- 	Limit          : 15.0
 
- 	Suppressed     : False
 
- </pre>
 
-           <p>--warn-mode=new ignores existing code and ensures that warnings are only about new code.
 
-           	For example, applying it to the boost interprocess library for a changes between 1.52 and 1.54 versions
 
-           	results in 0 warnings, so it shows that the new code is totally compliant with the standard required in the example.</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" limit --db-file=boost_1_54_0/metrixpp.db --db-file-prev=boost_1_52_0/metrixpp.db --max-limit=std.code.complexity:cyclomatic:15 --warn-mode=new
 
- </pre>
 
-           <h4>Suppressions</h4>
 
-           <p>It is possible to suppress warnings. Suppressions are collected from comments in code
 
-              and used by the 'limit' tool to filter out suppressed warnings.
 
-              It supports fine grained control over false-positive warnings, if there are any.</p>
 
-           <p>In order to suppress a warning:</p>
 
-           <ul>
 
-           	<li>per region metrics: put the metrix++ instruction in the comments before the region, for example:</li>
 
-           <pre class="prettyprint linenums">
 
- // This function returns string typed
 
- // representation of a name of a color,
 
- // requested by color's id
 
- // metrix++: suppress std.code.complexity:cyclomatic
 
- std::string getColorName(int color_id)
 
- {
 
- 	switch (color_id)
 
- 	{
 
- 	case COLOR_RED:
 
- 		return std::string("red")
 
- 	case COLOR_GREEN:
 
- 		return std::string("green")
 
- 	case COLOR_BLUE:
 
- 		return std::string("blue")
 
- 	/* and so on */
 
- 	}
 
- }
 
- </pre>
 
-           	<li>per file metrics: put the metrix++ instruction in the comments at the beginning of a file, for example:</li>
 
-           <pre class="prettyprint linenums">
 
- //
 
- // This file does processing of colors and brushes
 
- // Copyright is my company, 2013
 
- // 
 
- // However, it is too long and big file, and there is no time
 
- // to split it into multiple file, so shut up the metrix++ warnings:
 
- // metrix++: suppress std.general:size
 
- //
 
- std::string getColorName(int color_id)
 
- {
 
- 	...
 
- ...
 
- </pre>
 
-           	<li>activate collection of suppressions:</li>
 
-           <pre>
 
- > python "/path/to/metrix++.py" collect --std.suppress
 
- </pre>
 
-           	<li>run the 'limit' tool WITHOUT --disable-suppressions option:</li>
 
-           <pre>
 
- > python "/path/to/metrix++.py" limit ...
 
- </pre>
 
-              </ul>
 
-           <h5>Important notice:</h5>
 
-              <ul><li>The --std.suppress option enables collection of 2 metrics as well: 'std.suppress:count' and 
 
-                 'std.suppress.file:count'. The first is number of suppressions per region.
 
-                 The second is the same but applies to file-scope metrics.
 
-                 It supports management of the number of suppressions.
 
-                 Usually there are no false-positives to suppress with the <strong>right</strong> metric,
 
-                 but there could be exceptions in specific cases. Managing suppressions is about managing exceptions.
 
-                 If there are many exceptional cases, maybe something is wrong with a metric or the application of a metric.
 
-                 Two code examples about colors above do not demonstrate the technically exceptional case,
 
-                 they likely demonstrate a case of a process exception, like "there is no time to do it properly now", or
 
-                 a case of the wrong application of a metric, like "shut up the useless tool". So, be careful.
 
-                 The 'view' tool shows the number of suppressions and its change trends on a per metric basis.</li></ul>
 
-         </section>
 
-         <section id="workflow_other_section">
 
-           <h2>Other applications</h2>
 
-           <h3>Checking data file properties</h3>
 
-           <p>The Metrix++ 'info' tool is helpful to check the properties of a data file, like the settings used to write it,  
 
-           	collected metrics and files processed. For example:</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" info --db-file=boost_1_54_0/metrixpp.db
 
- </pre>
 
-           <pre>
 
- boost_1_54_0/metrixpp.db:: info: Created using plugins and settings:
 
- 	version        : 1.0
 
- 	std.code.complexity:version: 1.1
 
- 	std.code.cpp:version: 1.1
 
- 	std.code.cpp:files: *.c,*.cc,*.cpp,*.cxx,*.h,*.hh,*.hpp,*.hxx
 
- 	std.code.cs:version: 1.0
 
- 	std.code.cs:files: *.cs
 
- 	std.code.java:version: 1.1
 
- 	std.code.java:files: *.java
 
- 	std.code.lines:version: 1.1
 
- test_workflow.db:: info: Collected metrics:
 
- 	std.code.complexity:cyclomatic: 
 
- 	std.code.lines:code: 
 
- :: info: Processed files and checksums:
 
- 	./interprocess/allocators/detail/node_pool.hpp: 0xb099a7c3
 
- 	./interprocess/allocators/detail/node_tools.hpp: 0xaaf5044d
 
- 	./interprocess/anonymous_shared_memory.hpp: 0x2bf06cb0
 
- 	./interprocess/containers/allocation_type.hpp: 0x8e95cda0
 
- 	./interprocess/containers/containers_fwd.hpp: 0xa4d0d9f7
 
- 	./interprocess/containers/deque.hpp: 0x6dbb77af
 
- 	./interprocess/containers/flat_map.hpp: 0x6750338c
 
- 	...
 
- </pre>
 
-           <h3>Exporting results</h3>
 
-           <p>The Metrix++ 'export' tool exports data files to csv formated files. For example:</p>
 
-           <pre>
 
- > python "/path/to/metrix++.py" export --db-file=boost_1_54_0/metrixpp.db > boost_1_54_0/metrixpp.csv
 
- </pre>
 
-           <pre>
 
- file,region,type,modified,line start,line end,std.code.complexity:cyclomatic,std.code.lines:code
 
- ./interprocess/allocators/detail/node_pool.hpp,__global__,global,,1,110,,0
 
- ./interprocess/allocators/detail/node_pool.hpp,boost,namespace,,33,105,,2
 
- ./interprocess/allocators/detail/node_pool.hpp,interprocess,namespace,,34,104,,2
 
- ./interprocess/allocators/detail/node_pool.hpp,ipcdetail,namespace,,35,103,,4
 
- ./interprocess/allocators/detail/node_pool.hpp,SegmentManager,class,,39,72,,16
 
- ...
 
- </pre>
 
-           <p>Files with csv format can be opened by applications, like Microsoft Office Excel, with advanced analysis capabilities.
 
-           	For example, to draw this distribution graph:</p>
 
-           <p align="center"><img src="assets/img/piechart.png"/></p>
 
-           <p>It is not recommended to use the export tool to implement custom post-analysis Metrix++ extensions.
 
-           	  The main reason is that granted backward compatibility support for csv columns is not granted.
 
-           	  Another main reason is that
 
-           	  exporting is relatively slow process. It is recommended to use Metrix++ extensions API instead.</p>
 
-         </section>
 
-         <section id="extend_section">
 
-           <div class="page-header">
 
-             <h1>Create plugin</h1>
 
-             <p>There are 3 types of plugins considered in this chapter:</p>
 
-             <ul>
 
-             	<li>Metric plugin</li>
 
-             	<li>Language parser</li>
 
-             	<li>Post-processing / Analysis tool</li>
 
-             </ul>
 
-             <p>Tutorial for metric plugin is generic at the beginning and large portion of this is applied to
 
-             	all other plugins. You need to know python and python regular expressions library to write Metrix++ extensions.</p>
 
-           </div>
 
-           <h2>Metric plugin</h2>
 
-           <p>The tutorial will explain how to create a plugin to count magic numbers in source code.
 
-              It will be relatively simple at first and will be extended with additional configuration
 
-              options and smarter counting logic.</p>
 
-           <h4>Create placeholder for new plugin</h4>
 
-           <ol>
 
-              <li>All plugins are loaded by Metrix++ from standard places within the tool installation directory and
 
-                  from custom places specified in the METRIXPLUSPLUS_PATH environment variable.
 
-                  METRIXPLUSPLUS_PATH has got the same format as system PATH environment variable.
 
-                  So, the first step in plugin development is to set the METRIXPLUSPLUS_PATH to point out to
 
-                  the directory (or directories) where plugin is located.</li>
 
-              <li>Create new python package 'myext', python lib 'magic.py' and 'magic.ini' file.</li>
 
-              <pre>
 
- + working_directory (set in METRIXPLUSPLUS_PATH variable)
 
- \--+ myext
 
-    \--- __init__.py
 
-    \--- magic.py
 
-    \--- magic.ini
 
- </pre>
 
-             <li>__init__.py is empty file to make myext considered by python as a package.</li>
 
-             <li>Edit magic.py to have the following content:
 
-              <pre class="prettyprint linenums">
 
- import mpp.api
 
- class Plugin(mpp.api.Plugin):
 
-     
 
-     def initialize(self):
 
-         print "Hello world"
 
- </pre>
 
-             mpp.api package include Metrix++ API classes. mpp.api.Plugin is the base class, which can be loaded
 
-             by Metrix++ engine and does nothing by default. In the code sample above it is extended to print
 
-             "Hello world" on initialization.</li>
 
-             <li>Edit magic.ini to have the following content:
 
-              <pre class="prettyprint linenums">
 
- [Plugin]
 
- version: 1.0
 
- package: myext
 
- module:  magic
 
- class:   Plugin
 
- depends: None
 
- actions: collect
 
- enabled: True
 
- </pre>
 
-             This file is a manifest for Metrix++ plugin loader. The fields in Plugin section are:
 
-             <dl class="dl-horizontal">
 
-             	<dt>version</dt>
 
-             	<dd>a string representing the version, step up it every time when behaviour of a plugin
 
-             		or backward compatibility in api or data scope is changed</dd>
 
-             	<dt>package</dt>
 
-             	<dd>python package name where to load from</dd>
 
-             	<dt>module</dt>
 
-             	<dd>python module name (filename of *.py file) to load</dd>
 
-             	<dt>class</dt>
 
-             	<dd>name of a plugin class to instanciate</dd>
 
-             	<dt>depends</dt>
 
-             	<dd>list of plugin names to load, if it this plugin is loaded</dd>
 
-             	<dt>actions</dt>
 
-             	<dd>list of Metrix++ actions affected by this plugin</dd>
 
-             	<dt>enabled</dt>
 
-             	<dd>True or False, working status of a plugin</dd>
 
-             </dl>
 
-             </li>
 
-             <li>Now run Metrix++ to see how this new plugin works:</li>
 
-           <pre>> python "/path/to/metrix++.py" collect</pre>
 
-           <pre>Hello world</pre>
 
-           </ol>
 
-           <h4>Toogle option for the plugin</h4>
 
-           <ol>
 
-              <li>It is recommended to follow the convention for all plugins: 'run only if enabled'.
 
-              	So, let's extend the magic.py file to make it configurable
 
-              <pre class="prettyprint linenums">
 
- import mpp.api
 
- class Plugin(mpp.api.Plugin,
 
-              # make this instance configurable...
 
-              mpp.api.IConfigurable):
 
-     # ... and implement 2 interfaces
 
-     
 
-     def declare_configuration(self, parser):
 
-         parser.add_option("--myext.magic.numbers", "--mmn",
 
-             action="store_true", default=False,
 
-             help="Enables collection of magic numbers metric [default: %default]")
 
-         
 
-     def configure(self, options):
 
-         self.is_active_numbers = options.__dict__['myext.magic.numbers']
 
-     
 
-     def initialize(self):
 
-         # use configuration option here
 
-         if self.is_active_numbers == True:
 
-             print "Hello world"
 
- </pre>
 
-             parser argument is an instance of optparse.OptionParser class. It has got an extension to
 
-             accept multiple options of the same argument. Check std.tools.limit to see how to declare multiopt options, if you need.</li>
 
-             <li>Now run Metrix++ to see how this works:</li>
 
-           <pre>> python "/path/to/metrix++.py" collect --myext.magic.numbers</pre>
 
-           <pre>Hello world</pre>
 
-           </ol>
 
-           <h4>Subscribe to notifications from parent plugins (or code parsers)</h4>
 
-           <ol>
 
-              <li>Every plugin works in a callback functions called by parent plugins.
 
-              	Callback receives a reference to parent plugin, data object where to store metrics data,
 
-              	and a flag indicating if there are changes in file or parent's settings since the previous collection.</li>
 
-              <pre class="prettyprint linenums">
 
- import mpp.api
 
- class Plugin(mpp.api.Plugin,
 
-              mpp.api.IConfigurable,
 
-              # declare that it can subscribe on notifications
 
-              mpp.api.Child):
 
-     
 
-     def declare_configuration(self, parser):
 
-         parser.add_option("--myext.magic.numbers", "--mmn",
 
-             action="store_true", default=False,
 
-             help="Enables collection of magic numbers metric [default: %default]")
 
-     
 
-     def configure(self, options):
 
-         self.is_active_numbers = options.__dict__['myext.magic.numbers']
 
-     
 
-     def initialize(self):
 
-         if self.is_active_numbers == True:
 
-             # subscribe to notifications from all code parsers
 
-             self.subscribe_by_parents_interface(mpp.api.ICode, 'callback')
 
-     # parents (code parsers) will call the callback declared
 
-     def callback(self, parent, data, is_updated):
 
-         print parent.get_name(), data.get_path(), is_updated
 
- </pre>
 
-             <li>Now run Metrix++ to see how this works. Try to do iterative scans (--db-file-prev option) to see how the
 
-             	state of arguments is changed</li>
 
-           <pre>> python "/path/to/metrix++.py" collect --myext.magic.numbers</pre>
 
-           <pre>std.code.cpp ./test.cpp True</pre>
 
-           </ol>
 
-           <h4>Implement simple metric based on regular expression pattern</h4>
 
-           <ol>
 
-              <li>Callback may execute counting, searcing and additional parsing and store results, using data argument.
 
-              	'data' argument is an instance of mpp.api.FileData class.
 
-              	However, most metrics can be implemented
 
-              	simplier, if mpp.api.MetricPluginMixin routines are used. MetricPluginMixin implements
 
-              	declarative style for metrics based on searches by regular expression. It
 
-              	cares about initialisation of database fields and properties.
 
-              	It implements default callback which counts number of matches by regular expression for all
 
-              	active declared metrics. So, let's utilise that:
 
-              	</li>
 
-              <pre class="prettyprint linenums">
 
- import mpp.api
 
- import re
 
- class Plugin(mpp.api.Plugin,
 
-              mpp.api.IConfigurable,
 
-              mpp.api.Child,
 
-              # reuse by inheriting standard metric facilities
 
-              mpp.api.MetricPluginMixin):
 
-     
 
-     def declare_configuration(self, parser):
 
-         parser.add_option("--myext.magic.numbers", "--mmn",
 
-             action="store_true", default=False,
 
-             help="Enables collection of magic numbers metric [default: %default]")
 
-     
 
-     def configure(self, options):
 
-         self.is_active_numbers = options.__dict__['myext.magic.numbers']
 
-     
 
-     def initialize(self):
 
-         # declare metric rules
 
-         self.declare_metric(
 
-             self.is_active_numbers, # to count if active in callback
 
-             self.Field('numbers', int), # field name and type in the database
 
-             re.compile(r'''[0-9]+'''), # pattern to search
 
-             marker_type_mask=mpp.api.Marker.T.CODE, # search in code
 
-             region_type_mask=mpp.api.Region.T.ANY) # search in all types of regions
 
-         
 
-         # use superclass facilities to initialize everything from declared fields
 
-         super(Plugin, self).initialize(fields=self.get_fields())
 
-         
 
-         # subscribe to all code parsers if at least one metric is active
 
-         if self.is_active() == True:
 
-             self.subscribe_by_parents_interface(mpp.api.ICode)
 
- </pre>
 
-             <li>Now run Metrix++ to count numbers in code files.</li>
 
-           <pre>> python "/path/to/metrix++.py" collect --myext.magic.numbers</pre>
 
-             <li>Now view the results. At this stage it is fully working simple metric.</li>
 
-           <pre>> python "/path/to/metrix++.py" view</pre>
 
-           <pre>
 
- :: info: Overall metrics for 'myext.magic:numbers' metric
 
- 	Average        : 2.75
 
- 	Minimum        : 0
 
- 	Maximum        : 7
 
- 	Total          : 11.0
 
- 	Distribution   : 4 regions in total (including 0 suppressed)
 
- 	  Metric value : Ratio : R-sum : Number of regions
 
- 	             0 : 0.250 : 0.250 : 1	|||||||||||||||||||||||||
 
- 	             1 : 0.250 : 0.500 : 1	|||||||||||||||||||||||||
 
- 	             3 : 0.250 : 0.750 : 1	|||||||||||||||||||||||||
 
- 	             7 : 0.250 : 1.000 : 1	|||||||||||||||||||||||||
 
- :: info: Directory content:
 
- 	Directory      : .
 
- </pre>
 
-           </ol>
 
-           <h4>Extend regular expression incremental counting by smarter logic</h4>
 
-           <ol>
 
-              <li>At this stage the metric counts every number in source code.
 
-                  However, we indent to spot only 'magic' numbers. Declared constant
 
-                  is not a magic number, so it is better to exclude constants from counting.
 
-                  It is easy to change default counter behaviour by implementing 
 
-                  a function with name '_<metric_name>_count'. </li>
 
-              <pre class="prettyprint linenums">
 
- import mpp.api
 
- import re
 
- class Plugin(mpp.api.Plugin,
 
-              mpp.api.IConfigurable,
 
-              mpp.api.Child,
 
-              mpp.api.MetricPluginMixin):
 
-     
 
-     def declare_configuration(self, parser):
 
-         parser.add_option("--myext.magic.numbers", "--mmn",
 
-             action="store_true", default=False,
 
-             help="Enables collection of magic numbers metric [default: %default]")
 
-     
 
-     def configure(self, options):
 
-         self.is_active_numbers = options.__dict__['myext.magic.numbers']
 
-     
 
-     def initialize(self):
 
-         # improve pattern to find declarations of constants
 
-         pattern_to_search = re.compile(
 
-             r'''(const\s+([_a-zA-Z][_a-zA-Z0-9]*\s+)+[=]\s*)?[-+]?[0-9]+''')
 
-         self.declare_metric(self.is_active_numbers,
 
-                             self.Field('numbers', int),
 
-                             pattern_to_search, # and use it here
 
-                             marker_type_mask=mpp.api.Marker.T.CODE,
 
-                             region_type_mask=mpp.api.Region.T.ANY)
 
-         
 
-         super(Plugin, self).initialize(fields=self.get_fields())
 
-         
 
-         if self.is_active() == True:
 
-             self.subscribe_by_parents_interface(mpp.api.ICode)
 
-     
 
-     # implement custom counter behavior:
 
-     # increments counter by 1 only if single number spotted,
 
-     # but not declaration of a constant
 
-     def _numbers_count(self, alias, data, region, marker, match, count, counter_data):
 
-         if match.group(0).startswith('const'):
 
-             return count
 
-         return count + 1
 
- </pre>
 
-              <li>Initialy counter is initialized by zero, but it is possible to 
 
-              	change it as well by implementing a function with name '_<metric_name>_count_initialize'.
 
-              	Plugin we are implementing does not require this.</li>
 
-             <li>Now run Metrix++ to collect and view the results.</li>
 
-           <pre>> python "/path/to/metrix++.py" collect --myext.magic.numbers</pre>
 
-           <pre>> python "/path/to/metrix++.py" view</pre>
 
-           </ol>
 
-           <h4>Language specific regular expressions</h4>
 
-           <ol>
 
-              <li>In the previous step we added matching of constants assuming that identifiers
 
-              	may have symbols '_', 'a-z', 'A-Z' and '0-9'. It is true for C++ but it is not complete for Java.
 
-              	Java identifier may have '$' symbol in the identifier. So, let's add language specific pattern
 
-              	in the declaration of the metric:</li>
 
-              <pre class="prettyprint linenums">
 
- import mpp.api
 
- import re
 
- class Plugin(mpp.api.Plugin,
 
-              mpp.api.IConfigurable,
 
-              mpp.api.Child,
 
-              mpp.api.MetricPluginMixin):
 
-     
 
-     def declare_configuration(self, parser):
 
-         parser.add_option("--myext.magic.numbers", "--mmn",
 
-             action="store_true", default=False,
 
-             help="Enables collection of magic numbers metric [default: %default]")
 
-     
 
-     def configure(self, options):
 
-         self.is_active_numbers = options.__dict__['myext.magic.numbers']
 
-     
 
-     def initialize(self):
 
-         # specialized pattern for java
 
-         pattern_to_search_java = re.compile(
 
-             r'''(const\s+([_$a-zA-Z][_$a-zA-Z0-9]*\s+)+[=]\s*)?[-+]?[0-9]+''')
 
-         # pattern for C++ and C# languages
 
-         pattern_to_search_cpp_cs = re.compile(
 
-             r'''(const\s+([_a-zA-Z][_a-zA-Z0-9]*\s+)+[=]\s*)?[-+]?[0-9]+''')
 
-         # pattern for all other languages
 
-         pattern_to_search = re.compile(
 
-             r'''[0-9]+''')
 
-         self.declare_metric(self.is_active_numbers,
 
-                             self.Field('numbers', int),
 
-                             # dictionary of patterns instead of a single one
 
-                             {
 
-                              'std.code.java': pattern_to_search_java,
 
-                              'std.code.cpp': pattern_to_search_cpp_cs,
 
-                              'std.code.cs': pattern_to_search_cpp_cs,
 
-                              '*': pattern_to_search
 
-                             },
 
-                             marker_type_mask=mpp.api.Marker.T.CODE,
 
-                             region_type_mask=mpp.api.Region.T.ANY)
 
-         
 
-         super(Plugin, self).initialize(fields=self.get_fields())
 
-         
 
-         if self.is_active() == True:
 
-             self.subscribe_by_parents_interface(mpp.api.ICode)
 
-     def _numbers_count(self, alias, data, region, marker, match, count, counter_data):
 
-         if match.group(0).startswith('const'):
 
-             return count
 
-         return count + 1
 
- </pre>
 
-              <li>Keys in the dictionary of patterns are names of parent plugins (references to code parsers).
 
-              	The key '*' refers to any parser.</li>
 
-             <li>Now run Metrix++ to collect and view the results.</li>
 
-           <pre>> python "/path/to/metrix++.py" collect --myext.magic.numbers</pre>
 
-           <pre>> python "/path/to/metrix++.py" view</pre>
 
-           </ol>
 
-           <h4>Store only non-zero metric values</h4>
 
-           <ol>
 
-              <li>Most functions have the metric, which we are implemneting, equal to zero.
 
-              	However, we are interested in finding code blocks having this metric greater than zero.
 
-              	Zeros consumes the space in the data file. So, we can optimise the size of a data file,
 
-              	if we exclude zero metric values. Let's declare this behavior for the metric.</li>
 
-              <pre class="prettyprint linenums">
 
- import mpp.api
 
- import re
 
- class Plugin(mpp.api.Plugin,
 
-              mpp.api.IConfigurable,
 
-              mpp.api.Child,
 
-              mpp.api.MetricPluginMixin):
 
-     
 
-     def declare_configuration(self, parser):
 
-         parser.add_option("--myext.magic.numbers", "--mmn",
 
-             action="store_true", default=False,
 
-             help="Enables collection of magic numbers metric [default: %default]")
 
-     
 
-     def configure(self, options):
 
-         self.is_active_numbers = options.__dict__['myext.magic.numbers']
 
-     
 
-     def initialize(self):
 
-         pattern_to_search_java = re.compile(
 
-             r'''(const\s+([_$a-zA-Z][_$a-zA-Z0-9]*\s+)+[=]\s*)?[-+]?[0-9]+''')
 
-         pattern_to_search_cpp_cs = re.compile(
 
-             r'''(const\s+([_a-zA-Z][_a-zA-Z0-9]*\s+)+[=]\s*)?[-+]?[0-9]+''')
 
-         pattern_to_search = re.compile(
 
-             r'''[0-9]+''')
 
-         self.declare_metric(self.is_active_numbers,
 
-                             self.Field('numbers', int,
 
-                                 # optimize the size of datafile:
 
-                                 # store only non-zero results
 
-                                 non_zero=True),
 
-                             {
 
-                              'std.code.java': pattern_to_search_java,
 
-                              'std.code.cpp': pattern_to_search_cpp_cs,
 
-                              'std.code.cs': pattern_to_search_cpp_cs,
 
-                              '*': pattern_to_search
 
-                             },
 
-                             marker_type_mask=mpp.api.Marker.T.CODE,
 
-                             region_type_mask=mpp.api.Region.T.ANY)
 
-         
 
-         super(Plugin, self).initialize(fields=self.get_fields())
 
-         
 
-         if self.is_active() == True:
 
-             self.subscribe_by_parents_interface(mpp.api.ICode)
 
-     def _numbers_count(self, alias, data, region, marker, match, count, counter_data):
 
-         if match.group(0).startswith('const'):
 
-             return count
 
-         return count + 1
 
- </pre>
 
-             <li>Now run Metrix++ to collect and view the results.</li>
 
-           <pre>> python "/path/to/metrix++.py" collect --myext.magic.numbers</pre>
 
-           <pre>> python "/path/to/metrix++.py" view</pre>
 
-           </ol>
 
-           <h4>Additional per metric configuration options</h4>
 
-           <ol>
 
-              <li>It is typical that most numbers counted by the metric are equal to 0, -1 or 1.
 
-              	They are not necessary magic numbers. 0 or 1 are typical variable initializers.
 
-              	-1 is a typical negative return code. So, let's implement simplified version of the metric,
 
-              	which does not count 0, -1 and 1, if the specific new option is set.</li>
 
-              <pre class="prettyprint linenums">
 
- import mpp.api
 
- import re
 
- class Plugin(mpp.api.Plugin,
 
-              mpp.api.IConfigurable,
 
-              mpp.api.Child,
 
-              mpp.api.MetricPluginMixin):
 
-     
 
-     def declare_configuration(self, parser):
 
-         parser.add_option("--myext.magic.numbers", "--mmn",
 
-             action="store_true", default=False,
 
-             help="Enables collection of magic numbers metric [default: %default]")
 
-         # Add new option
 
-         parser.add_option("--myext.magic.numbers.simplier", "--mmns",
 
-             action="store_true", default=False,
 
-             help="Is set, 0, -1 and 1 numbers are not counted [default: %default]")
 
-     
 
-     def configure(self, options):
 
-         self.is_active_numbers = options.__dict__['myext.magic.numbers']
 
-         # remember the option here
 
-         self.is_active_numbers_simplier = options.__dict__['myext.magic.numbers.simplier']
 
-     
 
-     def initialize(self):
 
-         pattern_to_search_java = re.compile(
 
-             r'''(const\s+([_$a-zA-Z][_$a-zA-Z0-9]*\s+)+[=]\s*)?[-+]?[0-9]+''')
 
-         pattern_to_search_cpp_cs = re.compile(
 
-             r'''(const\s+([_a-zA-Z][_a-zA-Z0-9]*\s+)+[=]\s*)?[-+]?[0-9]+''')
 
-         pattern_to_search = re.compile(
 
-             r'''[0-9]+''')
 
-         self.declare_metric(self.is_active_numbers,
 
-                             self.Field('numbers', int,
 
-                                 non_zero=True),
 
-                             {
 
-                              'std.code.java': pattern_to_search_java,
 
-                              'std.code.cpp': pattern_to_search_cpp_cs,
 
-                              'std.code.cs': pattern_to_search_cpp_cs,
 
-                              '*': pattern_to_search
 
-                             },
 
-                             marker_type_mask=mpp.api.Marker.T.CODE,
 
-                             region_type_mask=mpp.api.Region.T.ANY)
 
-         
 
-         super(Plugin, self).initialize(fields=self.get_fields(),
 
-             # remember option settings in data file properties
 
-             # in order to detect changes in settings on iterative re-run
 
-             properties=[self.Property('number.simplier', self.is_active_numbers_simplier)])
 
-         
 
-         if self.is_active() == True:
 
-             self.subscribe_by_parents_interface(mpp.api.ICode)
 
-     def _numbers_count(self, alias, data, region, marker, match, count, counter_data):
 
-         if (match.group(0).startswith('const') or
 
-             # use new option to exclude 0 and 1 numbers
 
-             (self.is_active_numbers_simplier == True and
 
-              match.group(0) in ['0', '1', '-1', '+1'])):
 
-             return count
 
-         return count + 1
 
- </pre>
 
-             <li>Now run Metrix++ to collect and view the results.</li>
 
-           <pre>> python "/path/to/metrix++.py" collect --myext.magic.numbers</pre>
 
-           <pre>> python "/path/to/metrix++.py" view</pre>
 
-           <pre>
 
- :: info: Overall metrics for 'myext.magic:numbers' metric
 
- 	Average        : 2.5 (excluding zero metric values)
 
- 	Minimum        : 2
 
- 	Maximum        : 3
 
- 	Total          : 5.0
 
- 	Distribution   : 2 regions in total (including 0 suppressed)
 
- 	  Metric value : Ratio : R-sum : Number of regions
 
- 	             2 : 0.500 : 0.500 : 1	||||||||||||||||||||||||||||||||||||||||||||||||||
 
- 	             3 : 0.500 : 1.000 : 1	||||||||||||||||||||||||||||||||||||||||||||||||||
 
- :: info: Directory content:
 
- 	Directory      : .
 
- </pre>
 
-           </ol>
 
-           <h4>Summary</h4>
 
-           <p>We have finished with the tutorial. The tutorial explained how to implement simple and advanced metric plugins.
 
-           	We used built-in Metrix++ base classes. If you need to more advanced plugin capabilities,
 
-           	override in your plugin class functions inherited from mpp.api base classes. Check code of standard plugins
 
-           	to learn more techniques.</p>
 
-           <p></p>
 
-           <h2>Analysis tool plugin</h2>
 
-           <p>This tutorial will explain how to build custom Metrix++ command, which is bound to custom post-analysis tool.
 
-           	We will implement the tool, which identifies all new and changed regions and counts number of added lines.
 
-           	We skip calculating number of deleted lines, but it is easy to extend from what we get finally in the tutorial.</p>
 
-           <h4>New Metrix++ command / action</h4>
 
-           <ol>
 
-              <li>As in the tutorial for metric plugin, set the environment and 
 
-              	create new python package 'myext', python lib 'compare.py' and 'compare.ini' file.</li>
 
-              <pre>
 
- + working_directory (set in METRIXPLUSPLUS_PATH variable)
 
- \--+ myext
 
-    \--- __init__.py
 
-    \--- compare.py
 
-    \--- compare.ini
 
- </pre>
 
-             <li>__init__.py is empty file to make myext considered by python as a package.</li>
 
-             <li>Edit compare.py to have the following content:
 
-              <pre class="prettyprint linenums">
 
- import mpp.api
 
- class Plugin(mpp.api.Plugin, mpp.api.IRunable):
 
-     
 
-     def run(self, args):
 
-         print args
 
-         return 0
 
- </pre>
 
-             Inheritance from mpp.api.IRunable declares that the plugin is runable and requires implementation of 'run' interface.</li>
 
-             <li>Edit compare.ini to have the following content:
 
-              <pre class="prettyprint linenums">
 
- [Plugin]
 
- version: 1.0
 
- package: myext
 
- module:  compare
 
- class:   Plugin
 
- depends: None
 
- actions: compare
 
- enabled: True
 
- </pre>
 
-             This file is a manifest for Metrix++ plugin loader. Actions field has got new value 'compare'.
 
-             Metrix++ engine will automatically pick this action and will add it to the list of available commands.
 
-             This plugin will be loaded on 'compare' action.
 
-             </li>
 
-             <li>Now run Metrix++ to see how this new plugin works:</li>
 
-           <pre>> python "/path/to/metrix++.py" compare -- path1 path2 path3</pre>
 
-           <pre>["path1", "path2", "path3"]</pre>
 
-           </ol>
 
-           <h4>Access data file loader and its' interfaces</h4>
 
-           <ol>
 
-              <li>By default, all post-analysis tools have got --db-file and --db-file-prev options. It is 
 
-              	because 'mpp.dbf' plugin is loaded for any action, including our new one 'compare'. In order to continue
 
-              	the tutorial, we need to have 2 data files with 'std.code.lines:total' metric collected.
 
-              	So, write to files by running:</li>
 
-              <pre>cd my_project_version_1
 
- > python "/path/to/metrix++.py" collect --std.code.lines.total</pre>
 
-              <pre>cd my_project_version_2
 
- > python "/path/to/metrix++.py" collect --std.code.lines.total</pre>
 
-             <li>Edit compare.py file to get the loader and iterate collected file paths:</li>
 
-              <pre class="prettyprint linenums">
 
- import mpp.api
 
- # load common utils for post processing tools
 
- import mpp.utils
 
- class Plugin(mpp.api.Plugin, mpp.api.IRunable):
 
-     
 
-     def run(self, args):
 
-         # get data file reader using standard metrix++ plugin
 
-         loader = self.get_plugin('mpp.dbf').get_loader()
 
-         
 
-         # iterate and print file length for every path in args
 
-         exit_code = 0
 
-         for path in (args if len(args) > 0 else [""]):
 
-             file_iterator = loader.iterate_file_data(path)
 
-             if file_iterator == None:
 
-                 mpp.utils.report_bad_path(path)
 
-                 exit_code += 1
 
-                 continue
 
-             for file_data in file_iterator:
 
-                 print file_data.get_path()
 
-         return exit_code
 
- </pre>
 
-             <li>Now run Metrix++ to see how it works:</li>
 
-           <pre>> python "/path/to/metrix++.py" compare --db-file=my_project_version_2/metrixpp.db --db-file-prev=my_project_version_1/metrixpp.db</pre>
 
-           </ol>
 
-           <h4>Identify added, modified files/regions and read metric data</h4>
 
-           <ol>
 
-             <li>Let's extend the logic of the tool to compare files and regions, read 'std.code.lines:total' metric
 
-             	and calcuate the summary of number of added lines. mpp.utils.FileRegionsMatcher is helper class
 
-             	which does matching and comparison of regions for 2 given mpp.api.FileData objects.</li>
 
-              <pre class="prettyprint linenums">
 
- import mpp.api
 
- import mpp.utils
 
- import mpp.cout
 
- class Plugin(mpp.api.Plugin, mpp.api.IRunable):
 
-     
 
-     def run(self, args):
 
-         loader = self.get_plugin('mpp.dbf').get_loader()
 
-         # get previous db file loader
 
-         loader_prev = self.get_plugin('mpp.dbf').get_loader_prev()
 
-         
 
-         exit_code = 0
 
-         for path in (args if len(args) > 0 else [""]):
 
-             added_lines = 0
 
-             file_iterator = loader.iterate_file_data(path)
 
-             if file_iterator == None:
 
-                 mpp.utils.report_bad_path(path)
 
-                 exit_code += 1
 
-                 continue
 
-             for file_data in file_iterator:
 
-                 added_lines += self._compare_file(file_data, loader, loader_prev)
 
-             mpp.cout.notify(path, '', mpp.cout.SEVERITY_INFO,
 
-                             "Change trend report",
 
-                             [('Added lines', added_lines)])
 
-         return exit_code
 
-     def _compare_file(self, file_data, loader, loader_prev):
 
-         # compare file with previous and return number of new lines
 
-         file_data_prev = loader_prev.load_file_data(file_data.get_path())
 
-         if file_data_prev == None:
 
-             return self._sum_file_regions_lines(file_data)
 
-         elif file_data.get_checksum() != file_data_prev.get_checksum():
 
-             return self._compare_file_regions(file_data, file_data_prev)
 
-     def _sum_file_regions_lines(self, file_data):
 
-         # just sum up the metric for all regions
 
-         result = 0
 
-         for region in file_data.iterate_regions():
 
-             result += region.get_data('std.code.lines', 'total')
 
-     
 
-     def _compare_file_regions(self, file_data, file_data_prev):
 
-         # compare every region with previous and return number of new lines
 
-         matcher = mpp.utils.FileRegionsMatcher(file_data, file_data_prev)
 
-         result = 0
 
-         for region in file_data.iterate_regions():
 
-             if matcher.is_matched(region.get_id()) == False:
 
-                 # if added region, just add the lines
 
-                 result += region.get_data('std.code.lines', 'total')
 
-             elif matcher.is_modified(region.get_id()):
 
-                 # if modified, add the difference in lines
 
-                 region_prev = file_data_prev.get_region(
 
-                     matcher.get_prev_id(region.get_id()))
 
-                 result += (region.get_data('std.code.lines', 'total') -
 
-                            region_prev.get_data('std.code.lines', 'total'))
 
-         return result
 
- </pre>
 
-             <li>Now run Metrix++ to see how it works:</li>
 
-           <pre>> python "/path/to/metrix++.py" compare --db-file=my_project_version_2/metrixpp.db --db-file-prev=my_project_version_1/metrixpp.db</pre>
 
-           <pre>
 
- :: info: Change trend report
 
- 	Added lines    : 7
 
- </pre>
 
-           </ol>
 
-           <h4>Summary</h4>
 
-           <p>We have finished with the tutorial. The tutorial explained how to read Metrix++ data files and 
 
-           	implement custom post-processing tools. Even if some existing Metrix++ code requires clean-up and refactoring,
 
-           	check code of standard tool plugins to learn more techniques.</p>
 
-           <h2>Language parser plugin</h2>
 
-                 <p>Unfortunately, there is no good documentation at this stage for this part.
 
-                 Briefly, if metric plugin counts and stores data into FileData object,
 
-                 tool plugin reads this data, language plugin construct the original structure of
 
-                 FileData object. The orginal structure includes regions (like functions, classes, etc.)
 
-                  and markers (like comments, strings, preprocessor, etc.). 
 
-                  Check code of existing parsers.</p>
 
-                 <ul>
 
-                   <li>a language parser plugin is registered in the same way as a metric plugin</li>
 
-                   <li>it registers parser's callback in 'std.tools.collect' plugin</li>
 
-                   <li>parses a file in a callback, called by 'std.tools.collect'</li>
 
-                   <li>parser needs to identify markers  and regions 
 
-                     and tell about this to file data object passed as an
 
-                     argument for the callback.</li>
 
-                 </ul>
 
-                 <p>There are useful options and tools avaialble for
 
-                 trobuleshooting purposes during development:</p>
 
-                 <ul>
 
-                   <li>metrix++.py debug generates html code showing parsed code structures and their boundaries</li>
 
-                   <li>--nest-regions for view tool forces the viewer to indent subregions.</li>
 
-                   <li>--general.log-level option is available for any command and is helpful to trace execution.</li>
 
-                 </ul>
 
-                 <p>Finally, if there are any questions or enquires, please,
 
-                 feel free to <a href="https://sourceforge.net/p/metrixplusplus/tickets/new/">submit new question</a>.</p>
 
-         </section>
 
-         <section id="contribute_section">
 
-           <div class="page-header">
 
-             <h1>Feeback and contribute</h1>
 
-           </div>
 
-           <p>Now it is your turn. There are multiple ways how you can contribute and help to improve and progress Metrix++ project:</p>
 
-           <ul>
 
-           	<li>Try Metrix++ and <a href="https://sourceforge.net/projects/metrixplusplus/reviews/new">post review</a></li>
 
-           	<li><a href="https://sourceforge.net/p/metrixplusplus/tickets/new/">Submit new feature request or bug report</a></li>
 
-           	<li><a href="https://sourceforge.net/p/metrixplusplus/tickets/new/">Ask a question</a></li>
 
-           	<li>Share your patch files and ideas, colloborate by email to 
 
-           		<a href="mailto:avkonst@users.sourceforge.net?subject=Metrix%2B%2B Project Request">project administrator</a></li>
 
-           	<li>Create and publish your plugin. 
 
-           		<a href="mailto:avkonst@users.sourceforge.net?subject=Metrix%2B%2B Plugin Reference">Request to refer</a>
 
-           			 to it from Metrix++ project space.</li>
 
-           	<li><a href="mailto:avkonst@users.sourceforge.net?subject=Metrix%2B%2B Plugin Submission">Submit your plugin</a>
 
-           		 to include to the standard set</li>
 
-           	<li>... and consider to
 
-           		<a href="mailto:avkonst@users.sourceforge.net?subject=Metrix%2B%2B Join Request">join the project</a>!</li>
 
-           </ul>
 
-         </section>
 
-       </div> <!-- end for sections -->
 
-     </div></div> <!-- end for row and container -->
 
-     <!-- Footer
 
-     ================================================== -->
 
-     <footer class="footer">
 
-       <div class="container">
 
-       	<div class="row">
 
-       		<div class="span3">
 
-       			<p><a href="http://sourceforge.net/projects/metrixplusplus/"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=275605&type=3"
 
- 		        	alt="Get Metrix++ at SourceForge.net. Fast, secure and Free Open Source software downloads" border="0"></a></p>
 
- 		        <p>·</p>
 
- 		        <p>· ·<script type="text/javascript" src="http://www.ohloh.net/p/485947/widgets/project_users_logo.js"></script></p>
 
- 		        <p><a href="http://freecode.com/projects/metrix"><img src="assets/img/fm_logo.png" width="130"></a></p>
 
- 		        <p>·</p>
 
-       		</div>
 
-       		<div class="span9">
 
- 		        <p>Copyright <strong>©</strong> 2009 - 2013, <a href="mailto:avkonst@users.sourceforge.net"><span class="normalImportance">Metrix++</span> Project</a></p>
 
- 		        <p>Code licensed under <a href="http://www.gnu.org/licenses/gpl.txt" target="_blank">GPL 3.0</a>, documentation under <a href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.</p>
 
- 		        <ul class="footer-links">
 
- 		          <li><a href="https://sourceforge.net/p/metrixplusplus/tickets/new/">Ask question</a></li>
 
- 		          <li class="muted">·</li>
 
- 		          <li><a href="https://sourceforge.net/p/metrixplusplus/tickets/new/">Report defect</a></li>
 
- 		          <li class="muted">·</li>
 
- 		          <li><a href="https://sourceforge.net/p/metrixplusplus/tickets/new/">Feature request</a></li>
 
- 		          <li class="muted">·</li>
 
- 		          <li><a href="https://sourceforge.net/p/metrixplusplus/tickets/search/?q=%21status%3Awont-fix+%26%26+%21status%3Aclosed">Open issues</a></li>
 
- 		          <li class="muted">·</li>
 
- 		          <li><a href="https://sourceforge.net/p/metrixplusplus/wiki/ChangeLog/">Changelog</a></li>
 
- 		        </ul>
 
-             </div>
 
-         </div>
 
-       </div>
 
-     </footer>
 
-     <!-- Le javascript
 
-     ================================================== -->
 
-     <!-- Placed at the end of the document so the pages load faster -->
 
-     <script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
 
-     <script src="assets/js/jquery.js"></script>
 
-     <script src="assets/js/bootstrap-transition.js"></script>
 
-     <script src="assets/js/bootstrap-alert.js"></script>
 
-     <script src="assets/js/bootstrap-modal.js"></script>
 
-     <script src="assets/js/bootstrap-dropdown.js"></script>
 
-     <script src="assets/js/bootstrap-scrollspy.js"></script>
 
-     <script src="assets/js/bootstrap-tab.js"></script>
 
-     <script src="assets/js/bootstrap-tooltip.js"></script>
 
-     <script src="assets/js/bootstrap-popover.js"></script>
 
-     <script src="assets/js/bootstrap-button.js"></script>
 
-     <script src="assets/js/bootstrap-collapse.js"></script>
 
-     <script src="assets/js/bootstrap-carousel.js"></script>
 
-     <script src="assets/js/bootstrap-typeahead.js"></script>
 
-     <script src="assets/js/bootstrap-affix.js"></script>
 
-     <script>
 
-       !function ($) {
 
-         $(function(){
 
-           // carousel demo
 
-           $('#myCarousel').carousel()
 
-         })
 
-       }(window.jQuery)
 
-     </script>
 
-     <script src="assets/js/holder/holder.js"></script>
 
-     <script src="assets/js/google-code-prettify/prettify.js"></script>
 
-     <script src="assets/js/application.js"></script>
 
-     <script>
 
-     
 
-     </script>
 
-     <!-- Analytics
 
-     ================================================== -->
 
-     <!--
 
-     <script>
 
-       var _gauges = _gauges || [];
 
-       (function() {
 
-         var t   = document.createElement('script');
 
-         t.type  = 'text/javascript';
 
-         t.async = true;
 
-         t.id    = 'gauges-tracker';
 
-         t.setAttribute('data-site-id', '4f0dc9fef5a1f55508000013');
 
-         t.src = '//secure.gaug.es/track.js';
 
-         var s = document.getElementsByTagName('script')[0];
 
-         s.parentNode.insertBefore(t, s);
 
-       })();
 
-     </script>
 
- 	-->
 
-   </body>
 
- </html>
 
 
  |