Code::Blocks Forums

User forums => Help => Topic started by: Folco on May 17, 2010, 06:35:10 pm

Title: Auto-completion of functions pointers in a structure
Post by: Folco on May 17, 2010, 06:35:10 pm
Hi all,

I use a structure defined like that :
Code
typedef struct
{
    int (*Load)();          /* Constructor */
    void (*Unload)();       /* Destructor */
    void (*Manage)();       /* Management handler */
    MODULE_DATA* Data;      /* Used data */
} MODULE;
When typing to write inside members of this structure, only the 'Data' member is displayed in the auto-completion list :

(http://www.mirari.fr/IJPM)

Is it a bug, must I fill a bug report ? Or perhaps I am wrong ?

Infos :
Code::Blocks svn 6218 on Debian Lenny 32 bits.
Package provided by Jens.

BTW : Many thanks, Jens, for your work and for the repo often updated !!!  8)
Title: Re: Auto-completion of functions pointers in a structure
Post by: reckless on May 19, 2010, 12:23:46 pm
not sure its a bug since you allready have the other members declared it correctly shows the missing one.

what happens if you remove Load Data etc from (*ModuleList[*ModuleNum]). ?
Title: Re: Auto-completion of functions pointers in a structure
Post by: ollydbg on May 19, 2010, 03:54:42 pm
Hi all,

I use a structure defined like that :
Code
typedef struct
{
    int (*Load)();          /* Constructor */
    void (*Unload)();       /* Destructor */
    void (*Manage)();       /* Management handler */
    MODULE_DATA* Data;      /* Used data */
} MODULE;


I just do a test, and find that only "Data" will be parsed as a member of this structure. (All the other function pointers were not correctly parsed.)
So, only this member get prompted.
Title: Re: Auto-completion of functions pointers in a structure
Post by: Folco on May 19, 2010, 05:47:25 pm
Quote
what happens if you remove Load Data etc from (*ModuleList[*ModuleNum]). ?
Exactly the same behavior.
Quote
All the other function pointers were not correctly parsed.
So it's should be a bug, and I should fill a bug report ?
Title: Re: Auto-completion of functions pointers in a structure
Post by: reckless on May 23, 2010, 10:48:54 pm
id probably have to say yes as that shouldnt happen.
Title: Re: Auto-completion of functions pointers in a structure
Post by: ollydbg on June 26, 2010, 03:27:07 am
I have find the bug report here:
http://developer.berlios.de/bugs/?func=detailbug&bug_id=17186&group_id=5358

I will try to fix the bug today... :D
Title: Re: Auto-completion of functions pointers in a structure
Post by: ollydbg on June 26, 2010, 03:42:41 am
The test code is "test.h" under ParserTest project. (I'm using the latest CC_branch)
Code
typedef struct
{
    int (*Load)();          /* Constructor */
    void (*Unload)();       /* Destructor */
    void (*Manage)();       /* Management handler */
    MODULE_DATA* Data;      /* Used data */
} MODULE;

And here is the log out put:
Quote
--------------M-a-i-n--L-o-g--------------

000001. Parse() : Parsing ''
000002. InitTokenizer() : m_Filename='test.h', m_FileSize=226.
000003. Init() : m_Filename='test.h'
000004. DoParse() : Loop:m_Str='', token='typedef'
000005. HandleTypedef() : Typedef start
000006. HandleTypedef() : token=struct, peek={
000007. HandleTypedef() : Before HandleClass m_LastUnnamedTokenName=''
000008. HandleClass() : Found class '{'
000009. DoAddToken() : Created token='UnnamedStruct0', file_idx=1, line=1
000010. GetActualTokenType() : Searching within m_Str=''
000011. GetActualTokenType() : Compensated m_Str=''
000012. GetActualTokenType() : Returning ''
000013. DoAddToken() : Prepending ''
000014. DoAddToken() : Added/updated token 'UnnamedStruct0' (0), type '', actual ''. Parent is  (-1)
000015. DoParse() : Loop:m_Str='', token='int'
000016. wxString Tokenizer::ReadBlock(const wxChar&) : line=3, CurrentChar='(', PreviousChar=' ', NextChar='*', leftBrace(()
000017. ReadBlock(): (END) We are now at line 3, CurrentChar='(', PreviousChar=')', NextChar=')'
000018. wxString Tokenizer::ReadBlock(const wxChar&) : line=3, CurrentChar='(', PreviousChar=')', NextChar=')', leftBrace(()
000019. ReadBlock(): (END) We are now at line 3, CurrentChar=';', PreviousChar=')', NextChar=' '
000020. DoParse() : Loop:m_Str='int(*Load)', token='()'
000021. DoParse() : Loop:m_Str='int(*Load)', token=';'
000022. DoParse() : Loop:m_Str='', token='void'
000023. wxString Tokenizer::ReadBlock(const wxChar&) : line=4, CurrentChar='(', PreviousChar=' ', NextChar='*', leftBrace(()
000024. ReadBlock(): (END) We are now at line 4, CurrentChar='(', PreviousChar=')', NextChar=')'
000025. wxString Tokenizer::ReadBlock(const wxChar&) : line=4, CurrentChar='(', PreviousChar=')', NextChar=')', leftBrace(()
000026. ReadBlock(): (END) We are now at line 4, CurrentChar=';', PreviousChar=')', NextChar=' '
000027. DoParse() : Loop:m_Str='void(*Unload)', token='()'
000028. DoParse() : Loop:m_Str='void(*Unload)', token=';'
000029. DoParse() : Loop:m_Str='', token='void'
000030. wxString Tokenizer::ReadBlock(const wxChar&) : line=5, CurrentChar='(', PreviousChar=' ', NextChar='*', leftBrace(()
000031. ReadBlock(): (END) We are now at line 5, CurrentChar='(', PreviousChar=')', NextChar=')'
000032. wxString Tokenizer::ReadBlock(const wxChar&) : line=5, CurrentChar='(', PreviousChar=')', NextChar=')', leftBrace(()
000033. ReadBlock(): (END) We are now at line 5, CurrentChar=';', PreviousChar=')', NextChar=' '
000034. DoParse() : Loop:m_Str='void(*Manage)', token='()'
000035. DoParse() : Loop:m_Str='void(*Manage)', token=';'
000036. DoParse() : Loop:m_Str='', token='MODULE_DATA'
000037. DoParse() : Loop:m_Str='MODULE_DATA ', token='*'
000038. DoParse() : Loop:m_Str='MODULE_DATA ', token='Data'
000039. DoAddToken() : Created token='Data', file_idx=1, line=6
000040. GetActualTokenType() : Searching within m_Str='MODULE_DATA'
000041. GetActualTokenType() : Compensated m_Str='MODULE_DATA'
000042. GetActualTokenType() : Found 'MODULE_DATA'
000043. DoAddToken() : Prepending ''
000044. DoAddToken() : Added/updated token 'Data' (1), type 'MODULE_DATA*', actual 'MODULE_DATA'. Parent is UnnamedStruct0 (0)
000045. DoParse() : Loop:m_Str='MODULE_DATA', token=';'
000046. DoParse() : Loop:m_Str='', token='}'
000047. ReadClsNames() : Adding variable 'MODULE' as '' to '<no-parent>'
000048. DoAddToken() : Created token='MODULE', file_idx=1, line=7
000049. GetActualTokenType() : Searching within m_Str='UnnamedStruct0'
000050. GetActualTokenType() : Compensated m_Str='UnnamedStruct0'
000051. GetActualTokenType() : Found 'UnnamedStruct0'
000052. DoAddToken() : Prepending ''
000053. DoAddToken() : Added/updated token 'MODULE' (2), type 'UnnamedStruct0', actual 'UnnamedStruct0'. Parent is  (-1)
000054. HandleTypedef() : After HandleClass m_LastUnnamedTokenName='UnnamedStruct0'
000055. HandleTypedef() : Pushing component='UnnamedStruct0', typedef args=''
000056.  + 'UnnamedStruct0'
000057. HandleTypedef() : token=;, peek=
000058. HandleTypedef() : Typedef done


--------------T-r-e-e--L-o-g--------------

000059. +class UnnamedStruct0 {...}   [1,1]
000060. MODULE_DATA* UnnamedStruct0::Data   [6,0]
000061. typedef UnnamedStruct0 MODULE   [7,0]


--------------L-i-s-t--L-o-g--------------

000062. class class UnnamedStruct0 {...}   [1,1]
000063. variable MODULE_DATA* UnnamedStruct0::Data   [6,0]
000064. typedef typedef UnnamedStruct0 MODULE   [7,0]


So, you can see, the final "List log", there are only three Tokens found.  :D


Edit

Haha, I find the bug, it seems the function pointer declaration is just something like:

Code
AAA (*BBB) ()

See the screen shot of my debugger.
(http://i683.photobucket.com/albums/vv194/ollydbg_cb/2010-06-26094834.png)
Title: Re: Auto-completion of functions pointers in a structure
Post by: ollydbg on June 26, 2010, 03:57:48 am
Ok, solved by change the code (just comment some lines , :D)

Code
                if (   (peek.GetChar(0) == '(')
                    && m_Options.handleFunctions
                    && m_Str.IsEmpty()
                    && m_EncounteredNamespaces.empty()
                    && m_EncounteredTypeNamespaces.empty()
                    && (!m_pLastParent || m_pLastParent->m_Name != token) ) // if func has same name as current scope (class)
                {
                    int id = m_pTokensTree->TokenExists(token, -1, tkPreprocessor);

                    if (id != -1)
                    {
                        m_Tokenizer.GetToken();
                        HandleMacro(id, peek);
                        m_Str.Clear();
                    }
                    else
                    {
                        //we need to check if it is a function pointer definition here:
                        // like int (* p) ();
                        //wxString arg = m_Tokenizer.GetToken(); // eat args ()
                        m_Str = token;
                    }
                }

Here is the new log file:
Code
--------------M-a-i-n--L-o-g--------------

000001. Parse() : Parsing ''
000002. InitTokenizer() : m_Filename='test.h', m_FileSize=226.
000003. Init() : m_Filename='test.h'
000004. DoParse() : Loop:m_Str='', token='typedef'
000005. HandleTypedef() : Typedef start
000006. HandleTypedef() : token=struct, peek={
000007. HandleTypedef() : Before HandleClass m_LastUnnamedTokenName=''
000008. HandleClass() : Found class '{'
000009. DoAddToken() : Created token='UnnamedStruct0', file_idx=1, line=1
000010. GetActualTokenType() : Searching within m_Str=''
000011. GetActualTokenType() : Compensated m_Str=''
000012. GetActualTokenType() : Returning ''
000013. DoAddToken() : Prepending ''
000014. DoAddToken() : Added/updated token 'UnnamedStruct0' (0), type '', actual ''. Parent is  (-1)
000015. DoParse() : Loop:m_Str='', token='int'
000016. wxString Tokenizer::ReadBlock(const wxChar&) : line=3, CurrentChar='(', PreviousChar=' ', NextChar='*', leftBrace(()
000017. ReadBlock(): (END) We are now at line 3, CurrentChar='(', PreviousChar=')', NextChar=')'
000018. DoParse() : Loop:m_Str='int', token='(*Load)'
000019. wxString Tokenizer::ReadBlock(const wxChar&) : line=3, CurrentChar='(', PreviousChar=')', NextChar=')', leftBrace(()
000020. ReadBlock(): (END) We are now at line 3, CurrentChar=';', PreviousChar=')', NextChar=' '
000021. HandleFunction() : Adding function '(*Load)': m_Str='int'
000022. HandleFunction() : name='(*Load)', args='()', peek=';'
000023. HandleFunction() : !(Ctor/Dtor) '(*Load)', m_Str='int', localParent='<none>'
000024. HandleFunction() : Adding function '(*Load)', ': m_Str='int', enc_ns='nil'.
000025. HandleFunction() : Add token name='(*Load)', args='()', return type='int'
000026. GetStrippedArgs() : args='()'.
000027. GetStrippedArgs() : stripped_args='()'.
000028. DoAddToken() : Created token='(*Load)', file_idx=1, line=3
000029. GetActualTokenType() : Searching within m_Str='int'
000030. GetActualTokenType() : Compensated m_Str='int'
000031. GetActualTokenType() : Found 'int'
000032. DoAddToken() : Prepending ''
000033. DoAddToken() : Added/updated token '(*Load)' (1), type 'int', actual 'int'. Parent is UnnamedStruct0 (0)
000034. DoParse() : Loop:m_Str='', token=';'
000035. DoParse() : Loop:m_Str='', token='void'
000036. wxString Tokenizer::ReadBlock(const wxChar&) : line=4, CurrentChar='(', PreviousChar=' ', NextChar='*', leftBrace(()
000037. ReadBlock(): (END) We are now at line 4, CurrentChar='(', PreviousChar=')', NextChar=')'
000038. DoParse() : Loop:m_Str='void', token='(*Unload)'
000039. wxString Tokenizer::ReadBlock(const wxChar&) : line=4, CurrentChar='(', PreviousChar=')', NextChar=')', leftBrace(()
000040. ReadBlock(): (END) We are now at line 4, CurrentChar=';', PreviousChar=')', NextChar=' '
000041. HandleFunction() : Adding function '(*Unload)': m_Str='void'
000042. HandleFunction() : name='(*Unload)', args='()', peek=';'
000043. HandleFunction() : !(Ctor/Dtor) '(*Unload)', m_Str='void', localParent='<none>'
000044. HandleFunction() : Adding function '(*Unload)', ': m_Str='void', enc_ns='nil'.
000045. HandleFunction() : Add token name='(*Unload)', args='()', return type='void'
000046. GetStrippedArgs() : args='()'.
000047. GetStrippedArgs() : stripped_args='()'.
000048. DoAddToken() : Created token='(*Unload)', file_idx=1, line=4
000049. GetActualTokenType() : Searching within m_Str='void'
000050. GetActualTokenType() : Compensated m_Str='void'
000051. GetActualTokenType() : Found 'void'
000052. DoAddToken() : Prepending ''
000053. DoAddToken() : Added/updated token '(*Unload)' (2), type 'void', actual 'void'. Parent is UnnamedStruct0 (0)
000054. DoParse() : Loop:m_Str='', token=';'
000055. DoParse() : Loop:m_Str='', token='void'
000056. wxString Tokenizer::ReadBlock(const wxChar&) : line=5, CurrentChar='(', PreviousChar=' ', NextChar='*', leftBrace(()
000057. ReadBlock(): (END) We are now at line 5, CurrentChar='(', PreviousChar=')', NextChar=')'
000058. DoParse() : Loop:m_Str='void', token='(*Manage)'
000059. wxString Tokenizer::ReadBlock(const wxChar&) : line=5, CurrentChar='(', PreviousChar=')', NextChar=')', leftBrace(()
000060. ReadBlock(): (END) We are now at line 5, CurrentChar=';', PreviousChar=')', NextChar=' '
000061. HandleFunction() : Adding function '(*Manage)': m_Str='void'
000062. HandleFunction() : name='(*Manage)', args='()', peek=';'
000063. HandleFunction() : !(Ctor/Dtor) '(*Manage)', m_Str='void', localParent='<none>'
000064. HandleFunction() : Adding function '(*Manage)', ': m_Str='void', enc_ns='nil'.
000065. HandleFunction() : Add token name='(*Manage)', args='()', return type='void'
000066. GetStrippedArgs() : args='()'.
000067. GetStrippedArgs() : stripped_args='()'.
000068. DoAddToken() : Created token='(*Manage)', file_idx=1, line=5
000069. GetActualTokenType() : Searching within m_Str='void'
000070. GetActualTokenType() : Compensated m_Str='void'
000071. GetActualTokenType() : Found 'void'
000072. DoAddToken() : Prepending ''
000073. DoAddToken() : Added/updated token '(*Manage)' (3), type 'void', actual 'void'. Parent is UnnamedStruct0 (0)
000074. DoParse() : Loop:m_Str='', token=';'
000075. DoParse() : Loop:m_Str='', token='MODULE_DATA'
000076. DoParse() : Loop:m_Str='MODULE_DATA ', token='*'
000077. DoParse() : Loop:m_Str='MODULE_DATA ', token='Data'
000078. DoAddToken() : Created token='Data', file_idx=1, line=6
000079. GetActualTokenType() : Searching within m_Str='MODULE_DATA'
000080. GetActualTokenType() : Compensated m_Str='MODULE_DATA'
000081. GetActualTokenType() : Found 'MODULE_DATA'
000082. DoAddToken() : Prepending ''
000083. DoAddToken() : Added/updated token 'Data' (4), type 'MODULE_DATA*', actual 'MODULE_DATA'. Parent is UnnamedStruct0 (0)
000084. DoParse() : Loop:m_Str='MODULE_DATA', token=';'
000085. DoParse() : Loop:m_Str='', token='}'
000086. ReadClsNames() : Adding variable 'MODULE' as '' to '<no-parent>'
000087. DoAddToken() : Created token='MODULE', file_idx=1, line=7
000088. GetActualTokenType() : Searching within m_Str='UnnamedStruct0'
000089. GetActualTokenType() : Compensated m_Str='UnnamedStruct0'
000090. GetActualTokenType() : Found 'UnnamedStruct0'
000091. DoAddToken() : Prepending ''
000092. DoAddToken() : Added/updated token 'MODULE' (5), type 'UnnamedStruct0', actual 'UnnamedStruct0'. Parent is  (-1)
000093. HandleTypedef() : After HandleClass m_LastUnnamedTokenName='UnnamedStruct0'
000094. HandleTypedef() : Pushing component='UnnamedStruct0', typedef args=''
000095.  + 'UnnamedStruct0'
000096. HandleTypedef() : token=;, peek=
000097. HandleTypedef() : Typedef done


--------------T-r-e-e--L-o-g--------------

000098. +class UnnamedStruct0 {...} [1,1]
000099. (*Load)() [3,0]
000100. (*Unload)() [4,0]
000101. (*Manage)() [5,0]
000102. MODULE_DATA* UnnamedStruct0::Data [6,0]
000103. typedef UnnamedStruct0 MODULE [7,0]


--------------L-i-s-t--L-o-g--------------

000104. class class UnnamedStruct0 {...} [1,1]
000105. function int UnnamedStruct0::(*Load)() [3,0]
000106. function void UnnamedStruct0::(*Unload)() [4,0]
000107. function void UnnamedStruct0::(*Manage)() [5,0]
000108. variable MODULE_DATA* UnnamedStruct0::Data [6,0]
000109. typedef typedef UnnamedStruct0 MODULE [7,0]


So, you can see the List Log here. It is correct now!!!

I will do more test and publish the patch here later.

Title: Re: Auto-completion of functions pointers in a structure
Post by: blueshake on June 27, 2010, 04:02:28 pm
will be fixed in ccbranch.
Title: Re: Auto-completion of functions pointers in a structure
Post by: ollydbg on June 27, 2010, 04:32:36 pm
will be fixed in ccbranch.

Nice, I have received your patch, And tested, here is the log:
Code
--------------L-i-s-t--L-o-g--------------

000124. typedef typedef void(*dMessageFunction)(int errnum, const char *msg, va_list ap) [2,0]
000125. class class UnnamedStruct0 {...} [4,4]
000126. function UnnamedStruct0::Load() [6,0]
000127. function UnnamedStruct0::Unload() [7,0]
000128. function UnnamedStruct0::Manage() [8,0]
000129. variable MODULE_DATA* UnnamedStruct0::Data [9,0]
000130. typedef typedef UnnamedStruct0 MODULE [10,0]


So, after some more test, we will send to Morten, and soon it will exist in the ccbranch. :D
Title: Re: Auto-completion of functions pointers in a structure
Post by: Folco on July 09, 2010, 11:08:39 am
Many thanks for this job ollydbg. :)
Title: Re: Auto-completion of functions pointers in a structure
Post by: Folco on August 08, 2010, 08:11:00 pm
https://developer.berlios.de/bugs/?func=detailbug&group_id=5358&bug_id=17186 :
Quote
This bug is fixed in the cc_branch, so can be closed.

First, many thanks for the job !

Then, what is the usual procedure ? I have to close myself the bug report, or this is an admin who have to do it ?
Title: Re: Auto-completion of functions pointers in a structure
Post by: ollydbg on August 09, 2010, 01:49:06 am
I think admin(the developer of C::B) can do this. :D
Title: Re: Auto-completion of functions pointers in a structure
Post by: Folco on September 05, 2010, 07:00:55 pm
Does the fix have been imported in the main branch ?
I still get it, using C::B svn 6525 on Debian 32 bits (package by Jens, btw thank you) :
(http://www.mirari.fr/W0Qw)
I don't know how the cc branch is handled, perhaps it hasn't been already merged in the main part of C::B ?
Title: Re: Auto-completion of functions pointers in a structure
Post by: oBFusCATed on September 05, 2010, 07:20:14 pm
Yes, it is not merged