terryyin / lizard

A simple code complexity analyser without caring about the C/C++ header files or Java imports, supports most of the popular languages.
Other
1.85k stars 250 forks source link

#if and #else directives stop analysis #137

Open Hirse opened 8 years ago

Hirse commented 8 years ago

When you have code with #if and #else directives (that make the syntax incomplete) any following functions will not be found.

In this simplified example a and b are found, c and d (and any potentially following) are not:

static void a(void *param) {}

static void b(void *param) {}

static void c(void *param) {
    if (true &&
    #if defined(WIN32) || defined(OS2) || defined(NETWARE)
        true) {
    #else
        false) {
    #endif
    }
}

static void d(void *param) {}

Found when running lizard on httpd's util.c.

terryyin commented 8 years ago

You can use option -Ecpre to solve this problem. The cpre extension will ignore the code in the #else block.

I plan to put this information in the github wiki. Can I use your example code?

On 19 Jul 2016, at 5:35 AM, Jan Pilzer notifications@github.com wrote:

When you have code with #if and #else directives (that make the syntax incomplete) any following functions will not be found.

In this simplified example a and b are found, c and d (and any potentially following) are not:

static void a(void *param) {}

static void b(void *param) {}

static void c(void *param) { if (true &&

if defined(WIN32) || defined(OS2) || defined(NETWARE)

    true) {
#else
    false) {
#endif
}

}

static void d(void *param) {} Found when running lizard on httpd's util.c https://github.com/apache/httpd/blob/64aca96b7f6a7a3d0fd40acf7fbabe69eed2de48/server/util.c.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/terryyin/lizard/issues/137, or mute the thread https://github.com/notifications/unsubscribe-auth/AAwJYgys9WK61n1AWYoJtTZ3N1h91gZOks5qW_GlgaJpZM4JPKk2.

Hirse commented 8 years ago

Thanks for the quick reply.

Of course, you can use the example code.

danikaZ commented 8 years ago

How are options such as "-Ecpre" specified in python? For example, in lizard.analyze_file("../cpputest/tests/AllTests.cpp")

terryyin commented 8 years ago

@danikaZ there isn't a specific interface yet. You can do this:

import lizard
analyze_file = lizard.FileAnalyzer(lizard.get_extensions(['cpre']))

analyze_file("../cpputest/tests/AllTests.cpp")
bistMania commented 6 years ago

Hi, If you have code with #if 0 directive the tool is confused

int abc() { int xya=0; int www=0; int xxx;

if 0

if(www) xxx=1; else {

endif

xxx=2; //} }

Do you have any workaround for that?

terryyin commented 6 years ago

with option -Ecpre, it will take the block before #else only. But in your case it's very wrong. I don't have a workaround right now (perhaps except to switch the if & else by reverse the logic in your source code.

So lizard is trying to get how complicated the code "looks" rather than "actually is".

I'm thinking perhaps I can let lizard to deal with obvious directives like #if 0 in the future.

bistMania commented 6 years ago

This is quite dangerous. Due to this bug it merged 3 functions into one and reported total CCN that was 3 times higher than it should be.

I think you can change a logic to ignore #if 0 as you do for #else (invert condition just for if 0). For #if 1 your approach will work fine with -Ecpre

Thanks