manual: rewrote the chapter about cppcheck extensions/addons

This commit is contained in:
Daniel Marjamäki 2015-06-21 15:18:24 +02:00
parent d828cd29cb
commit 49a9b59490
1 changed files with 155 additions and 35 deletions

View File

@ -5,7 +5,7 @@
<bookinfo> <bookinfo>
<title>Cppcheck 1.70 dev</title> <title>Cppcheck 1.70 dev</title>
<date>2015-01-03</date> <date>2015-06-20</date>
</bookinfo> </bookinfo>
<chapter> <chapter>
@ -366,8 +366,8 @@ cppcheck -DA --force file.c</programlisting>
<term><sgmltag>cwe</sgmltag></term> <term><sgmltag>cwe</sgmltag></term>
<listitem> <listitem>
<para>CWE ID for message. This attribute is only used <para>CWE ID for message. This attribute is only used when the CWE
when the CWE ID for the message is known.</para> ID for the message is known.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
@ -1192,7 +1192,8 @@ Checking unusedvar.cpp...
<para>To get started writing rules, see the related articles here:</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><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> <para>The file format for rules is:</para>
@ -1294,53 +1295,172 @@ Checking unusedvar.cpp...
</chapter> </chapter>
<chapter> <chapter>
<title>Cppcheck extensions with Python</title> <title>Cppcheck addons</title>
<para>Using dump files it is possible to write Cppcheck extensions with <para>Cppcheck addons are implemented as standalone scripts or programs.
for instance Python.</para> With Cppcheck addons, you can for instance:</para>
<para>The <literal>cppcheckdata.py</literal> module <itemizedlist>
(<ulink url="http://github.com/danmar/cppcheck/blob/master/tools/cppcheckdata.py">http://github.com/danmar/cppcheck/blob/master/tools/cppcheckdata.py</ulink>) <listitem>
allows you to load such dump file. It contains <para>add extra custom checkers that use sophisticated analysis</para>
<literal>Token</literal>/<literal>Variable</literal>/<literal>ValueFlow.Value</literal>/<literal>Scope</literal> </listitem>
classes that are similar to the <literal>C++</literal> classes in
<literal>Cppcheck</literal>-core. The doxygen information for the <listitem>
<literal>C++</literal> classes should be somewhat useful for Python <para>visualize your code</para>
developers also.</para> </listitem>
<listitem>
<para>etc</para>
</listitem>
</itemizedlist>
<section> <section>
<title>Simple checker: Division by zero</title> <title>Using Cppcheck addons</title>
<para>Here is a simple checker:</para> <para>Currently there are two steps to use an addon:</para>
<programlisting>import cppcheckdata <orderedlist>
<listitem>
<para>Run Cppcheck to generate dump files</para>
</listitem>
data = cppcheckdata.parsedump('1.c.dump') <listitem>
<para>Run the addon on the dump files</para>
</listitem>
</orderedlist>
for token in data.tokenlist: <para>The <literal>--dump</literal> flag is used to generate dump files.
if token.str == '/' or token.str == '%': To generate a dump file for every source file in the foo/ folder:</para>
# Get denominator (2nd operand)
den = token.astOperand2
# Can denominator be zero? <programlisting>cppcheck --dump foo/</programlisting>
if den.getValue(0):
print '[' + token.file + ':' + str(token.linenr) + '] Division by zero'</programlisting>
<para>Example usage:</para> <para>To run a addon script on all dump files in the foo/ folder:</para>
<para><programlisting>cppcheck --dump 1.c <programlisting>python addon.py foo/*.dump</programlisting>
python divzero.py</programlisting></para>
<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, currently just a
simple threadsafety checker:
<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>
<section> <section>
<title>Licensing</title> <title>Writing Cppcheck addons</title>
<para>The dump file is just a xml file, so it is an open interface <para>Cppcheck generates dump files in XML format that contains:</para>
without restrictions. You can use it in any way you need.</para>
<para>The <literal>cppcheckdata.py</literal> is also free to use. No <itemizedlist>
matter if your project is open source or closed source. Use it for any <listitem>
purpose.</para> <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> </section>
</chapter> </chapter>