Menu

#119 function call ignored if opening parenthesis on next line

open
5
2013-10-13
2003-06-19
No

When using cscope 15.4 on a set of C files that include
function calls like this

foo
(bar);

with the opening parenthesis of the argument list on
the line
following the function name, cscope recognizes this
instance
of foo as an instance of a C symbol, but not as an instance
of a function call. That is, using the "find functions
calling
this function" command will not find this function
call, but
using "find this C symbol" to find foo will find this
function call.

Simply moving the opening parenthesis to the same line as
the function call allows cscope to recognize the
function call:

foo(
bar);

Discussion

  • Hans-Bernhard Broeker

    Logged In: YES
    user_id=27517

    The root of this limitation is quite obviuos. E.g. in the
    lex version of the scanner:

    {identifier}/[ \t]*\( { /* if a function call */

    The code in fscanner.l is similar in effect, but works
    differently. You can see it explicitly disallows anything
    except blanks and tabs between the function name and the
    opening parenthesis.

    Unfortunately, my attempts at fixing this for the flex
    scanner fscanner.l failed rather miserably: fscanner.c
    exploded to a size of 10 MB, and failed to compile because
    it ran out of memory at about 128 MB.

    Further experimentation will be needed...

     
  • Georg Sauthoff

    Georg Sauthoff - 2013-09-30

    I ran into this bug a few times but until now never recognized that the kind of whitespace between function identifier and opening bracket is significant with cscope ...

    I've patched fscanner.l to work around that limitation.

    A patch against cscope 15.8a:

    --- a/src/fscanner.l
    +++ b/src/fscanner.l
    @@ -536,7 +536,7 @@ if{wsnl}*\( {       /* ignore 'if' */
                    }
    
     <WAS_IDENTIFIER>{       
    -{ws}*\(({wsnl}|{identifier}|{number}|[*&[\]=,.:])*\)([()]|{wsnl})*[:a-zA-Z_#{] {
    +{wsnl}*\(({wsnl}|{identifier}|{number}|[*&[\]=,.:])*\)([()]|{wsnl})*[:a-zA-Z_#{]       {
                            /* a function definition */
                            /* note: "#define a (b) {" and "#if defined(a)\n#"
    
                             * are not fcn definitions! */
    

    The generated lexer has 5 times as much states but the resulting cscope binary runs fine.

    Even on an old 900 Mhz machine the runtime and memory usage of flex/gcc are acceptable (gcc used < 200 MB RSS).

    Of course, placing the opening bracket after a newline probably violates most sane coding styles, but (as always) there are large code bases out there where such a anti-pattern is used.

     
  • Hans-Bernhard Broeker

    Just for completness' sake: you missed the corresponding change in the rule that detects function calls instead of function definitions.

    Well, I just tried again after all these years, and flex still takes at least two minutes(!) just to generate fscanner.l, which ends up 20 times as big as the current version. I consider that excessive cost for negligible gain.

    And it's only one flex option away from total failure, too: flex -F8 died of memory exhaustion in m4 after 6 minutes; flex -f8 did manage to complete its 150 MB whopper in 10 minutes, but that contains hundreds of overflows of 16-bit integers in its tables, so the scanner most likely won't work.

     

    Last edit: Hans-Bernhard Broeker 2013-10-03
  • Georg Sauthoff

    Georg Sauthoff - 2013-10-13

    I did not miss the corresponding change. I deliberately omitted that other change because a) I rarely observe such function calls (not even in large code-bases where consistently opening brackets in declarations are put after a newline) and b) to avoid a further explosion of DFA states in the generated lexer code.

    I do not suggest that you apply the patch as is. I just posted it as workaround for people who need a quick-fix right now. With that single change the number of states grows 5 times - which is acceptable for a workaround.

    But this white-space issue really is an arbitrary limitation one usually finds only in proprietary or unmaintained historic software. It's kind of embarrassing.

     

Log in to post a comment.

MongoDB Logo MongoDB