Function list doesn't detect C functions that have function pointers in the argument list



  • This valid C function is not included in the list:
    void A( void( *call )( void ) )
    {

    }

    And this one is:
    void B( void )
    {

    }

    There is a file functionList.xml that contains regex rules but the regex is already very long, I lack the knowledge to change it correctly.

    Anyone have any idea how to solve this, any C programmers having the same problem?

    Edit:

    Or this variant also isn’t detected:
    void C( int (*s)[10] )
    {

    }



  • Hello,
    I’m also not good in regex, but I think here’s the problem:

    	<function
    	    mainExpr="^[\t ]*((static|const|virtual)[\s]+)?[\w]+([\s]+[\w]+)?([\s]+|\*[\s]+|[\s]+\*|[\s]+\*[\s]+)([\w_]+[\s]*::)?(?!(if|while|for))[\w_]+[\s]*\([^\)\(]*\)([\s]*const[\s]*)?[\n\s]*\{"
    

    Imo, the bad part is this: \([^\)\(]*\)
    It means:

    \( matches the character ( literally
    
    [^\)\(]* match a single character not present below (* Between zero and unlimited times)
        \) matches the character ) literally
        \( matches the character ( literally
    
    \) matches the character ) literally
    

    But… I tried modifying with \((.*)\) so it matches anything inside parens, but it does not work in Np++…

    I also would like to know a solution.



  • Hello bri235445, Ricardo, and All,

    Ricardo, you’re right ! the problem comes from the expression [^\)\(]* that means any sequence, even empty, of characters, different from round brackets

    To match the special case of bri235445 void A( void( *call )( void ) ), I changed that previous class character into [\S ]*

    Remember that the syntax \s is equivalent to the syntax [\t\n\x0B\f\r\x20\xA0]

    => The syntax \S, with the uppercase letter s, means [^\t\n\x0B\f\r\x20\xA0]

    So, my regex [\S ]* matches any sequence, even empty, of a NON blank character OR a space


    Then, knowing that :

    • The syntax \w does match the underscore _

    • The syntax [\s] can be simplified in \s

    => The mainExpr regex of the C parser, with my modification, could be simplified in :

    
    ^[\t ]*((static|const|virtual)\s+)?[\w:]+(\s+\w+)?(\s+|\*\s+|\s+\*|\s+\*\s+)(\w+\s*::)?(?!(if|while|for))\w+\s*\([\S ]*\)(\s*const\s*)?\s*\{
       
    

    Thus, bri235445 :

    • Do a backup copy of the functionList.xml file

    • Open the functionList.xml file, in N++

    • Change, between the double quotes, the mainExpr regex, of the c_function parser, with the regex just above

    • Save the modifications. Then close and restart N++

    => You should notice that you get the functions A and B in the Function List panel, with your text, in C language, that follows :

    void B( void )
    {
    
    }
    
    void A( void( *call )( void ) )
    {
    
    }
    

    I tested with a portable v6.7.9.2 version and everything works fine :-)

    Best Regards,

    guy038

    P.S. :

    Ricardo, your modification (.*) was nearly good :-)

    But it’s very important to remember that the Function List behaves, by default, as the DOT stands for ANY character, even the End of Line characters !

    So, to restrict the matches of a dot to standard characters, only, the right syntax should be (?-s).*. I just suppress the round brackets, surrounding .*, as we don’t need any back-reference \1

    It passes the test, too. However, I think that the syntax [\S ]*, being more restrictive, should be preferred



  • @guy038

    Thank you for your reply. Your version does seem to work.

    Maybe this change could be added to future versions of Notepad++? Implementers should consider that C++ can have the same function definition thus that regex should be changed as well.



  • Hello bri235445 and Ricardo,

    The most important thing is that my regex version doesn’t break anything else !!

    As you’re certainly more acquainted with C/C++ programs than me, it shouldn’t be very difficult, to you, to detect any additional problem :-)

    Cheers,

    guy038



  • @guy038

    It is hard to test for false positives. Thus far I haven’t seen any.

    I have found an example that is a valid C function but it isn’t detected by your regex:

    void ( *complicated( int a , void( *f )( int ) ) ) ( int )
    {
    void( *b )( int ) = NULL ;
    return b ;
    }

    This is a function taking an int and a pointer to a function taking an int and returning nothing, returning a pointer to a function taking an int and returning nothing.

    This is not a common occurrence and actually writing such code is obnoxious. Nevertheless, can you make this work? :-)



  • Hello bri235445,

    I intend to learn C/C++ language, someday. But, I presently know very few, about these languages !

    However, in your previous post, didn’t you forget the name of the function ? I mean something like :

    void D( *complicated( int a ,...., instead of void( *complicated( int a ,....


    In case of a negative answer, can you tell me what name the functionList should return, in that specific case ?

    Regards,

    guy038



  • @guy038

    The name of the function is complicated, so functionList should return complicated as the name.

    You can see it in action here:https://ideone.com/SmDmCF

    It doesn’t do anything useful since it is an example.

    Here is another example:

    float ( *GetPointer( int a ) )[10]
    {
    ( void )a ;
    return NULL ;
    }

    This is a function named GetPointer, taking an int and returning a pointer to an array of 10 float.
    You can see it working here: https://ideone.com/Sxn8WQ


Log in to reply