Community
    • Login

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

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    8 Posts 3 Posters 8.1k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • bri235445B
      bri235445
      last edited by bri235445

      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] )
      {

      }

      1 Reply Last reply Reply Quote 0
      • RicardoR
        Ricardo
        last edited by Ricardo

        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.

        1 Reply Last reply Reply Quote 1
        • guy038G
          guy038
          last edited by guy038

          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

          1 Reply Last reply Reply Quote 2
          • bri235445B
            bri235445
            last edited by bri235445

            @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.

            1 Reply Last reply Reply Quote 0
            • guy038G
              guy038
              last edited by guy038

              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

              bri235445B 1 Reply Last reply Reply Quote 0
              • bri235445B
                bri235445 @guy038
                last edited by bri235445

                @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? :-)

                1 Reply Last reply Reply Quote 0
                • guy038G
                  guy038
                  last edited by guy038

                  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

                  bri235445B 1 Reply Last reply Reply Quote 0
                  • bri235445B
                    bri235445 @guy038
                    last edited by bri235445

                    @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

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post
                    The Community of users of the Notepad++ text editor.
                    Powered by NodeBB | Contributors