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 bracketsTo 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 -
-
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
-
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 ofvoid( *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
-
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