2010-12-04 09:18:57 +01:00
|
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
2011-07-02 16:21:58 +02:00
|
|
|
<section id="writing-rules-1">
|
2011-07-02 14:50:01 +02:00
|
|
|
<title>Part 1 - Getting started</title>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
|
|
|
<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-04 09:18:57 +01:00
|
|
|
|
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>
|
2010-12-04 09:18:57 +01:00
|
|
|
</section>
|
|
|
|
|
|
|
|
<section>
|
|
|
|
<title>Data representation of the source code</title>
|
|
|
|
|
2010-12-04 20:01:55 +01:00
|
|
|
<para>The data used by the rules are not the raw source code.
|
2011-07-01 17:06:56 +02:00
|
|
|
Cppcheck will read the source code and process it
|
2010-12-04 20:01:55 +01:00
|
|
|
before the rules are used.</para>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
2010-12-04 20:01:55 +01:00
|
|
|
<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
|
2010-12-04 20:01:55 +01:00
|
|
|
early state. You don't need to worry about such stylistic information when
|
|
|
|
you write rules.</para>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
2010-12-04 20:01:55 +01:00
|
|
|
<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-04 09:18:57 +01:00
|
|
|
|
2010-12-06 19:36:51 +01:00
|
|
|
<para>The code is simplified in many ways.</para>
|
|
|
|
</section>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
2010-12-06 19:36:51 +01:00
|
|
|
<section>
|
|
|
|
<title>Creating a simple rule</title>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
2010-12-06 19:36:51 +01:00
|
|
|
<para>When creating a rule there are two steps:</para>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
2010-12-06 19:36:51 +01:00
|
|
|
<orderedlist>
|
2010-12-04 20:01:55 +01:00
|
|
|
<listitem>
|
2010-12-06 19:36:51 +01:00
|
|
|
<para>Create the regular expression</para>
|
2010-12-04 20:01:55 +01:00
|
|
|
</listitem>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
2010-12-04 20:01:55 +01:00
|
|
|
<listitem>
|
2010-12-06 19:36:51 +01:00
|
|
|
<para>Create a XML based rule file</para>
|
2010-12-04 20:01:55 +01:00
|
|
|
</listitem>
|
2010-12-06 19:36:51 +01:00
|
|
|
</orderedlist>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
2010-12-05 09:36:13 +01:00
|
|
|
<section>
|
2010-12-06 19:36:51 +01:00
|
|
|
<title>Step 1 - Creating the regular expression</title>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
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>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
2010-12-05 09:36:13 +01:00
|
|
|
<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 09:36:13 +01:00
|
|
|
|
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>
|
2010-12-05 09:36:13 +01:00
|
|
|
|
|
|
|
<programlisting>void f() {
|
2010-12-05 13:19:30 +01:00
|
|
|
if (p)
|
|
|
|
free(p);
|
2010-12-05 09:36:13 +01:00
|
|
|
}</programlisting>
|
|
|
|
|
2011-06-30 20:58:43 +02:00
|
|
|
<para>Save that code as <filename>dealloc.cpp</filename> and then use
|
2011-07-01 17:06:56 +02:00
|
|
|
<command>cppcheck --rule=".+" dealloc.cpp</command>:</para>
|
2010-12-05 09:36:13 +01:00
|
|
|
|
2012-09-22 20:41:13 +02:00
|
|
|
<programlisting>$ ./cppcheck --rule=".+" dealloc.cpp
|
2010-12-05 14:08:49 +01:00
|
|
|
Checking dealloc.cpp...
|
|
|
|
[dealloc.cpp:1]: (style) found ' void f ( ) { if ( p ) { free ( p ) ; } }'</programlisting>
|
2010-12-05 13:19:30 +01:00
|
|
|
|
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>
|
2010-12-05 09:36:13 +01:00
|
|
|
|
2010-12-05 14:08:49 +01:00
|
|
|
<programlisting> void f ( ) { if ( p ) { free ( p ) ; } }</programlisting>
|
2010-12-05 09:36:13 +01:00
|
|
|
|
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>
|
2010-12-05 09:36:13 +01:00
|
|
|
|
2010-12-05 13:19:30 +01:00
|
|
|
<programlisting>$ cppcheck --rule="if \( p \) { free \( p \) ; }" dealloc.cpp
|
|
|
|
Checking dealloc.cpp...
|
|
|
|
[dealloc.cpp:2]: (style) found 'if ( p ) { free ( p ) ; }'</programlisting>
|
2010-12-05 09:36:13 +01:00
|
|
|
</section>
|
|
|
|
|
|
|
|
<section>
|
2010-12-06 19:36:51 +01:00
|
|
|
<title>Step 2 - Create rule file</title>
|
2010-12-05 09:36:13 +01:00
|
|
|
|
2010-12-06 19:36:51 +01:00
|
|
|
<para>A rule file is a simple XML file that contains:</para>
|
2010-12-05 09:36:13 +01:00
|
|
|
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
2010-12-05 21:50:17 +01:00
|
|
|
<para>a pattern to search for</para>
|
2010-12-05 09:36:13 +01:00
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
2010-12-05 21:50:17 +01:00
|
|
|
<para>an error message that is reported when pattern is found</para>
|
2010-12-05 09:36:13 +01:00
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
2010-12-05 09:36:13 +01:00
|
|
|
<para>Here is a simple example:</para>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
2010-12-05 09:36:13 +01:00
|
|
|
<programlisting><?xml version="1.0"?>
|
2010-12-04 20:01:55 +01:00
|
|
|
<rule version="1">
|
2010-12-05 13:19:30 +01:00
|
|
|
<pattern>if \( p \) { free \( p \) ; }</pattern>
|
2010-12-04 09:18:57 +01:00
|
|
|
<message>
|
2010-12-05 09:36:13 +01:00
|
|
|
<id>redundantCondition</id>
|
|
|
|
<severity>style</severity>
|
|
|
|
<summary>Redundant condition. It is valid to free a NULL pointer.</summary>
|
2010-12-04 09:18:57 +01:00
|
|
|
</message>
|
|
|
|
</rule></programlisting>
|
|
|
|
|
2011-06-30 20:58:43 +02:00
|
|
|
<para>If you save that xml data in <filename>dealloc.rule</filename> you
|
2010-12-05 13:19:30 +01:00
|
|
|
can test this rule:</para>
|
2010-12-04 09:18:57 +01:00
|
|
|
|
2010-12-05 13:19:30 +01:00
|
|
|
<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>
|
2010-12-05 09:36:13 +01:00
|
|
|
</section>
|
2010-12-04 09:18:57 +01:00
|
|
|
</section>
|
2011-06-27 23:36:23 +02:00
|
|
|
</section>
|