1. Summary
  2. Files
  3. Support
  4. Report Spam
  5. Create account
  6. Log in

how to add my check addon to cppcheck

developer discussions

how to add my check addon to cppcheck

Postby b0207191 » Thu Feb 27, 2014 9:29 am

i add two file , x.cpp and x.h to /lib/ , and modified the Makefile to add x.o

but when i run cppcheck, i think the function 'test' i placed in the runChecks did not run.

can anyone tell me which step i missed?

following are the main part of my code

Code: Select all
x.h

class CPPCHECKLIB CheckRgos : public Check {
public:
    /** @brief This constructor is used when registering the CheckClass */
    CheckRgos() : Check(myName()) {
    }

    /** @brief This constructor is used when running checks. */
    CheckRgos(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger)
        : Check(myName(), tokenizer, settings, errorLogger) {
    }

    /** @brief Run checks against the normal token list */
    void runChecks(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger) {
        CheckRgos foo(tokenizer, settings, errorLogger);

        // Checks
        foo.test();
    }

    /** @brief Run checks against the simplified token list */
    void runSimplifiedChecks(const Tokenizer*, const Settings*, ErrorLogger*) {
    }

    void test();

x.c

namespace {
    CheckRgos instance;
}
void CheckRgos::test()
{
    cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n";
   while(1){}
}

b0207191
 
Posts: 11
Joined: Thu Feb 20, 2014 7:18 am

Re: how to add my check addon to cppcheck

Postby danielmarjamaki » Fri Feb 28, 2014 6:23 am

that should work as far as I see..

To clarify, when you run make.. can you see in the output that it compiles x.cpp and then uses the x.o when linking the cppcheck binary?
danielmarjamaki
 
Posts: 419
Joined: Wed Oct 12, 2011 7:49 pm

Re: how to add my check addon to cppcheck

Postby danielmarjamaki » Fri Feb 28, 2014 6:39 am

This works for me.. I created a single file called x.cpp and put it in the lib folder. Here is the code (more or less copy pasted from your code)..
Code: Select all
#include "config.h"
#include "check.h"
#include <iostream>

class CPPCHECKLIB CheckRgos : public Check {
public:
    /** @brief This constructor is used when registering the CheckClass */
    CheckRgos() : Check(myName()) {
    }

    /** @brief This constructor is used when running checks. */
    CheckRgos(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger)
        : Check(myName(), tokenizer, settings, errorLogger) {
    }

    /** @brief Run checks against the normal token list */
    void runChecks(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger) {
        CheckRgos foo(tokenizer, settings, errorLogger);

        // Checks
        foo.test();
    }

    /** @brief Run checks against the simplified token list */
    void runSimplifiedChecks(const Tokenizer*, const Settings*, ErrorLogger*) {
    }

    void test() {
        std::cout << "TEST" << std::endl;
    }

private:
    void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {}

    static std::string myName() { return "X"; }

    std::string classInfo() const {
        return "TESTING";
    }
};

// Register this check class (by creating a static instance of it)
namespace {
    CheckRgos instance;
}


I didn't bother to create a .h file but that shouldn't matter.

I recommend that you generate the Makefile using:
Code: Select all
$ cd path-to-cppcheck
$ make dmake
$ ./dmake
danielmarjamaki
 
Posts: 419
Joined: Wed Oct 12, 2011 7:49 pm

Re: how to add my check addon to cppcheck

Postby b0207191 » Fri Feb 28, 2014 7:23 am

well, today i tried again and found something strange.

i scanned two c files with newly complied cppcheck.
when i scan file1.c , the "test" didn't display.
when i scan file2.c, the "test" display several times.
but i thought it should only occur once when scanning each file.
can anyone tell me why?

the scan result is following
# ./cppcheck --enable=all --template=gcc /root/windows/ctest/cocc/file2.c
Checking /root/windows/ctest/cocc/file2.c...
/root/windows/ctest/cocc/file2.c:89: style: The scope of the variable 'dst_ifx' can be reduced.
TEST!!!
:: warning: speak:hahaha!!!!
/root/windows/ctest/cocc/file2.c:95: style: Variable 'dst_ifx' is assigned a value that is never used.
TEST!!!
Checking /root/windows/ctest/cocc/file2.c: CONFIG_PAN...
/root/windows/ctest/cocc/file2.c:540: style: The scope of the variable 'ret' can be reduced.
TEST!!!
TEST!!!
Checking usage of global functions..
/root/windows/ctest/cocc/file2.c:176: style: The function 'abccli_enter_erabcmode_cmd' is never used.
/root/windows/ctest/cocc/file2.c:123: style: The function 'abccli_show_erspan' is never used.
/root/windows/ctest/cocc/file2.c:607: style: The function 'abcerabcdest_ip_cmd' is never used.
/root/windows/ctest/cocc/file2.c:472: style: The function 'abcerabcdscp_cmd' is never used.
/root/windows/ctest/cocc/file2.c:534: style: The function 'abcerabcorg_ip_cmd' is never used.
/root/windows/ctest/cocc/file2.c:376: style: The function 'abcerabcshut_cmd' is never used.
/root/windows/ctest/cocc/file2.c:232: style: The function 'abcerabcsrc_c2p_cmd' is never used.
/root/windows/ctest/cocc/file2.c:279: style: The function 'abcerabcsrc_cmd' is never used.
/root/windows/ctest/cocc/file2.c:426: style: The function 'abcerabcttl_cmd' is never used.
/root/windows/ctest/cocc/file2.c:692: style: The function 'abcerabcvrf_cmd' is never used.
:: information: Cppcheck cannot find all the include files (use --check-config for details)
#
#
#
# ./cppcheck --enable=all --template=gcc /root/windows/ctest/cocc/file1.c
Checking /root/windows/ctest/cocc/file1.c...
/root/windows/ctest/cocc/file1.c:89: error: Invalid number of character ({) when these macros are defined: ''.
Checking usage of global functions..
:: information: Cppcheck cannot find all the include files (use --check-config for details)
#



my test function is written as following
Code: Select all
void CheckRgos::test()
{
   std::cout << "TEST!!!" << std::endl;
    reportError(NULL, Severity::warning, "test!!", "speak:hahaha!!!!");
}
b0207191
 
Posts: 11
Joined: Thu Feb 20, 2014 7:18 am

Re: how to add my check addon to cppcheck

Postby danielmarjamaki » Fri Feb 28, 2014 1:57 pm

test1.c : the file is invalid. there is an error message 'Invalid number of character ({)'. the scan is aborted when that happens.

test2.c : each #if configuration that cppcheck see is checked.
danielmarjamaki
 
Posts: 419
Joined: Wed Oct 12, 2011 7:49 pm

Re: how to add my check addon to cppcheck

Postby b0207191 » Mon Mar 03, 2014 7:45 am

danielmarjamaki wrote:test1.c : the file is invalid. there is an error message 'Invalid number of character ({)'. the scan is aborted when that happens.

test2.c : each #if configuration that cppcheck see is checked.



i see. thanks to danielmarjamaki.

may i ask some questions detail about cppcheck? is there any document describing the structure of abstract syntax tree generated by cppcheck framework?
i tried this code
Code: Select all
    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
      tokold = tok;
    }

    reportError(tokold, Severity::warning, "rgos_test", "speak:a_test!!!");


it seems the "_tokenizer" walk the entire file ,until end of file.

so i guess runChecks of class Check runs exactly once every file?
another question is , what is the difference between 'runSimplifiedChecks' and 'runChecks'>? that is what is the difference between 'the simplified token list' and 'the normal token list'

more general, if i can find something like MSDN for cppcheck dev, it will be more helpful. :)
b0207191
 
Posts: 11
Joined: Thu Feb 20, 2014 7:18 am

Re: how to add my check addon to cppcheck

Postby danielmarjamaki » Wed Mar 05, 2014 8:31 pm

is there any document describing the structure of abstract syntax tree generated by cppcheck framework?


Not right now.

You have to use some trial and error. Look at the --debug output when you run cppcheck on various small code examples.

For instance, you could try writing this in a file 'ast1.c':
Code: Select all
a = b + c(1,2) * d;


Then use cppcheck to look at its ast:
Code: Select all
$ cppcheck --debug --verbose ast1.c
##AST
=
|-a
`-+
  |-b
  `-*
    |-(
    | |-c
    | `-,
    | | |-1
    | | `-2
    `-d


In that output you can see that the operands of the '=' is the 'a' and '+'. The operands of the '+' is 'b' and '*'.

it seems the "_tokenizer" walk the entire file ,until end of file.


Yes. And if there is a #include "x.h" then you'll walk into x.h also.

so i guess runChecks of class Check runs exactly once every file?


Almost.

If you have this code:

Code: Select all
#ifdef X
abcd;
#else
efgh;
#endif


Then the runChecks will be executed twice. The first time no macro is defined and then the tokens will just be "efgh" and ";". The second time the X will be defined and then the tokens will be "abcd" and ";".

another question is , what is the difference between 'runSimplifiedChecks' and 'runChecks'>? that is what is the difference between 'the simplified token list' and 'the normal token list'


The runChecks is executed on the normal token list. And runSimplifiedChecks is executed on the simplified token list.

In the 'normal' token list most simplifications are not used. So the token list will look mostly like the input source code. In the 'simplified' token list all simplifications are used. Which means that all redundant variables are removed, calculations are simplified, unreachable code is removed, etc.

Code example:
Code: Select all
void f() {
    int a[2];
    int x = 3;
    x++;
    a[x] = 0;
}


Normal token list:
Code: Select all
##file 0
1: void f ( ) {
2: int a@1 [ 2 ] ;
3: int x@2 ; x@2 = 3 ;
4: x@2 ++ ;
5: a@1 [ x@2 ] = 0 ;
6: }


Simplified token list:
Code: Select all
##file a.c
1: void f ( ) {
2: int a@1 [ 2 ] ;
3:
4:
5: a@1 [ 4 ] = 0 ;
6: }


The simplifications are focused on exposing errors.

I recommend that you use the 'simplified' token list whenever you can. Only use the 'normal' token list when you really can't use the simplified token list.
danielmarjamaki
 
Posts: 419
Joined: Wed Oct 12, 2011 7:49 pm

Re: how to add my check addon to cppcheck

Postby b0207191 » Thu Mar 06, 2014 2:13 am

well, why the result of './cppcheck --debug --verbose' on my environment does not look like above given?

[code]
### Symbol database ###
Scope: 0x833fdb8
type: Global
className:
classDef: 0
classStart: 0
classEnd: 0
Function: 0x83473e0
name: echo_time_sub [/root/windows/ctest/cppsample/echo_string.c:16]
type: Function
access: Public
hasBody: true
isInline: false
isConst: false
isVirtual: false
isPure: false
isStatic: false
isFriend: false
isExplicit: false
isDefault: false
isDelete: false
isOperator: false
retFuncPtr: false
tokenDef: echo_time_sub [/root/windows/ctest/cppsample/echo_string.c:16]
argDef: [/root/windows/ctest/cppsample/echo_string.c:16]
retDef: long [/root/windows/ctest/cppsample/echo_string.c:16]
retType: 0
token: [/root/windows/ctest/cppsample/echo_string.c:16]
arg: [/root/windows/ctest/cppsample/echo_string.c:16]
nestedIn: Global
functionScope: echo_time_sub [/root/windows/ctest/cppsample/echo_string.c:16]
Variable: 0x834a270
_name: 0x8340170 start [/root/windows/ctest/cppsample/echo_string.c:16]
declarationId: 1
_start: 0x8341c48 struct [/root/windows/ctest/cppsample/echo_string.c:16]
_end: 0x83400f8 * [/root/windows/ctest/cppsample/echo_string.c:16]
_index: 0
_access: Argument
_flags:
isMutable: false
isStatic: false
isExtern: false
isLocal: false
[code]
b0207191
 
Posts: 11
Joined: Thu Feb 20, 2014 7:18 am

Re: how to add my check addon to cppcheck

Postby danielmarjamaki » Thu Mar 06, 2014 7:33 am

The full output should be:

Code: Select all
$ cppcheck --debug --verbose ast1.c
Checking ast1.c...

##file ast1.c
1: a = b + c ( 1 , 2 ) * d ;

### Symbol database ###
Scope: 0011A8A0
    type: Global
    className:
    classDef: 00000000
    classStart: 00000000
    classEnd: 00000000
    nestedIn: 00000000
    definedType: 0023E9F8
    nestedList[0] = ( )
    functionOf: 00000000
    function: 00000000

##AST
=
|-a
`-+
  |-b
  `-*
    |-(
    | |-c
    | `-,
    | | |-1
    | | `-2
    `-d

##Value flow
Line 1
  1:{1}
  2:{2}

$


I hope you get such output too. Otherwise.. what Cppcheck version do you use? I used the 1.64 release to get that output. Latest git head should produce the same output also.
danielmarjamaki
 
Posts: 419
Joined: Wed Oct 12, 2011 7:49 pm


Return to dev

Who is online

Users browsing this forum: Yahoo [Bot] and 1 guest

cron