2255 lines
71 KiB
XML
2255 lines
71 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
|
<book>
|
|
<bookinfo>
|
|
<title>Cppcheck 1.88 dev</title>
|
|
|
|
<date>2018-04-23</date>
|
|
</bookinfo>
|
|
|
|
<chapter>
|
|
<title>Introduction</title>
|
|
|
|
<para>Cppcheck is an analysis tool for C/C++ code. Unlike C/C++ compilers
|
|
and many other analysis tools, it doesn't detect syntax errors. Instead,
|
|
Cppcheck detects the types of bugs that the compilers normally fail to
|
|
detect. The goal is no false positives.</para>
|
|
|
|
<para>Supported code and platforms:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>You can check non-standard code that includes various compiler
|
|
extensions, inline assembly code, etc.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Cppcheck should be compilable by any C++ compiler that handles
|
|
the latest C++ standard.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Cppcheck should work on any platform that has sufficient CPU and
|
|
memory.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Please understand that there are limits of Cppcheck. Cppcheck is
|
|
rarely wrong about reported errors. But there are many bugs that it
|
|
doesn't detect.</para>
|
|
|
|
<para>You will find more bugs in your software by testing your software
|
|
carefully, than by using Cppcheck. You will find more bugs in your
|
|
software by instrumenting your software, than by using Cppcheck. But
|
|
Cppcheck can still detect some of the bugs that you miss when testing and
|
|
instrumenting your software.</para>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Getting started (GUI)</title>
|
|
|
|
<para>Start the GUI.</para>
|
|
|
|
<section>
|
|
<title>New Project</title>
|
|
|
|
<para>It is not required but creating a new project file is a good first
|
|
step. You do so through <literal>File</literal> and <literal>New project
|
|
file.</literal></para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>New Project - Paths and Defines</title>
|
|
|
|
<para>What kind of project do you have? If it is a Visual Studio project
|
|
or if you can generate a compile database (cmake/qbs/etc), then you can
|
|
import the project.</para>
|
|
|
|
<para>Otherwise you can configure the paths and defines manually. In
|
|
this screenshot below, a Visual Studio project file is imported:</para>
|
|
|
|
<mediaobject>
|
|
<imageobject>
|
|
<imagedata fileref="images/gui-newproject-pathsanddefines.png"/>
|
|
</imageobject>
|
|
</mediaobject>
|
|
</section>
|
|
|
|
<section>
|
|
<title>New Project - Project</title>
|
|
|
|
<para>In the Project tab it is highly recommended that a
|
|
<literal>Cppcheck build dir</literal> is configured. This will be used
|
|
by Cppcheck to store various analysis information. It gives you whole
|
|
program analysis, incremental analysis, statistics, etc. Each project
|
|
should have its own unique build dir. In the screenshot below the build
|
|
dir is configured as <literal>cppcheck-build-dir</literal>. The path is
|
|
relative to the project file.</para>
|
|
|
|
<para>You should also choose all the libraries that you use. In the
|
|
screenshot below the microsoft_sal and windows libraries are selected.
|
|
You can read more about libraries in this manual.</para>
|
|
|
|
<mediaobject>
|
|
<imageobject>
|
|
<imagedata fileref="images/gui-newproject-project.png"/>
|
|
</imageobject>
|
|
</mediaobject>
|
|
</section>
|
|
|
|
<section>
|
|
<title>New Project - Addons</title>
|
|
|
|
<para>We skip the <literal>Exclude</literal> and
|
|
<literal>Suppressions</literal> tabs now, they can be used later to
|
|
tweak the results.</para>
|
|
|
|
<para>In the Addons tab you can add extra analysis. The addons require
|
|
python.</para>
|
|
|
|
<mediaobject>
|
|
<imageobject>
|
|
<imagedata fileref="images/gui-newproject-addons.png"/>
|
|
</imageobject>
|
|
</mediaobject>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Analyze</title>
|
|
|
|
<para>Click the <literal>OK</literal> button in the dialog. Analysis
|
|
will start immediately.</para>
|
|
|
|
<mediaobject>
|
|
<imageobject>
|
|
<imagedata fileref="images/gui-results.png"/>
|
|
</imageobject>
|
|
</mediaobject>
|
|
|
|
<para>All warnings are activated and therefore it is pretty noisy. There
|
|
are likely various warnings that you don't care about. You can fix that
|
|
easily, right click on messages and choose <literal>Hide</literal> or
|
|
<literal>Suppress</literal>. Hiding messages is not permanent, they will
|
|
be shown after next analysis. Suppressing messages is permanent,
|
|
suppressed ids are stored in the project file and those will not be
|
|
shown again.</para>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Getting started (command line)</title>
|
|
|
|
<section>
|
|
<title>First test</title>
|
|
|
|
<para>Here is a simple code</para>
|
|
|
|
<programlisting>int main()
|
|
{
|
|
char a[10];
|
|
a[10] = 0;
|
|
return 0;
|
|
}</programlisting>
|
|
|
|
<para>If you save that into <filename>file1.c</filename> and
|
|
execute:</para>
|
|
|
|
<programlisting>cppcheck file1.c</programlisting>
|
|
|
|
<para>The output from cppcheck will then be:</para>
|
|
|
|
<programlisting>Checking file1.c...
|
|
[file1.c:4]: (error) Array 'a[10]' index 10 out of bounds</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Checking all files in a folder</title>
|
|
|
|
<para>Normally a program has many source files. And you want to check
|
|
them all. Cppcheck can check all source files in a directory:</para>
|
|
|
|
<programlisting>cppcheck path</programlisting>
|
|
|
|
<para>If "path" is a folder then cppcheck will recursively check all
|
|
source files in this folder.</para>
|
|
|
|
<programlisting>Checking path/file1.cpp...
|
|
1/2 files checked 50% done
|
|
Checking path/file2.cpp...
|
|
2/2 files checked 100% done</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Check files manually or use project file</title>
|
|
|
|
<para>With Cppcheck you can check files manually, by specifying
|
|
files/paths to check and settings. Or you can use a project file
|
|
(cmake/visual studio).</para>
|
|
|
|
<para>Using the project file is quicker since it requires very little
|
|
configuration from you.</para>
|
|
|
|
<para>Checking files manually gives you better control of the
|
|
analysis.</para>
|
|
|
|
<para>We don't know which approach will give you the best results. It is
|
|
recommended that you try both. It is possible that you will get
|
|
different results so that to find most bugs you need to use both
|
|
approaches.</para>
|
|
|
|
<para>Later chapters will describe this in more detail.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Excluding a file or folder from checking</title>
|
|
|
|
<para>To exclude a file or folder, there are two options. The first
|
|
option is to only provide the paths and files you want to check.</para>
|
|
|
|
<programlisting>cppcheck src/a src/b</programlisting>
|
|
|
|
<para>All files under <filename class="directory">src/a</filename> and
|
|
<filename class="directory">src/b</filename> are then checked.</para>
|
|
|
|
<para>The second option is to use <parameter
|
|
class="command">-i</parameter>, with it you specify files/paths to
|
|
ignore. With this command no files in <filename
|
|
class="directory">src/c</filename> are checked:</para>
|
|
|
|
<programlisting>cppcheck -isrc/c src</programlisting>
|
|
|
|
<para>This option does not currently work with the <parameter
|
|
class="command">--project</parameter> option and is only valid when
|
|
supplying an input directory.To ignore multiple directories supply the
|
|
<parameter class="command">-i</parameter> multiple times. The following
|
|
command ignores both the src/b and src/c directories.</para>
|
|
|
|
<programlisting>cppcheck -isrc/b -isrc/c</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Severities</title>
|
|
|
|
<para>The possible severities for messages are:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>error</term>
|
|
|
|
<listitem>
|
|
<para>used when bugs are found</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>warning</term>
|
|
|
|
<listitem>
|
|
<para>suggestions about defensive programming to prevent
|
|
bugs</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>style</term>
|
|
|
|
<listitem>
|
|
<para>stylistic issues related to code cleanup (unused functions,
|
|
redundant code, constness, and such)</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>performance</term>
|
|
|
|
<listitem>
|
|
<para>Suggestions for making the code faster. These suggestions
|
|
are only based on common knowledge. It is not certain you'll get
|
|
any measurable difference in speed by fixing these
|
|
messages.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>portability</term>
|
|
|
|
<listitem>
|
|
<para>portability warnings. 64-bit portability. code might work
|
|
different on different compilers. etc.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>information</term>
|
|
|
|
<listitem>
|
|
<para>Configuration problems. The recommendation is to only enable
|
|
these during configuration.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Enable messages</title>
|
|
|
|
<para>By default only <parameter class="command">error</parameter>
|
|
messages are shown. Through the <parameter
|
|
class="command">--enable</parameter> command more checks can be
|
|
enabled.</para>
|
|
|
|
<programlisting># enable warning messages
|
|
cppcheck --enable=warning file.c
|
|
|
|
# enable performance messages
|
|
cppcheck --enable=performance file.c
|
|
|
|
# enable information messages
|
|
cppcheck --enable=information file.c
|
|
|
|
# For historical reasons, --enable=style enables warning, performance,
|
|
# portability and style messages. These are all reported as "style" when
|
|
# using the old xml format.
|
|
cppcheck --enable=style file.c
|
|
|
|
# enable warning and performance messages
|
|
cppcheck --enable=warning,performance file.c
|
|
|
|
# enable unusedFunction checking. This is not enabled by --enable=style
|
|
# because it doesn't work well on libraries.
|
|
cppcheck --enable=unusedFunction file.c
|
|
|
|
# enable all messages
|
|
cppcheck --enable=all</programlisting>
|
|
|
|
<para>Please note that <literal>--enable=unusedFunction</literal> should
|
|
only be used when the whole program is scanned. Therefore,
|
|
<literal>--enable=all</literal> should also only be used when the whole
|
|
program is scanned. The reason is that the unusedFunction checking will
|
|
warn if a function is not called. There will be noise if function calls
|
|
are not seen.</para>
|
|
|
|
<section>
|
|
<title>Inconclusive checks</title>
|
|
|
|
<para>By default Cppcheck only writes error messages if it is certain.
|
|
With <parameter class="command">--inconclusive</parameter> error
|
|
messages will also be written when the analysis is
|
|
inconclusive.</para>
|
|
|
|
<programlisting>cppcheck --inconclusive path</programlisting>
|
|
|
|
<para>This can of course cause false warnings, it might be reported
|
|
that there are bugs even though there are not. Only use this command
|
|
if false warnings are acceptable.</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Saving results in file</title>
|
|
|
|
<para>Many times you will want to save the results in a file. You can
|
|
use the normal shell redirection for piping error output to a
|
|
file.</para>
|
|
|
|
<programlisting>cppcheck file1.c 2> err.txt</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Multithreaded checking</title>
|
|
|
|
<para>The option <literal>-j</literal> is used to specify the number of
|
|
threads you want to use. For example, to use 4 threads to check the
|
|
files in a folder:</para>
|
|
|
|
<programlisting>cppcheck -j 4 path</programlisting>
|
|
|
|
<para>Please note that this will disable unusedFunction checking.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Platform</title>
|
|
|
|
<para>You should use a platform configuration that match your
|
|
target.</para>
|
|
|
|
<para>By default Cppcheck uses native platform configuration that works
|
|
well if your code is compiled and executed locally.</para>
|
|
|
|
<para>Cppcheck has builtin configurations for <literal>unix</literal>
|
|
and <literal>windows</literal> targets. You can easily use these with
|
|
the <literal>--platform</literal> command line flag.</para>
|
|
|
|
<para>You can also create your own custom platform configuration in a
|
|
xml file. Here is an example:</para>
|
|
|
|
<programlisting><?xml version="1"?>
|
|
<platform>
|
|
<char_bit>8</char_bit>
|
|
<default-sign>signed</default-sign>
|
|
<sizeof>
|
|
<short>2</short>
|
|
<int>4</int>
|
|
<long>4</long>
|
|
<long-long>8</long-long>
|
|
<float>4</float>
|
|
<double>8</double>
|
|
<long-double>12</long-double>
|
|
<pointer>4</pointer>
|
|
<size_t>4</size_t>
|
|
<wchar_t>2</wchar_t>
|
|
</sizeof>
|
|
</platform></programlisting>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Project</title>
|
|
|
|
<para>When you use CMake or Visual Studio you can use
|
|
<literal>--project</literal> to analyse your project.</para>
|
|
|
|
<para>It will give you quick and easy results. There is not much
|
|
configuration you need to do. But it is hard to say if this will give you
|
|
the best results, it is recommended that you try it and also try to
|
|
analyse your source code without <literal>--project</literal> and see
|
|
which option works best for you.</para>
|
|
|
|
<section>
|
|
<title>CMake</title>
|
|
|
|
<para>Cppcheck can understand compile databases. You can generate these
|
|
with CMake.</para>
|
|
|
|
<para>Example:</para>
|
|
|
|
<programlisting>$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .</programlisting>
|
|
|
|
<para>The file <literal>compile_commands.json</literal> is created in
|
|
the current folder.</para>
|
|
|
|
<para>Now run Cppcheck like this:</para>
|
|
|
|
<programlisting>$ cppcheck --project=compile_commands.json</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Visual Studio</title>
|
|
|
|
<para>You can run Cppcheck on individual project files (*.vcxproj) or on
|
|
a whole solution (*.sln)</para>
|
|
|
|
<programlisting># run cppcheck on a whole solution
|
|
$ cppcheck --project=foobar.sln
|
|
|
|
# run cppcheck on a individual project
|
|
$ cppcheck --project=foobar.vcxproj</programlisting>
|
|
|
|
<para>Please note that there is also a Visual Studio plugin that allows
|
|
you to run cppcheck inside Visual Studio.</para>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter id="preprocessor-configurations">
|
|
<title>Preprocessor settings</title>
|
|
|
|
<para>If you use <literal>--project</literal> then Cppcheck will use the
|
|
preprocessor settings from the project file.</para>
|
|
|
|
<para>Otherwise you'll probably want to configure the include paths,
|
|
defines etc.</para>
|
|
|
|
<section>
|
|
<title>Defines</title>
|
|
|
|
<para>Here is a file that has 2 configurations (with A defined and
|
|
without A):</para>
|
|
|
|
<programlisting>#ifdef A
|
|
x = y;
|
|
#else
|
|
x = z;
|
|
#endif</programlisting>
|
|
|
|
<para>By default Cppcheck will check all preprocessor configurations
|
|
(except those that have #error in them). So the above code will be
|
|
analysed both when A is defined and when it is not.</para>
|
|
|
|
<para>You can use -D to change this. When you use -D, cppcheck will by
|
|
default only check the given configuration and nothing else. This is how
|
|
compilers work. But you can use <literal>--force</literal> or
|
|
<literal>--max-configs</literal> to override the number of
|
|
configurations.</para>
|
|
|
|
<programlisting># check all configurations
|
|
cppcheck file.c
|
|
|
|
# only check the configuration A
|
|
cppcheck -DA file.c
|
|
|
|
# check all configurations when macro A is defined
|
|
cppcheck -DA --force file.c</programlisting>
|
|
|
|
<para>Another useful flag might be -U. It undefines a symbol. Example
|
|
usage:</para>
|
|
|
|
<programlisting>cppcheck -UX file.c</programlisting>
|
|
|
|
<para>That will mean that X is not defined. Cppcheck will not check what
|
|
happens when X is defined.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Include paths</title>
|
|
|
|
<para>To add an include path, use <parameter
|
|
class="command">-I</parameter>, followed by the path.</para>
|
|
|
|
<para>Cppcheck's preprocessor basically handles includes like any other
|
|
preprocessor. However, while other preprocessors stop working when they
|
|
encounter a missing header, cppcheck will just print an information
|
|
message and continues parsing the code.</para>
|
|
|
|
<para>The purpose of this behaviour is that cppcheck is meant to work
|
|
without necessarily seeing the entire code. Actually, it is recommended
|
|
to not give all include paths. While it is useful for cppcheck to see
|
|
the declaration of a class when checking the implementation of its
|
|
members, passing standard library headers is highly discouraged because
|
|
it will result in worse results and longer checking time. For such
|
|
cases, .cfg files (see below) are the better way to provide information
|
|
about the implementation of functions and types to cppcheck.</para>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>XML output</title>
|
|
|
|
<para>Cppcheck can generate output in <literal>XML</literal> format. Use
|
|
<parameter>--xml</parameter> to enable this format.</para>
|
|
|
|
<para>A sample command to check a file and output errors in the
|
|
<literal>XML</literal> format:</para>
|
|
|
|
<programlisting>cppcheck --xml file1.cpp</programlisting>
|
|
|
|
<para>Here is a sample report:</para>
|
|
|
|
<programlisting><?xml version="1.0" encoding="UTF-8"?>
|
|
<results version="2">
|
|
<cppcheck version="1.66">
|
|
<errors>
|
|
<error id="someError" severity="error" msg="short error text"
|
|
verbose="long error text" inconclusive="true" cwe="312">
|
|
<location file0="file.c" file="file.h" line="1"/>
|
|
</error>
|
|
</errors>
|
|
</results></programlisting>
|
|
|
|
<section>
|
|
<title>The <error> element</title>
|
|
|
|
<para>Each error is reported in a <literal><error></literal>
|
|
element. Attributes:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><sgmltag class="attribute">id</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>id of error. These are always valid symbolnames.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><sgmltag class="attribute">severity</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>either: <literal>error</literal>,
|
|
<literal>warning</literal>, <literal>style</literal>,
|
|
<literal>performance</literal>, <literal>portability</literal> or
|
|
<literal>information</literal></para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><sgmltag class="attribute">msg</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>the error message in short format</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><sgmltag>verbose</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>the error message in long format.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><sgmltag>inconclusive</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>This attribute is only used when the message is
|
|
inconclusive.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><sgmltag>cwe</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>CWE ID for message. This attribute is only used when the CWE
|
|
ID for the message is known.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
|
|
<section>
|
|
<title>The <location> element</title>
|
|
|
|
<para>All locations related to an error is listed with
|
|
<literal><location></literal> elements. The primary location is
|
|
listed first.</para>
|
|
|
|
<para>Attributes:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><sgmltag class="attribute">file</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>filename. Both relative and absolute paths are
|
|
possible</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><sgmltag class="attribute">file0</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>name of the source file (optional)</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><sgmltag class="attribute">line</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>a number</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><sgmltag class="attribute">info</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>short information message for each location
|
|
(optional)</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Reformatting the output</title>
|
|
|
|
<para>If you want to reformat the output so it looks different you can use
|
|
templates.</para>
|
|
|
|
<section>
|
|
<title>Predefined output formats</title>
|
|
|
|
<para>To get Visual Studio compatible output you can use <parameter
|
|
class="command">--template=vs</parameter>:</para>
|
|
|
|
<programlisting>cppcheck --template=vs samples/arrayIndexOutOfBounds/bad.c</programlisting>
|
|
|
|
<para>This output will look like this:</para>
|
|
|
|
<programlisting>Checking samples/arrayIndexOutOfBounds/bad.c ...
|
|
samples/arrayIndexOutOfBounds/bad.c(6): error: Array 'a[2]' accessed at index 2, which is out of bounds.</programlisting>
|
|
|
|
<para>To get <literal>gcc</literal> compatible output you can use
|
|
<parameter class="command">--template=gcc</parameter>:</para>
|
|
|
|
<programlisting>cppcheck --template=gcc samples/arrayIndexOutOfBounds/bad.c</programlisting>
|
|
|
|
<para>The output will look like this:</para>
|
|
|
|
<programlisting>Checking samples/arrayIndexOutOfBounds/bad.c ...
|
|
samples/arrayIndexOutOfBounds/bad.c:6:6: warning: Array 'a[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds]
|
|
a[2] = 0;
|
|
^</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>User defined output format (single line)</title>
|
|
|
|
<para>You can write your own pattern. For instance, to get warning
|
|
messages that are formatted like old <literal>gcc</literal> such format
|
|
can be used:</para>
|
|
|
|
<programlisting>cppcheck --template="{file}:{line}: {severity}: {message}" samples/arrayIndexOutOfBounds/bad.c</programlisting>
|
|
|
|
<para>The output will look like this:</para>
|
|
|
|
<programlisting>Checking samples/arrayIndexOutOfBounds/bad.c ...
|
|
samples/arrayIndexOutOfBounds/bad.c:6: error: Array 'a[2]' accessed at index 2, which is out of bounds.</programlisting>
|
|
|
|
<para>A comma separated format:</para>
|
|
|
|
<programlisting>cppcheck --template="{file},{line},{severity},{id},{message}" samples/arrayIndexOutOfBounds/bad.c</programlisting>
|
|
|
|
<para>The output will look like this:</para>
|
|
|
|
<programlisting>Checking samples/arrayIndexOutOfBounds/bad.c ...
|
|
samples/arrayIndexOutOfBounds/bad.c,6,error,arrayIndexOutOfBounds,Array 'a[2]' accessed at index 2, which is out of bounds.</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>User defined output format (multi line)</title>
|
|
|
|
<para>Many warnings have multiple locations. Example code:</para>
|
|
|
|
<programlisting>void f(int *p)
|
|
{
|
|
*p = 3; // line 3
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int *p = 0; // line 8
|
|
f(p); // line 9
|
|
return 0;
|
|
}</programlisting>
|
|
|
|
<para>There is a possible null pointer dereference at line 3. Cppcheck
|
|
can show how it came to that conclusion by showing extra location
|
|
information. You need to use both <literal>--template</literal> and
|
|
<literal>--template-location</literal> at the command line.</para>
|
|
|
|
<para>Example command:</para>
|
|
|
|
<programlisting>cppcheck --template="{file}:{line}: {severity}: {message}\n{code}" --template-location="{file}:{line}: note: {info}\n{code}" multiline.c</programlisting>
|
|
|
|
<para>The output from Cppcheck is:</para>
|
|
|
|
<programlisting>Checking multiline.c ...
|
|
multiline.c:3: warning: Possible null pointer dereference: p
|
|
*p = 3;
|
|
^
|
|
multiline.c:8: note: Assignment 'p=0', assigned value is 0
|
|
int *p = 0;
|
|
^
|
|
multiline.c:9: note: Calling function 'f', 1st argument 'p' value is 0
|
|
f(p);
|
|
^
|
|
multiline.c:3: note: Null pointer dereference
|
|
*p = 3;
|
|
^</programlisting>
|
|
|
|
<para>The first line in the warning is formatted by the
|
|
<literal>--template</literal> format.</para>
|
|
|
|
<para>The other lines in the warning are formatted by the
|
|
<literal>--template-location</literal> format.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Format specifiers for --template</title>
|
|
|
|
<para>The available specifiers for <literal>--template</literal>
|
|
are:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>{file}</term>
|
|
|
|
<listitem>
|
|
<para>File name</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>{line}</term>
|
|
|
|
<listitem>
|
|
<para>Line number</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>{column}</term>
|
|
|
|
<listitem>
|
|
<para>Column number</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>{callstack}</term>
|
|
|
|
<listitem>
|
|
<para>Write all locations. Each location is written in
|
|
[{file}:{line}] format and the locations are separated by ->.
|
|
For instance it might look like: [multiline.c:8] ->
|
|
[multiline.c:9] -> [multiline.c:3]</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>{inconclusive:text}</term>
|
|
|
|
<listitem>
|
|
<para>If warning is inconclusive then the given text is written.
|
|
The given text can be any arbitrary text that does not contain }.
|
|
Example: {inconclusive:inconclusive,}</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>{severity}</term>
|
|
|
|
<listitem>
|
|
<para>error/warning/style/performance/portability/information</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>{message}</term>
|
|
|
|
<listitem>
|
|
<para>The warning message</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>{id}</term>
|
|
|
|
<listitem>
|
|
<para>Warning id</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>{code}</term>
|
|
|
|
<listitem>
|
|
<para>The real code.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>\t</term>
|
|
|
|
<listitem>
|
|
<para>Tab</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>\n</term>
|
|
|
|
<listitem>
|
|
<para>Newline</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>\r</term>
|
|
|
|
<listitem>
|
|
<para>Carriage return</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Format specifiers for --template-location</title>
|
|
|
|
<para>The available specifiers for
|
|
<literal>--template-location</literal> are:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>{file}</term>
|
|
|
|
<listitem>
|
|
<para>File name</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>{line}</term>
|
|
|
|
<listitem>
|
|
<para>Line number</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>{column}</term>
|
|
|
|
<listitem>
|
|
<para>Column number</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>{info}</term>
|
|
|
|
<listitem>
|
|
<para>Information message about current location</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>{code}</term>
|
|
|
|
<listitem>
|
|
<para>The real code.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>\t</term>
|
|
|
|
<listitem>
|
|
<para>Tab</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>\t</term>
|
|
|
|
<listitem>
|
|
<para>Newline</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>\r</term>
|
|
|
|
<listitem>
|
|
<para>Carriage return</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Misra</title>
|
|
|
|
<para>Cppcheck has an addon that checks for <literal>MISRA</literal> C
|
|
2012 compliance.</para>
|
|
|
|
<section>
|
|
<title>Requirements</title>
|
|
|
|
<para>You need:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Python 2.X or 3.X</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><literal>The MISRA C 2012</literal> PDF. You can buy this from
|
|
<uri>http://www.misra.org.uk</uri> (costs 15-20 pounds)</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
|
|
<section>
|
|
<title>MISRA Text file</title>
|
|
|
|
<para>It is not allowed to publish the <literal>MISRA</literal> rule
|
|
texts. Therefore the <literal>MISRA</literal> rule texts are not
|
|
available directly in the addon. Instead, the addon can read the rule
|
|
texts from a text file. If you copy/paste all text in "Appendix A
|
|
Summary of guidelines" from the MISRA pdf, then you have all the rule
|
|
texts.</para>
|
|
|
|
<para>If you have installed <literal>xpdf</literal>, such text file can
|
|
be generated on the command line (using <literal>pdftotext</literal>
|
|
that is included in <literal>xpdf</literal>):</para>
|
|
|
|
<programlisting>pdftotext misra-c-2012.pdf output.txt</programlisting>
|
|
|
|
<para>The output might not be 100% perfect so you might need to make
|
|
minor tweaks manually.</para>
|
|
|
|
<para>Other pdf-to-text utilities might work also.</para>
|
|
|
|
<para>To create the text file manually, copy paste Appendix A "Summary
|
|
of guidelines" from the MISRA PDF. Format:</para>
|
|
|
|
<programlisting>Appendix A Summary of guidelines
|
|
Rule 1.1
|
|
Rule text
|
|
Rule 1.2
|
|
Rule text
|
|
...</programlisting>
|
|
|
|
<para>Rules that you want to disable does not need to have a rule text.
|
|
Rules that don't have rule text will be suppressed by the addon.</para>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Suppressions</title>
|
|
|
|
<para>If you want to filter out certain errors you can suppress
|
|
these.</para>
|
|
|
|
<section>
|
|
<title>Plain text suppressions</title>
|
|
|
|
<para>You can suppress certain types of errors. The format for such a
|
|
suppression is one of:</para>
|
|
|
|
<programlisting>[error id]:[filename]:[line]
|
|
[error id]:[filename2]
|
|
[error id]</programlisting>
|
|
|
|
<para>The <replaceable>error id</replaceable> is the id that you want to
|
|
suppress. The easiest way to get it is to use the <parameter
|
|
class="command">--xml</parameter> command line flag. Copy and paste the
|
|
<replaceable>id</replaceable> string from the XML output. This may be
|
|
<literal>*</literal> to suppress all warnings (for a specified file or
|
|
files).</para>
|
|
|
|
<para>The <replaceable>filename</replaceable> may include the wildcard
|
|
characters <literal>*</literal> or <literal>?</literal>, which match any
|
|
sequence of characters or any single character respectively. It is
|
|
recommended that you use "/" as path separator on all operating
|
|
systems.</para>
|
|
|
|
<section>
|
|
<title>Command line suppression</title>
|
|
|
|
<para>The <parameter class="command">--suppress=</parameter> command
|
|
line option is used to specify suppressions on the command line.
|
|
Example:</para>
|
|
|
|
<programlisting>cppcheck --suppress=memleak:src/file1.cpp src/</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Listing suppressions in a file</title>
|
|
|
|
<para>You can create a suppressions file. Example:</para>
|
|
|
|
<programlisting>// suppress memleak and exceptNew errors in the file src/file1.cpp
|
|
memleak:src/file1.cpp
|
|
exceptNew:src/file1.cpp
|
|
|
|
// suppress all uninitvar errors in all files
|
|
uninitvar</programlisting>
|
|
|
|
<para>Note that you may add empty lines and comments in the
|
|
suppressions file.</para>
|
|
|
|
<para>You can use the suppressions file like this:</para>
|
|
|
|
<programlisting>cppcheck --suppressions-list=suppressions.txt src/</programlisting>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>XML suppressions</title>
|
|
|
|
<para>You can specify suppressions in a XML file. Example file:</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<suppressions>
|
|
<suppress>
|
|
<id>uninitvar</id>
|
|
<fileName>src/file1.c</fileName>
|
|
<lineNumber>10</lineNumber>
|
|
<symbolName>var</symbolName>
|
|
</suppress>
|
|
</suppressions></programlisting>
|
|
|
|
<para>The xml format is extensible and may be extended with further
|
|
attributes in the future.</para>
|
|
|
|
<para>You can use the suppressions file like this:</para>
|
|
|
|
<programlisting>cppcheck --suppress-xml=suppressions.xml src/</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Inline suppressions</title>
|
|
|
|
<para>Suppressions can also be added directly in the code by adding
|
|
comments that contain special keywords. Before adding such comments,
|
|
consider that the code readability is sacrificed a little.</para>
|
|
|
|
<para>This code will normally generate an error message:</para>
|
|
|
|
<programlisting>void f() {
|
|
char arr[5];
|
|
arr[10] = 0;
|
|
}</programlisting>
|
|
|
|
<para>The output is:</para>
|
|
|
|
<programlisting># cppcheck test.c
|
|
Checking test.c...
|
|
[test.c:3]: (error) Array 'arr[5]' index 10 out of bounds</programlisting>
|
|
|
|
<para>To suppress the error message, a comment can be added:</para>
|
|
|
|
<programlisting>void f() {
|
|
char arr[5];
|
|
|
|
// cppcheck-suppress arrayIndexOutOfBounds
|
|
arr[10] = 0;
|
|
}</programlisting>
|
|
|
|
<para>Now the --inline-suppr flag can be used to suppress the warning.
|
|
No error is reported when invoking cppcheck this way:</para>
|
|
|
|
<programlisting>cppcheck --inline-suppr test.c</programlisting>
|
|
|
|
<para>you can specify that the inline suppression only applies to a
|
|
specific symbol:</para>
|
|
|
|
<programlisting>// cppcheck-suppress arrayIndexOutOfBounds symbolName=arr</programlisting>
|
|
|
|
<para>You can write comments for the suppress, however is recommended to
|
|
use ; or // to specify where they start:</para>
|
|
|
|
<programlisting>// cppcheck-suppress arrayIndexOutOfBounds ; some comment
|
|
// cppcheck-suppress arrayIndexOutOfBounds // some comment</programlisting>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Library configuration</title>
|
|
|
|
<para>When external libraries are used, such as WinAPI, POSIX, gtk, Qt,
|
|
etc, <literal>Cppcheck</literal> doesn't know how the external functions
|
|
behave. <literal>Cppcheck</literal> then fails to detect various problems
|
|
such as leaks, buffer overflows, possible null pointer dereferences, etc.
|
|
But this can be fixed with configuration files.</para>
|
|
|
|
<para>Cppcheck already contains configurations for several libraries. They
|
|
can be loaded as described below. Note that the configuration for the
|
|
standard libraries of C and C++, <literal>std.cfg</literal>, is always
|
|
loaded by cppcheck. If you create or update a configuration file for a
|
|
popular library, we would appreciate if you upload it to us.</para>
|
|
|
|
<section>
|
|
<title>Using your own custom .cfg file</title>
|
|
|
|
<para>You can create and use your own .cfg files for your projects. Use
|
|
<literal>--check-library</literal> and
|
|
<literal>--enable=information</literal> to get hints about what you
|
|
should configure.</para>
|
|
|
|
<para>It is recommended that you use the <literal>Library
|
|
Editor</literal> in the <literal>Cppcheck GUI</literal> to edit
|
|
configuration files. It is available in the <literal>View</literal>
|
|
menu. All settings are not documented in this manual.</para>
|
|
|
|
<para>If you have a question about the <literal>.cfg</literal> file
|
|
format it is recommended you ask in the forum
|
|
(http://sourceforge.net/p/cppcheck/discussion/).</para>
|
|
|
|
<para>The command line cppcheck will try to load custom .cfg files from
|
|
the working path - execute cppcheck from the path where the .cfg files
|
|
are.</para>
|
|
|
|
<para>The cppcheck GUI will try to load custom .cfg files from the
|
|
project file path. The custom .cfg files should be shown in the
|
|
<literal>Edit Project File</literal> dialog that you open from the
|
|
<literal>File</literal> menu.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Memory/resource leaks</title>
|
|
|
|
<para>Cppcheck has configurable checking for leaks, e.g. you can specify
|
|
which functions allocate and free memory or resources and which
|
|
functions do not affect the allocation at all.</para>
|
|
|
|
<section>
|
|
<title>alloc and dealloc</title>
|
|
|
|
<para>Here is an example program:</para>
|
|
|
|
<para><programlisting>void test()
|
|
{
|
|
HPEN pen = CreatePen(PS_SOLID, 1, RGB(255,0,0));
|
|
}</programlisting></para>
|
|
|
|
<para>The code example above has a resource leak -
|
|
<literal>CreatePen()</literal> is a WinAPI function that creates a
|
|
pen. However, Cppcheck doesn't assume that return values from
|
|
functions must be freed. There is no error message:</para>
|
|
|
|
<programlisting># cppcheck pen1.c
|
|
Checking pen1.c...</programlisting>
|
|
|
|
<para>If you provide a configuration file then
|
|
<literal>Cppcheck</literal> detects the bug:</para>
|
|
|
|
<programlisting># cppcheck --library=windows.cfg pen1.c
|
|
Checking pen1.c...
|
|
[pen1.c:3]: (error) Resource leak: pen</programlisting>
|
|
|
|
<para>Here is a minimal <literal>windows.cfg</literal> file:</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<resource>
|
|
<alloc>CreatePen</alloc>
|
|
<dealloc>DeleteObject</dealloc>
|
|
</resource>
|
|
</def></programlisting>
|
|
|
|
<para>The allocation and deallocation functions are organized in
|
|
groups. Each group is defined in a <literal><resource></literal>
|
|
or <literal><memory></literal> tag and is identified by its
|
|
<literal><dealloc></literal> functions. This means, groups with
|
|
overlapping <literal><dealloc></literal> tags are merged.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>leak-ignore and use</title>
|
|
|
|
<para>Often the allocated pointer is passed to functions.
|
|
Example:</para>
|
|
|
|
<programlisting>void test()
|
|
{
|
|
char *p = malloc(100);
|
|
dostuff(p);
|
|
}</programlisting>
|
|
|
|
<para>If Cppcheck doesn't know what <literal>dostuff</literal> does,
|
|
without configuration it will assume that <literal>dostuff</literal>
|
|
takes care of the memory so there is no memory leak.</para>
|
|
|
|
<para>To specify that <literal>dostuff</literal> doesn't take care of
|
|
the memory in any way, use <literal>leak-ignore</literal> in the
|
|
<literal><function></literal> tag (see next section):</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<function name="dostuff">
|
|
<leak-ignore/>
|
|
<arg nr="1"/>
|
|
</function>
|
|
</def></programlisting>
|
|
|
|
<para>If instead <literal>dostuff</literal> takes care of the memory
|
|
then this can be configured with:</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<memory>
|
|
<dealloc>free</dealloc>
|
|
<use>dostuff</use>
|
|
</memory>
|
|
</def></programlisting>
|
|
|
|
<para>The <literal><use></literal> configuration has no logical
|
|
purpose. You will get the same warnings without it. Use it to silence
|
|
<literal>--check-library</literal> information messages.</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Function behaviour</title>
|
|
|
|
<para>To specify the behaviour of functions and how they should be used,
|
|
<literal><function></literal> tags can be used. Functions are
|
|
identified by their name, specified in the <literal>name</literal>
|
|
attribute and their number of arguments. The name is a comma-separated
|
|
list of function names. For functions in namespaces or classes, just
|
|
provide their fully qualified name. For example: <literal><function
|
|
name="memcpy,std::memcpy"></literal>. If you have template functions
|
|
then provide their instantiated names <literal><function
|
|
name="dostuff<int>"></literal>.</para>
|
|
|
|
<section>
|
|
<title>Function arguments</title>
|
|
|
|
<para>The arguments a function takes can be specified by
|
|
<literal><arg></literal> tags. Each of them takes the number of
|
|
the argument (starting from 1) in the <literal>nr</literal> attribute,
|
|
<literal>nr="any"</literal> for arbitrary arguments, or
|
|
<literal>nr="variadic"</literal> for variadic arguments. Optional
|
|
arguments can be specified by providing a default value:
|
|
<literal>default="value"</literal>. The specifications for individual
|
|
arguments override this setting.</para>
|
|
|
|
<section>
|
|
<title>Not bool</title>
|
|
|
|
<para>Here is an example program with misplaced comparison:</para>
|
|
|
|
<programlisting>void test()
|
|
{
|
|
if (MemCmp(buffer1, buffer2, 1024==0)) {}
|
|
}</programlisting>
|
|
|
|
<para><literal>Cppcheck</literal> assumes that it is fine to pass
|
|
boolean values to functions:</para>
|
|
|
|
<programlisting># cppcheck notbool.c
|
|
Checking notbool.c...</programlisting>
|
|
|
|
<para>If you provide a configuration file then Cppcheck detects the
|
|
bug:</para>
|
|
|
|
<programlisting># cppcheck --library=notbool.cfg notbool.c
|
|
Checking notbool.c...
|
|
[notbool.c:5]: (error) Invalid MemCmp() argument nr 3. A non-boolean value is required.</programlisting>
|
|
|
|
<para>Here is the minimal notbool.cfg</para>
|
|
|
|
<para><programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<function name="MemCmp">
|
|
<arg nr="1"/>
|
|
<arg nr="2"/>
|
|
<arg nr="3">
|
|
<not-bool/>
|
|
</arg>
|
|
</function>
|
|
</def></programlisting></para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Uninitialized memory</title>
|
|
|
|
<para>Here is an example program:</para>
|
|
|
|
<programlisting>void test()
|
|
{
|
|
char buffer1[1024];
|
|
char buffer2[1024];
|
|
CopyMemory(buffer1, buffer2, 1024);
|
|
}</programlisting>
|
|
|
|
<para>The bug here is that buffer2 is uninitialized. The second
|
|
argument for CopyMemory needs to be initialized. However,
|
|
<literal>Cppcheck</literal> assumes that it is fine to pass
|
|
uninitialized variables to functions:</para>
|
|
|
|
<programlisting># cppcheck uninit.c
|
|
Checking uninit.c...</programlisting>
|
|
|
|
<para>If you provide a configuration file then Cppcheck detects the
|
|
bug:</para>
|
|
|
|
<programlisting># cppcheck --library=windows.cfg uninit.c
|
|
Checking uninit.c...
|
|
[uninit.c:5]: (error) Uninitialized variable: buffer2</programlisting>
|
|
|
|
<para>Note that this implies for pointers that the memory they point
|
|
at has to be initialized, too.</para>
|
|
|
|
<para>Here is the minimal <literal>windows.cfg</literal>:</para>
|
|
|
|
<para><programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<function name="CopyMemory">
|
|
<arg nr="1"/>
|
|
<arg nr="2">
|
|
<not-uninit/>
|
|
</arg>
|
|
<arg nr="3"/>
|
|
</function>
|
|
</def></programlisting></para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Null pointers</title>
|
|
|
|
<para>Cppcheck assumes it's ok to pass NULL pointers to functions.
|
|
Here is an example program:</para>
|
|
|
|
<programlisting>void test()
|
|
{
|
|
CopyMemory(NULL, NULL, 1024);
|
|
}</programlisting>
|
|
|
|
<para>The MSDN documentation is not clear if that is ok or not. But
|
|
let's assume it's bad. Cppcheck assumes that it's ok to pass NULL to
|
|
functions so no error is reported:</para>
|
|
|
|
<programlisting># cppcheck null.c
|
|
Checking null.c...</programlisting>
|
|
|
|
<para>If you provide a configuration file then
|
|
<literal>Cppcheck</literal> detects the bug:</para>
|
|
|
|
<programlisting>cppcheck --library=windows.cfg null.c
|
|
Checking null.c...
|
|
[null.c:3]: (error) Null pointer dereference</programlisting>
|
|
|
|
<para>Note that this implies <literal><not-uninit></literal>
|
|
as far as values are concerned. Uninitialized memory might still be
|
|
passed to the function.</para>
|
|
|
|
<para>Here is a minimal <literal>windows.cfg</literal> file:</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<function name="CopyMemory">
|
|
<arg nr="1">
|
|
<not-null/>
|
|
</arg>
|
|
<arg nr="2"/>
|
|
<arg nr="3"/>
|
|
</function>
|
|
</def></programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Format string</title>
|
|
|
|
<para>You can define that a function takes a format string.
|
|
Example:</para>
|
|
|
|
<programlisting>void test()
|
|
{
|
|
do_something("%i %i\n", 1024);
|
|
}</programlisting>
|
|
|
|
<para>No error is reported for that:</para>
|
|
|
|
<programlisting># cppcheck formatstring.c
|
|
Checking formatstring.c...</programlisting>
|
|
|
|
<para>A configuration file can be created that says that the string
|
|
is a format string. For instance:</para>
|
|
|
|
<para><programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<function name="do_something">
|
|
<formatstr type="printf"/>
|
|
<arg nr="1">
|
|
<formatstr/>
|
|
</arg>
|
|
</function>
|
|
</def></programlisting>Now Cppcheck will report an error:</para>
|
|
|
|
<programlisting>cppcheck --library=test.cfg formatstring.c
|
|
Checking formatstring.c...
|
|
[formatstring.c:3]: (error) do_something format string requires 2 parameters but only 1 is given.</programlisting>
|
|
|
|
<para>The <literal>type</literal> attribute can be either:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>printf - format string follows the printf rules</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>scanf - format string follows the scanf rules</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Value range</title>
|
|
|
|
<para>The valid values can be defined. Imagine:</para>
|
|
|
|
<programlisting>void test()
|
|
{
|
|
do_something(1024);
|
|
}</programlisting>
|
|
|
|
<para>No error is reported for that:</para>
|
|
|
|
<programlisting># cppcheck valuerange.c
|
|
Checking valuerange.c...</programlisting>
|
|
|
|
<para>A configuration file can be created that says that 1024 is out
|
|
of bounds. For instance:</para>
|
|
|
|
<para><programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<function name="do_something">
|
|
<arg nr="1">
|
|
<valid>0:1023</valid>
|
|
</arg>
|
|
</function>
|
|
</def></programlisting>Now Cppcheck will report an error:</para>
|
|
|
|
<programlisting>cppcheck --library=test.cfg range.c
|
|
Checking range.c...
|
|
[range.c:3]: (error) Invalid do_something() argument nr 1. The value is 1024 but the valid values are '0-1023'.</programlisting>
|
|
|
|
<para>Some example expressions you can use in the valid
|
|
element:</para>
|
|
|
|
<programlisting>0,3,5 => only values 0, 3 and 5 are valid
|
|
-10:20 => all values between -10 and 20 are valid
|
|
:0 => all values that are less or equal to 0 are valid
|
|
0: => all values that are greater or equal to 0 are valid
|
|
0,2:32 => the value 0 and all values between 2 and 32 are valid
|
|
-1.5:5.6 => all values between -1.5 and 5.6 are valid </programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>minsize</title>
|
|
|
|
<para>Some function arguments take a buffer. With minsize you can
|
|
configure the min size of the buffer (in bytes, not elements).
|
|
Imagine:</para>
|
|
|
|
<programlisting>void test()
|
|
{
|
|
char str[5];
|
|
do_something(str,"12345");
|
|
}</programlisting>
|
|
|
|
<para>No error is reported for that:</para>
|
|
|
|
<programlisting># cppcheck minsize.c
|
|
Checking minsize.c...</programlisting>
|
|
|
|
<para>A configuration file can for instance be created that says
|
|
that the size of the buffer in argument 1 must be larger than the
|
|
strlen of argument 2.For instance:</para>
|
|
|
|
<para><programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<function name="do_something">
|
|
<arg nr="1">
|
|
<minsize type="strlen" arg="2"/>
|
|
</arg>
|
|
<arg nr="2"/>
|
|
</function>
|
|
</def></programlisting>Now Cppcheck will report this error:</para>
|
|
|
|
<programlisting>cppcheck --library=1.cfg minsize.c
|
|
Checking minsize.c...
|
|
[minsize.c:4]: (error) Buffer is accessed out of bounds: str
|
|
</programlisting>
|
|
|
|
<para>There are different types of minsizes:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>strlen</term>
|
|
|
|
<listitem>
|
|
<para>buffer size must be larger than other arguments string
|
|
length. Example: see strcpy configuration in std.cfg</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>argvalue</term>
|
|
|
|
<listitem>
|
|
<para>buffer size must be larger than value in other argument.
|
|
Example: see memset configuration in std.cfg</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>sizeof</term>
|
|
|
|
<listitem>
|
|
<para>buffer size must be larger than other argument buffer
|
|
size. Example: see memccpy configuration in posix.cfg</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>mul</term>
|
|
|
|
<listitem>
|
|
<para>buffer size must be larger than multiplication result
|
|
when multiplying values given in two other arguments.
|
|
Typically one argument defines the element size and another
|
|
element defines the number of elements. Example: see fread
|
|
configuration in std.cfg</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
|
|
<section>
|
|
<title>strz</title>
|
|
|
|
<para>With this you can say that an argument must be a zero-terminated
|
|
string.</para>
|
|
|
|
<para><programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<function name="do_something">
|
|
<arg nr="1">
|
|
<strz/>
|
|
</arg>
|
|
</function>
|
|
</def></programlisting></para>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>noreturn</title>
|
|
|
|
<para>Cppcheck doesn't assume that functions always return. Here is an
|
|
example code:</para>
|
|
|
|
<programlisting>void test(int x)
|
|
{
|
|
int data, buffer[1024];
|
|
if (x == 1)
|
|
data = 123;
|
|
else
|
|
ZeroMemory(buffer, sizeof(buffer));
|
|
buffer[0] = data; // <- error: data is uninitialized if x is not 1
|
|
}</programlisting>
|
|
|
|
<para>In theory, if <literal>ZeroMemory</literal> terminates the
|
|
program then there is no bug. Cppcheck therefore reports no
|
|
error:</para>
|
|
|
|
<programlisting># cppcheck noreturn.c
|
|
Checking noreturn.c...</programlisting>
|
|
|
|
<para>However if you use <literal>--check-library</literal> and
|
|
<literal>--enable=information</literal> you'll get this:</para>
|
|
|
|
<programlisting># cppcheck --check-library --enable=information noreturn.c
|
|
Checking noreturn.c...
|
|
[noreturn.c:7]: (information) --check-library: Function ZeroMemory() should have <noreturn> configuration
|
|
</programlisting>
|
|
|
|
<para>If a proper <literal>windows.cfg</literal> is provided, the bug
|
|
is detected:</para>
|
|
|
|
<programlisting># cppcheck --library=windows.cfg noreturn.c
|
|
Checking noreturn.c...
|
|
[noreturn.c:8]: (error) Uninitialized variable: data</programlisting>
|
|
|
|
<para>Here is a minimal <literal>windows.cfg</literal> file:</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<function name="ZeroMemory">
|
|
<noreturn>false</noreturn>
|
|
<arg nr="1"/>
|
|
<arg nr="2"/>
|
|
</function>
|
|
</def></programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>use-retval</title>
|
|
|
|
<para>As long as nothing else is specified, cppcheck assumes that
|
|
ignoring the return value of a function is ok:</para>
|
|
|
|
<programlisting>bool test(const char* a, const char* b)
|
|
{
|
|
strcmp(a, b); // <- bug: The call of strcmp does not have side-effects, but the return value is ignored.
|
|
return true;
|
|
}</programlisting>
|
|
|
|
<para>In case <literal>strcmp</literal> has side effects, such as
|
|
assigning the result to one of the parameters passed to it, nothing
|
|
bad would happen:</para>
|
|
|
|
<programlisting># cppcheck useretval.c
|
|
Checking useretval.c...</programlisting>
|
|
|
|
<para>If a proper <literal>lib.cfg</literal> is provided, the bug is
|
|
detected:</para>
|
|
|
|
<programlisting># cppcheck --library=lib.cfg --enable=warning useretval.c
|
|
Checking useretval.c...
|
|
[useretval.c:3]: (warning) Return value of function strcmp() is not used.</programlisting>
|
|
|
|
<para>Here is a minimal <literal>lib.cfg</literal> file:</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<function name="strcmp">
|
|
<use-retval/>
|
|
<arg nr="1"/>
|
|
<arg nr="2"/>
|
|
</function>
|
|
</def></programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>pure and const</title>
|
|
|
|
<para>These correspond to the GCC function attributes pure and
|
|
const.</para>
|
|
|
|
<para>A pure function has no effects except to return a value, and its
|
|
return value depends only on the parameters and global
|
|
variables.</para>
|
|
|
|
<para>A const function has no effects except to return a value, and
|
|
its return value depends only on the parameters.</para>
|
|
|
|
<para>Here is an example code:</para>
|
|
|
|
<programlisting>void f(int x)
|
|
{
|
|
if (calculate(x) == 213) {
|
|
|
|
} else if (calculate(x) == 213) {
|
|
// unreachable code
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>If <literal>calculate()</literal> is a const function then the
|
|
result of <literal>calculate(x)</literal> will be the same in both
|
|
conditions, since the same parameter value is used.</para>
|
|
|
|
<para>Cppcheck normally assumes that the result might be different,
|
|
and reports no warning for the code:</para>
|
|
|
|
<programlisting># cppcheck const.c
|
|
Checking const.c...</programlisting>
|
|
|
|
<para>If a proper <literal>const.cfg</literal> is provided, the
|
|
unreachable code is detected:</para>
|
|
|
|
<programlisting># cppcheck --enable=style --library=const const.c
|
|
Checking const.c...
|
|
[const.c:7]: (style) Expression is always false because 'else if' condition matches previous condition at line 5.</programlisting>
|
|
|
|
<para>Here is a minimal <literal>const.cfg</literal> file:</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<function name="calculate">
|
|
<const/>
|
|
<arg nr="1"/>
|
|
</function>
|
|
</def></programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Example configuration for strcpy()</title>
|
|
|
|
<para>The proper configuration for the standard strcpy() function
|
|
would be:</para>
|
|
|
|
<programlisting> <function name="strcpy">
|
|
<leak-ignore/>
|
|
<noreturn>false</noreturn>
|
|
<arg nr="1">
|
|
<not-null/>
|
|
</arg>
|
|
<arg nr="2">
|
|
<not-null/>
|
|
<not-uninit/>
|
|
<strz/>
|
|
</arg>
|
|
</function></programlisting>
|
|
|
|
<para>The <literal><leak-ignore/></literal> tells Cppcheck to
|
|
ignore this function call in the leaks checking. Passing allocated
|
|
memory to this function won't mean it will be deallocated.</para>
|
|
|
|
<para>The <literal><noreturn></literal> tells Cppcheck if this
|
|
function returns or not.</para>
|
|
|
|
<para>The first argument that the function takes is a pointer. It must
|
|
not be a null pointer, therefore <literal><not-null></literal>
|
|
is used.</para>
|
|
|
|
<para>The second argument the function takes is a pointer. It must not
|
|
be null. And it must point at initialized data. Using
|
|
<literal><not-null></literal> and
|
|
<literal><not-uninit></literal> is correct. Moreover it must
|
|
point at a zero-terminated string so <strz> is also used.</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>define</title>
|
|
|
|
<para>Libraries can be used to define preprocessor macros as well. For
|
|
example:</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<define name="NULL_VALUE" value="0"/>
|
|
</def></programlisting>
|
|
|
|
<para>Each occurrence of "NULL_VALUE" in the code would then be replaced
|
|
by "0" at preprocessor stage.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>podtype</title>
|
|
|
|
<para>Use this for integer/float/bool/pointer types. Not for
|
|
structs/unions.</para>
|
|
|
|
<para>Lots of code relies on typedefs providing platform independent
|
|
types. "podtype"-tags can be used to provide necessary information to
|
|
cppcheck to support them. Without further information, cppcheck does not
|
|
understand the type "uint16_t" in the following example:</para>
|
|
|
|
<programlisting>void test() {
|
|
uint16_t a;
|
|
}</programlisting>
|
|
|
|
<para>No message about variable 'a' being unused is printed:</para>
|
|
|
|
<programlisting># cppcheck --enable=style unusedvar.cpp
|
|
Checking unusedvar.cpp...</programlisting>
|
|
|
|
<para>If uint16_t is defined in a library as follows, the result
|
|
improves:</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<podtype name="uint16_t" sign="u" size="2"/>
|
|
</def></programlisting>
|
|
|
|
<para>The size of the type is specified in bytes. Possible values for
|
|
the "sign" attribute are "s" (signed) and "u" (unsigned). Both
|
|
attributes are optional. Using this library, cppcheck prints:</para>
|
|
|
|
<programlisting># cppcheck --library=lib.cfg --enable=style unusedvar.cpp
|
|
Checking unusedvar.cpp...
|
|
[unusedvar.cpp:2]: (style) Unused variable: a</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>container</title>
|
|
|
|
<para>A lot of C++ libraries, among those the STL itself, provide
|
|
containers with very similar functionality. Libraries can be used to
|
|
tell cppcheck about their behaviour. Each container needs a unique ID.
|
|
It can optionally have a startPattern, which must be a valid
|
|
Token::Match pattern and an endPattern that is compared to the linked
|
|
token of the first token with such a link. The optional attribute
|
|
"inherits" takes an ID from a previously defined container.</para>
|
|
|
|
<para>Inside the <container> tag, functions can be defined inside
|
|
of the tags <size>, <access> and <other> (on your
|
|
choice). Each of them can specify an action like "resize" and/or the
|
|
result it yields, for example "end-iterator".</para>
|
|
|
|
<para>The following example provides a definition for std::vector, based
|
|
on the definition of "stdContainer" (not shown):</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<def>
|
|
<container id="stdVector" startPattern="std :: vector &lt;" inherits="stdContainer">
|
|
<size>
|
|
<function name="push_back" action="push"/>
|
|
<function name="pop_back" action="pop"/>
|
|
</size>
|
|
<access indexOperator="array-like">
|
|
<function name="at" yields="at_index"/>
|
|
<function name="front" yields="item"/>
|
|
<function name="back" yields="item"/>
|
|
</access>
|
|
</container>
|
|
</def></programlisting>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Rules</title>
|
|
|
|
<para>You can define custom rules using regular expressions.</para>
|
|
|
|
<para>These rules can not perform sophisticated analysis of the code. But
|
|
they give you an easy way to check for various simple patterns in the
|
|
code.</para>
|
|
|
|
<para>To get started writing rules, see the related articles here:</para>
|
|
|
|
<para><ulink
|
|
url="http://sourceforge.net/projects/cppcheck/files/Articles/">http://sourceforge.net/projects/cppcheck/files/Articles/</ulink></para>
|
|
|
|
<para>The file format for rules is:</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<rule>
|
|
<tokenlist>LIST</tokenlist>
|
|
<pattern>PATTERN</pattern>
|
|
<message>
|
|
<id>ID</id>
|
|
<severity>SEVERITY</severity>
|
|
<summary>SUMMARY</summary>
|
|
</message>
|
|
</rule></programlisting>
|
|
|
|
<para>CDATA can be used to include characters in a pattern that might
|
|
interfere with XML:</para>
|
|
|
|
<programlisting><![CDATA[some<strange>pattern]]></programlisting>
|
|
|
|
<section>
|
|
<title><tokenlist></title>
|
|
|
|
<para>The <literal><tokenlist></literal> element is optional. With
|
|
this element you can control what tokens are checked. The
|
|
<literal>LIST</literal> can be either <literal>define</literal>,
|
|
<literal>raw</literal>, <literal>normal</literal> or
|
|
<literal>simple</literal>.</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>define</term>
|
|
|
|
<listitem>
|
|
<para>used to check #define preprocessor statements.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>raw</term>
|
|
|
|
<listitem>
|
|
<para>used to check the preprocessor output.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>normal</term>
|
|
|
|
<listitem>
|
|
<para>used to check the <literal>normal</literal> token list.
|
|
There are some simplifications.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>simple</term>
|
|
|
|
<listitem>
|
|
<para>used to check the simple token list. All simplifications are
|
|
used. Most Cppcheck checks use the simple token list.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>If there is no <tokenlist> element then
|
|
<literal>simple</literal> is used automatically.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title><pattern></title>
|
|
|
|
<para>The <literal>PATTERN</literal> is the
|
|
<literal>PCRE</literal>-compatible regular expression that will be
|
|
executed.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title><id></title>
|
|
|
|
<para>The ID specify the user-defined message id.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title><severity></title>
|
|
|
|
<para>The <literal>SEVERITY</literal> must be one of the
|
|
<literal>Cppcheck</literal> severities: <literal>information</literal>,
|
|
<literal>performance</literal>, <literal>portability</literal>,
|
|
<literal>style</literal>, <literal>warning</literal>, or
|
|
<literal>error</literal>.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title><summary></title>
|
|
|
|
<para>Optional. The summary for the message. If no summary is given, the
|
|
matching tokens is written.</para>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Cppcheck addons</title>
|
|
|
|
<para>Cppcheck addons are implemented as standalone scripts or programs.
|
|
With Cppcheck addons, you can for instance:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>add extra custom checkers that use sophisticated analysis</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>visualize your code</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>etc</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<section>
|
|
<title>Using Cppcheck addons</title>
|
|
|
|
<para>Currently there are two steps to use an addon:</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>Run Cppcheck to generate dump files</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Run the addon on the dump files</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<para>The <literal>--dump</literal> flag is used to generate dump files.
|
|
To generate a dump file for every source file in the foo/ folder:</para>
|
|
|
|
<programlisting>cppcheck --dump foo/</programlisting>
|
|
|
|
<para>To run a addon script on all dump files in the foo/ folder:</para>
|
|
|
|
<programlisting>python addon.py foo/*.dump</programlisting>
|
|
|
|
<section>
|
|
<title>Where to find some Cppcheck addons</title>
|
|
|
|
<para>There are a few addons that can be downloaded.</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Addons provided by the Cppcheck project:
|
|
<uri>http://github.com/danmar/cppcheck/blob/master/addons</uri></para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>ublinter, a project that wants to "lint" for "undefined
|
|
behaviour": <uri>http://github.com/danmar/ublinter</uri></para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>We would be happy to add a link to your addon here (no matter if
|
|
it's commercial or free).</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Writing Cppcheck addons</title>
|
|
|
|
<para>Cppcheck generates dump files in XML format that contains:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Token list</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Syntax trees</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Symbol database (functions, classes, variables, all scopes,
|
|
..)</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Known values (value flow analysis)</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Cppcheck can't execute addons directly. There is no direct
|
|
interface. This means there are not much restrictions:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>You can use any licensing you want for your addons</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>You can use an arbitrary script/programming language to write
|
|
addons</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The user interface and output is defined by you</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>You can use addons for other use cases than generating
|
|
warnings</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>For your convenience, Cppcheck provides cppcheckdata.py that you
|
|
can use to access Cppcheck data from Python. Using this is
|
|
optional.</para>
|
|
|
|
<section>
|
|
<title>Example 1 - print all tokens</title>
|
|
|
|
<para>Script:</para>
|
|
|
|
<programlisting>import sys
|
|
import cppcheckdata
|
|
|
|
def printtokens(data):
|
|
for token in data.tokenlist:
|
|
print(token.str)
|
|
|
|
for arg in sys.argv[1:]:
|
|
printtokens(cppcheckdata.parse(arg))</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Example 2 - List all functions</title>
|
|
|
|
<para>Script:</para>
|
|
|
|
<programlisting>import sys
|
|
import cppcheckdata
|
|
|
|
def printfunctions(data):
|
|
for scope in data.scopes:
|
|
if scope.type == 'Function':
|
|
print(scope.className)
|
|
|
|
for arg in sys.argv[1:]:
|
|
printfunctions(cppcheckdata.parse(arg))</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Example 3 - List all classes</title>
|
|
|
|
<para>Script:</para>
|
|
|
|
<programlisting>import sys
|
|
import cppcheckdata
|
|
|
|
def printclasses(data):
|
|
for scope in data.scopes:
|
|
if scope.type == 'Class':
|
|
print(scope.className)
|
|
|
|
for arg in sys.argv[1:]:
|
|
printfunctions(cppcheckdata.parse(arg))</programlisting>
|
|
</section>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>HTML report</title>
|
|
|
|
<para>You can convert the XML output from cppcheck into a HTML report.
|
|
You'll need Python and the pygments module (<ulink
|
|
url="http://pygments.org/">http://pygments.org/</ulink>) for this to work.
|
|
In the Cppcheck source tree there is a folder <filename
|
|
class="directory">htmlreport</filename> that contains a script that
|
|
transforms a Cppcheck XML file into HTML output.</para>
|
|
|
|
<para>This command generates the help screen:</para>
|
|
|
|
<programlisting>htmlreport/cppcheck-htmlreport -h</programlisting>
|
|
|
|
<para>The output screen says:</para>
|
|
|
|
<programlisting>Usage: cppcheck-htmlreport [options]
|
|
|
|
Options:
|
|
-h, --help show this help message and exit
|
|
--file=FILE The cppcheck xml output file to read defects from.
|
|
Default is reading from stdin.
|
|
--report-dir=REPORT_DIR
|
|
The directory where the html report content is written.
|
|
--source-dir=SOURCE_DIR
|
|
Base directory where source code files can be found.</programlisting>
|
|
|
|
<para>An example usage:</para>
|
|
|
|
<programlisting>./cppcheck gui/test.cpp --xml 2> err.xml
|
|
htmlreport/cppcheck-htmlreport --file=err.xml --report-dir=test1 --source-dir=.</programlisting>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Graphical user interface</title>
|
|
|
|
<section>
|
|
<title>Introduction</title>
|
|
|
|
<para>A Cppcheck GUI is available.</para>
|
|
|
|
<para>The main screen is shown immediately when the GUI is
|
|
started.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Check source code</title>
|
|
|
|
<para>Use the <guimenu>Check</guimenu> menu.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Inspecting results</title>
|
|
|
|
<para>The results are shown in a list.</para>
|
|
|
|
<para>You can show/hide certain types of messages through the
|
|
<guimenu>View</guimenu> menu.</para>
|
|
|
|
<para>Results can be saved to an XML file that can later be opened. See
|
|
<literal>Save results to file</literal> and <literal>Open
|
|
XML</literal>.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Settings</title>
|
|
|
|
<para>The language can be changed at any time by using the
|
|
<guimenu>Language</guimenu> menu.</para>
|
|
|
|
<para>More settings are available in <menuchoice>
|
|
<guimenu>Edit</guimenu>
|
|
|
|
<guimenuitem>Preferences</guimenuitem>
|
|
</menuchoice>.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Project files</title>
|
|
|
|
<para>The project files are used to store project specific settings.
|
|
These settings are:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>include folders</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>preprocessor defines</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>As you can read in <link
|
|
linkend="preprocessor-configurations">chapter 3</link> in this manual
|
|
the default is that Cppcheck checks all configurations. So only provide
|
|
preprocessor defines if you want to limit the checking.</para>
|
|
</section>
|
|
</chapter>
|
|
</book>
|