cppcheck/man/writing-rules-1.docbook

134 lines
4.4 KiB
Plaintext
Raw Normal View History

<?xml version="1.0" encoding="UTF-8"?>
<section>
<title>Part 1 - Getting started</title>
<section>
<title>Introduction</title>
2010-12-06 19:36:51 +01:00
<para>This is a short and simple guide that describes how rules are
written for Cppcheck.</para>
2010-12-06 19:36:51 +01:00
<para>The patterns are defined with regular expressions. It is required
that you know how regular expressions work.</para>
</section>
<section>
<title>Data representation of the source code</title>
<para>The data used by the rules are not the raw source code.
Cppcheck will read the source code and process it
before the rules are used.</para>
<para>Cppcheck is designed to find bugs and dangerous code. Stylistic
2010-12-06 19:36:51 +01:00
information (such as indentation, comments, etc) are filtered out at an
early state. You don't need to worry about such stylistic information when
you write rules.</para>
<para>Between each token in the code there is always a space. For instance
2011-07-02 14:04:13 +02:00
the raw code "<code>1+f()</code>" is processed into "<code>1 + f ( )</code>"
.</para>
2010-12-06 19:36:51 +01:00
<para>The code is simplified in many ways.</para>
</section>
2010-12-06 19:36:51 +01:00
<section>
<title>Creating a simple rule</title>
2010-12-06 19:36:51 +01:00
<para>When creating a rule there are two steps:</para>
2010-12-06 19:36:51 +01:00
<orderedlist>
<listitem>
2010-12-06 19:36:51 +01:00
<para>Create the regular expression</para>
</listitem>
<listitem>
2010-12-06 19:36:51 +01:00
<para>Create a XML based rule file</para>
</listitem>
2010-12-06 19:36:51 +01:00
</orderedlist>
<section>
2010-12-06 19:36:51 +01:00
<title>Step 1 - Creating the regular expression</title>
2011-07-02 14:04:13 +02:00
<para>Cppcheck uses the PCRE library to handle regular expressions.
<acronym>PCRE</acronym> stands for "Perl Compatible Regular Expressions".
The homepage for PCRE is <ulink url="http://www.pcre.org/">
http://www.pcre.org/</ulink>.</para>
2010-12-06 19:36:51 +01:00
<para>Let's create a regular expression that checks for code such
as:</para>
<programlisting>if (p)
free(p);</programlisting>
2010-12-06 19:36:51 +01:00
<para>For such code the condition is often redundant (on most
2011-07-02 14:04:13 +02:00
implementations it is valid to free a <constant>NULL</constant> pointer).
</para>
2010-12-05 21:50:17 +01:00
<para>The regular expression must be written for the simplified code. To
see what the simplified code looks like you can create a source file
2010-12-06 19:36:51 +01:00
with the code:</para>
<programlisting>void f() {
if (p)
free(p);
}</programlisting>
<para>Save that code as <filename>dealloc.cpp</filename> and then use
<command>cppcheck --rule=".+" dealloc.cpp</command>:</para>
<programlisting>$ ./cppcheck --rule=".+" dealloc.cpp
Checking dealloc.cpp...
[dealloc.cpp:1]: (style) found ' void f ( ) { if ( p ) { free ( p ) ; } }'</programlisting>
2010-12-06 19:36:51 +01:00
<para>The regular expression <literal>.+</literal> matches everything
and the matching text is shown on the screen.</para>
2010-12-05 21:50:17 +01:00
<para>From that output we can see that the simplified code is:</para>
<programlisting> void f ( ) { if ( p ) { free ( p ) ; } }</programlisting>
2010-12-06 19:36:51 +01:00
<para>Now that we know how the simplified code looks. We can create a
regular expression that matches it properly:</para>
<programlisting>$ cppcheck --rule="if \( p \) { free \( p \) ; }" dealloc.cpp
Checking dealloc.cpp...
[dealloc.cpp:2]: (style) found 'if ( p ) { free ( p ) ; }'</programlisting>
</section>
<section>
2010-12-06 19:36:51 +01:00
<title>Step 2 - Create rule file</title>
2010-12-06 19:36:51 +01:00
<para>A rule file is a simple XML file that contains:</para>
<itemizedlist>
<listitem>
2010-12-05 21:50:17 +01:00
<para>a pattern to search for</para>
</listitem>
<listitem>
2010-12-05 21:50:17 +01:00
<para>an error message that is reported when pattern is found</para>
</listitem>
</itemizedlist>
<para>Here is a simple example:</para>
<programlisting>&lt;?xml version="1.0"?&gt;
&lt;rule version="1"&gt;
&lt;pattern&gt;if \( p \) { free \( p \) ; }&lt;/pattern&gt;
&lt;message&gt;
&lt;id&gt;redundantCondition&lt;/id&gt;
&lt;severity&gt;style&lt;/severity&gt;
&lt;summary&gt;Redundant condition. It is valid to free a NULL pointer.&lt;/summary&gt;
&lt;/message&gt;
&lt;/rule&gt;</programlisting>
<para>If you save that xml data in <filename>dealloc.rule</filename> you
can test this rule:</para>
<programlisting>$ cppcheck --rule-file=dealloc.rule dealloc.cpp
Checking dealloc.cpp...
[dealloc.cpp:2]: (style) Redundant condition. It is valid to free a NULL pointer.</programlisting>
</section>
</section>
</section>