Developer forums (C::B DEVELOPMENT STRICTLY!) > CodeCompletion redesign

Is it possible for the parser to support newlib prototypes?

<< < (7/12) > >>

ollydbg:

--- Quote from: White-Tiger on September 14, 2014, 12:23:03 pm ---Yay! for the function pointer patch xD It finally works^^ (ok didn't test it, but I'm using them in different projects and they didn't work most of the time..)
It's weird though.. I've thought Code::Blocks was able to handle them as they sometimes seemed to work.. just didn't most of the time :P

--- End quote ---
Does the trunk fix your but report here Re: The 06 July 2014 build (9844) is out.?

White-Tiger:
yes an no.. the reported case works, same for the real world code I based it on... (at least it looks like that, didn't miss any function)
But another case I've used to work with, does not work.

I'll post the almost non-stripped code just in case there's another "bug" (had to strip it a bit because of 20k character limit for posts^^)

--- Code: (c++) ---#include <stdint.h>
typedef uint64_t uint64;
typedef unsigned short anyID;
#define TS3_VECTOR anyID
enum LogLevel{a,b,c,};
#define PluginMessageTarget LogLevel
#define PluginItemType LogLevel
#define PluginGuiProfile LogLevel
#define PluginConnectTab LogLevel


struct TS3Functions {
unsigned int (*getClientLibVersion)(char** result);
unsigned int (*getClientLibVersionNumber)(uint64* result);
unsigned int (*spawnNewServerConnectionHandler)(int port, uint64* result);
unsigned int (*destroyServerConnectionHandler)(uint64 serverConnectionHandlerID);

/* Error handling */
unsigned int (*getErrorMessage)(unsigned int errorCode, char** error);

/* Memory management */
unsigned int (*freeMemory)(void* pointer);

/* Logging */
unsigned int (*logMessage)(const char* logMessage, enum LogLevel severity, const char* channel, uint64 logID);

/* Sound */
unsigned int (*getPlaybackDeviceList)(const char* modeID, char**** result);
unsigned int (*getPlaybackModeList)(char*** result);
unsigned int (*getCaptureDeviceList)(const char* modeID, char**** result);
unsigned int (*getCaptureModeList)(char*** result);
unsigned int (*getDefaultPlaybackDevice)(const char* modeID, char*** result);
unsigned int (*getDefaultPlayBackMode)(char** result);
unsigned int (*getDefaultCaptureDevice)(const char* modeID, char*** result);
unsigned int (*getDefaultCaptureMode)(char** result);
unsigned int (*openPlaybackDevice)(uint64 serverConnectionHandlerID, const char* modeID, const char* playbackDevice);
unsigned int (*openCaptureDevice)(uint64 serverConnectionHandlerID, const char* modeID, const char* captureDevice);
unsigned int (*getCurrentPlaybackDeviceName)(uint64 serverConnectionHandlerID, char** result, int* isDefault);
unsigned int (*getCurrentPlayBackMode)(uint64 serverConnectionHandlerID, char** result);
unsigned int (*getCurrentCaptureDeviceName)(uint64 serverConnectionHandlerID, char** result, int* isDefault);
unsigned int (*getCurrentCaptureMode)(uint64 serverConnectionHandlerID, char** result);
unsigned int (*initiateGracefulPlaybackShutdown)(uint64 serverConnectionHandlerID);
unsigned int (*closePlaybackDevice)(uint64 serverConnectionHandlerID);
unsigned int (*closeCaptureDevice)(uint64 serverConnectionHandlerID);
unsigned int (*activateCaptureDevice)(uint64 serverConnectionHandlerID);
unsigned int (*playWaveFileHandle)(uint64 serverConnectionHandlerID, const char* path, int loop, uint64* waveHandle);
unsigned int (*pauseWaveFileHandle)(uint64 serverConnectionHandlerID, uint64 waveHandle, int pause);
unsigned int (*closeWaveFileHandle)(uint64 serverConnectionHandlerID, uint64 waveHandle);
unsigned int (*playWaveFile)(uint64 serverConnectionHandlerID, const char* path);
unsigned int (*registerCustomDevice)(const char* deviceID, const char* deviceDisplayName, int capFrequency, int capChannels, int playFrequency, int playChannels);
unsigned int (*unregisterCustomDevice)(const char* deviceID);
unsigned int (*processCustomCaptureData)(const char* deviceName, const short* buffer, int samples);
unsigned int (*acquireCustomPlaybackData)(const char* deviceName, short* buffer, int samples);

/* Preprocessor */
unsigned int (*getPreProcessorInfoValueFloat)(uint64 serverConnectionHandlerID, const char* ident, float* result);
unsigned int (*getPreProcessorConfigValue)(uint64 serverConnectionHandlerID, const char* ident, char** result);
unsigned int (*setPreProcessorConfigValue)(uint64 serverConnectionHandlerID, const char* ident, const char* value);

/* Encoder */
unsigned int (*getEncodeConfigValue)(uint64 serverConnectionHandlerID, const char* ident, char** result);

/* Playback */
unsigned int (*getPlaybackConfigValueAsFloat)(uint64 serverConnectionHandlerID, const char* ident, float* result);
unsigned int (*setPlaybackConfigValue)(uint64 serverConnectionHandlerID, const char* ident, const char* value);
unsigned int (*setClientVolumeModifier)(uint64 serverConnectionHandlerID, anyID clientID, float value);

/* Recording */
unsigned int (*startVoiceRecording)(uint64 serverConnectionHandlerID);
unsigned int (*stopVoiceRecording)(uint64 serverConnectionHandlerID);

/* 3d sound positioning */
unsigned int (*systemset3DListenerAttributes) (uint64 serverConnectionHandlerID, const TS3_VECTOR* position, const TS3_VECTOR* forward, const TS3_VECTOR* up);
unsigned int (*set3DWaveAttributes) (uint64 serverConnectionHandlerID, uint64 waveHandle, const TS3_VECTOR* position);
unsigned int (*systemset3DSettings) (uint64 serverConnectionHandlerID, float distanceFactor, float rolloffScale);
unsigned int (*channelset3DAttributes) (uint64 serverConnectionHandlerID, anyID clientID, const TS3_VECTOR* position);

/* Interaction with the server */
unsigned int (*startConnection)(uint64 serverConnectionHandlerID, const char* identity, const char* ip, unsigned int port, const char* nickname,
                               const char** defaultChannelArray, const char* defaultChannelPassword, const char* serverPassword);
unsigned int (*stopConnection)(uint64 serverConnectionHandlerID, const char* quitMessage);
unsigned int (*requestClientMove)(uint64 serverConnectionHandlerID, anyID clientID, uint64 newChannelID, const char* password, const char* returnCode);
unsigned int (*requestClientVariables)(uint64 serverConnectionHandlerID, anyID clientID, const char* returnCode);
unsigned int (*requestClientKickFromChannel)(uint64 serverConnectionHandlerID, anyID clientID, const char* kickReason, const char* returnCode);
unsigned int (*requestClientKickFromServer)(uint64 serverConnectionHandlerID, anyID clientID, const char* kickReason, const char* returnCode);
unsigned int (*requestChannelDelete)(uint64 serverConnectionHandlerID, uint64 channelID, int force, const char* returnCode);
unsigned int (*requestChannelMove)(uint64 serverConnectionHandlerID, uint64 channelID, uint64 newChannelParentID, uint64 newChannelOrder, const char* returnCode);
unsigned int (*requestSendPrivateTextMsg)(uint64 serverConnectionHandlerID, const char* message, anyID targetClientID, const char* returnCode);
unsigned int (*requestSendChannelTextMsg)(uint64 serverConnectionHandlerID, const char* message, uint64 targetChannelID, const char* returnCode);
unsigned int (*requestSendServerTextMsg)(uint64 serverConnectionHandlerID, const char* message, const char* returnCode);
unsigned int (*requestConnectionInfo)(uint64 serverConnectionHandlerID, anyID clientID, const char* returnCode);
unsigned int (*requestClientSetWhisperList)(uint64 serverConnectionHandlerID, anyID clientID, const uint64* targetChannelIDArray, const anyID* targetClientIDArray, const char* returnCode);
unsigned int (*requestChannelSubscribe)(uint64 serverConnectionHandlerID, const uint64* channelIDArray, const char* returnCode);
unsigned int (*requestChannelSubscribeAll)(uint64 serverConnectionHandlerID, const char* returnCode);
unsigned int (*requestChannelUnsubscribe)(uint64 serverConnectionHandlerID, const uint64* channelIDArray, const char* returnCode);
unsigned int (*requestChannelUnsubscribeAll)(uint64 serverConnectionHandlerID, const char* returnCode);
unsigned int (*requestChannelDescription)(uint64 serverConnectionHandlerID, uint64 channelID, const char* returnCode);
unsigned int (*requestMuteClients)(uint64 serverConnectionHandlerID, const anyID* clientIDArray, const char* returnCode);
unsigned int (*requestUnmuteClients)(uint64 serverConnectionHandlerID, const anyID* clientIDArray, const char* returnCode);
unsigned int (*requestClientPoke)(uint64 serverConnectionHandlerID, anyID clientID, const char* message, const char* returnCode);
unsigned int (*requestClientIDs)(uint64 serverConnectionHandlerID, const char* clientUniqueIdentifier, const char* returnCode);
unsigned int (*clientChatClosed)(uint64 serverConnectionHandlerID, const char* clientUniqueIdentifier, anyID clientID, const char* returnCode);
unsigned int (*clientChatComposing)(uint64 serverConnectionHandlerID, anyID clientID, const char* returnCode);
unsigned int (*requestServerTemporaryPasswordAdd)(uint64 serverConnectionHandlerID, const char* password, const char* description, uint64 duration, uint64 targetChannelID, const char* targetChannelPW, const char* returnCode);
unsigned int (*requestServerTemporaryPasswordDel)(uint64 serverConnectionHandlerID, const char* password, const char* returnCode);
unsigned int (*requestServerTemporaryPasswordList)(uint64 serverConnectionHandlerID, const char* returnCode);

/* Access clientlib information */

/* Query own client ID */
unsigned int (*getClientID)(uint64 serverConnectionHandlerID, anyID* result);

/* Client info */
unsigned int (*getClientSelfVariableAsInt)(uint64 serverConnectionHandlerID, size_t flag, int* result);
unsigned int (*getClientSelfVariableAsString)(uint64 serverConnectionHandlerID, size_t flag, char** result);
unsigned int (*setClientSelfVariableAsInt)(uint64 serverConnectionHandlerID, size_t flag, int value);
unsigned int (*setClientSelfVariableAsString)(uint64 serverConnectionHandlerID, size_t flag, const char* value);
unsigned int (*flushClientSelfUpdates)(uint64 serverConnectionHandlerID, const char* returnCode);
unsigned int (*getClientVariableAsInt)(uint64 serverConnectionHandlerID, anyID clientID, size_t flag, int* result);
unsigned int (*getClientVariableAsUInt64)(uint64 serverConnectionHandlerID, anyID clientID, size_t flag, uint64* result);
unsigned int (*getClientVariableAsString)(uint64 serverConnectionHandlerID, anyID clientID, size_t flag, char** result);
unsigned int (*getClientList)(uint64 serverConnectionHandlerID, anyID** result);
unsigned int (*getChannelOfClient)(uint64 serverConnectionHandlerID, anyID clientID, uint64* result);

/* Channel info */
unsigned int (*getChannelVariableAsInt)(uint64 serverConnectionHandlerID, uint64 channelID, size_t flag, int* result);
unsigned int (*getChannelVariableAsUInt64)(uint64 serverConnectionHandlerID, uint64 channelID, size_t flag, uint64* result);
unsigned int (*getChannelVariableAsString)(uint64 serverConnectionHandlerID, uint64 channelID, size_t flag, char** result);
unsigned int (*getChannelIDFromChannelNames)(uint64 serverConnectionHandlerID, char** channelNameArray, uint64* result);
unsigned int (*setChannelVariableAsInt)(uint64 serverConnectionHandlerID, uint64 channelID, size_t flag, int value);
unsigned int (*setChannelVariableAsUInt64)(uint64 serverConnectionHandlerID, uint64 channelID, size_t flag, uint64 value);
unsigned int (*setChannelVariableAsString)(uint64 serverConnectionHandlerID, uint64 channelID, size_t flag, const char* value);
unsigned int (*flushChannelUpdates)(uint64 serverConnectionHandlerID, uint64 channelID, const char* returnCode);
unsigned int (*flushChannelCreation)(uint64 serverConnectionHandlerID, uint64 channelParentID, const char* returnCode);
unsigned int (*getChannelList)(uint64 serverConnectionHandlerID, uint64** result);
unsigned int (*getChannelClientList)(uint64 serverConnectionHandlerID, uint64 channelID,  anyID** result);
unsigned int (*getParentChannelOfChannel)(uint64 serverConnectionHandlerID, uint64 channelID, uint64* result);

/* Server info */
unsigned int (*getServerConnectionHandlerList)(uint64** result);
unsigned int (*getServerVariableAsInt)(uint64 serverConnectionHandlerID, size_t flag, int* result);
unsigned int (*getServerVariableAsUInt64)(uint64 serverConnectionHandlerID, size_t flag, uint64* result);
unsigned int (*getServerVariableAsString)(uint64 serverConnectionHandlerID, size_t flag, char** result);
unsigned int (*requestServerVariables)(uint64 serverConnectionHandlerID);

/* Connection info */
unsigned int (*getConnectionStatus)(uint64 serverConnectionHandlerID, int* result);
unsigned int (*getConnectionVariableAsUInt64)(uint64 serverConnectionHandlerID, anyID clientID, size_t flag, uint64* result);
unsigned int (*getConnectionVariableAsDouble)(uint64 serverConnectionHandlerID, anyID clientID, size_t flag, double* result);
unsigned int (*getConnectionVariableAsString)(uint64 serverConnectionHandlerID, anyID clientID, size_t flag, char** result);
unsigned int (*cleanUpConnectionInfo)(uint64 serverConnectionHandlerID, anyID clientID);

/* Client related */
unsigned int (*requestClientDBIDfromUID)(uint64 serverConnectionHandlerID, const char* clientUniqueIdentifier, const char* returnCode);
unsigned int (*requestClientNamefromUID)(uint64 serverConnectionHandlerID, const char* clientUniqueIdentifier, const char* returnCode);
unsigned int (*requestClientNamefromDBID)(uint64 serverConnectionHandlerID, uint64 clientDatabaseID, const char* returnCode);
unsigned int (*requestClientEditDescription)(uint64 serverConnectionHandlerID, anyID clientID, const char* clientDescription, const char* returnCode);
unsigned int (*requestClientSetIsTalker)(uint64 serverConnectionHandlerID, anyID clientID, int isTalker, const char* returnCode);
unsigned int (*requestIsTalker)(uint64 serverConnectionHandlerID, int isTalkerRequest, const char* isTalkerRequestMessage, const char* returnCode);

/* Plugin related */
unsigned int (*requestSendClientQueryCommand)(uint64 serverConnectionHandlerID, const char* command, const char* returnCode);

/* Filetransfer */
unsigned int (*getTransferFileName)(anyID transferID, char** result);
unsigned int (*getTransferFilePath)(anyID transferID, char** result);
unsigned int (*getTransferFileSize)(anyID transferID, uint64* result);
unsigned int (*getTransferFileSizeDone)(anyID transferID, uint64* result);
unsigned int (*isTransferSender)(anyID transferID, int* result);  /* 1 == upload, 0 == download */
unsigned int (*getTransferStatus)(anyID transferID, int* result);
unsigned int (*getCurrentTransferSpeed)(anyID transferID, float* result);
unsigned int (*getAverageTransferSpeed)(anyID transferID, float* result);
unsigned int (*getTransferRunTime)(anyID transferID, uint64* result);
unsigned int (*sendFile)(uint64 serverConnectionHandlerID, uint64 channelID, const char* channelPW, const char* file, int overwrite, int resume, const char* sourceDirectory, anyID* result, const char* returnCode);
unsigned int (*requestFile)(uint64 serverConnectionHandlerID, uint64 channelID, const char* channelPW, const char* file, int overwrite, int resume, const char* destinationDirectory, anyID* result, const char* returnCode);
unsigned int (*haltTransfer)(uint64 serverConnectionHandlerID, anyID transferID, int deleteUnfinishedFile, const char* returnCode);
unsigned int (*requestFileList)(uint64 serverConnectionHandlerID, uint64 channelID, const char* channelPW, const char* path, const char* returnCode);
unsigned int (*requestFileInfo)(uint64 serverConnectionHandlerID, uint64 channelID, const char* channelPW, const char* file, const char* returnCode);
unsigned int (*requestDeleteFile)(uint64 serverConnectionHandlerID, uint64 channelID, const char* channelPW, const char** file, const char* returnCode);
unsigned int (*requestCreateDirectory)(uint64 serverConnectionHandlerID, uint64 channelID, const char* channelPW, const char* directoryPath, const char* returnCode);
unsigned int (*requestRenameFile)(uint64 serverConnectionHandlerID, uint64 fromChannelID, const char* channelPW, uint64 toChannelID, const char* toChannelPW, const char* oldFile, const char* newFile, const char* returnCode);

/** [...] **/

/* Client functions */
void         (*getAppPath)(char* path, size_t maxLen);
void         (*getResourcesPath)(char* path, size_t maxLen);
void         (*getConfigPath)(char* path, size_t maxLen);
void         (*getPluginPath)(char* path, size_t maxLen);
uint64       (*getCurrentServerConnectionHandlerID)();
void         (*printMessage)(uint64 serverConnectionHandlerID, const char* message, enum PluginMessageTarget messageTarget);
void         (*printMessageToCurrentTab)(const char* message);
void         (*urlsToBB)(const char* text, char* result, size_t maxLen);
void         (*sendPluginCommand)(uint64 serverConnectionHandlerID, const char* pluginID, const char* command, int targetMode, const anyID* targetIDs, const char* returnCode);
void         (*getDirectories)(const char* path, char* result, size_t maxLen);
unsigned int (*getServerConnectInfo)(uint64 scHandlerID, char* host, unsigned short* port, char* password, size_t maxLen);
unsigned int (*getChannelConnectInfo)(uint64 scHandlerID, uint64 channelID, char* path, char* password, size_t maxLen);
void         (*createReturnCode)(const char* pluginID, char* returnCode, size_t maxLen);
unsigned int (*requestInfoUpdate)(uint64 scHandlerID, enum PluginItemType itemType, uint64 itemID);
uint64       (*getServerVersion)(uint64 scHandlerID);
unsigned int (*isWhispering)(uint64 scHandlerID, anyID clientID, int* result);
unsigned int (*isReceivingWhisper)(uint64 scHandlerID, anyID clientID, int* result);
unsigned int (*getAvatar)(uint64 scHandlerID, anyID clientID, char* result, size_t maxLen);
void         (*setPluginMenuEnabled)(const char* pluginID, int menuID, int enabled);
void         (*showHotkeySetup)();
void         (*requestHotkeyInputDialog)(const char* pluginID, const char* keyword, int isDown, void* qParentWindow);
unsigned int (*getHotkeyFromKeyword)(const char* pluginID, const char** keywords, char** hotkeys, size_t arrayLen, size_t hotkeyBufSize);
unsigned int (*getClientDisplayName)(uint64 scHandlerID, anyID clientID, char* result, size_t maxLen);
unsigned int (*getBookmarkList)(struct PluginBookmarkList** list);
unsigned int (*getProfileList)(enum PluginGuiProfile profile, int* defaultProfileIdx, char*** result);
unsigned int (*guiConnect)(enum PluginConnectTab connectTab, const char* serverLabel, const char* serverAddress, const char* serverPassword, const char* nickname, const char* channel, const char* channelPassword, const char* captureProfile, const char* playbackProfile, const char* hotkeyProfile, const char* soundProfile, const char* userIdentity, const char* oneTimeKey, const char* phoneticName, uint64* scHandlerID);
unsigned int (*guiConnectBookmark)(enum PluginConnectTab connectTab, const char* bookmarkuuid, uint64* scHandlerID);
unsigned int (*createBookmark)(const char* bookmarkuuid, const char* serverLabel, const char* serverAddress, const char* serverPassword, const char* nickname, const char* channel, const char* channelPassword, const char* captureProfile, const char* playbackProfile, const char* hotkeyProfile, const char* soundProfile, const char* uniqueUserId, const char* oneTimeKey, const char* phoneticName);
unsigned int (*getPermissionIDByName)(uint64 serverConnectionHandlerID, const char* permissionName, unsigned int* result);
unsigned int (*getClientNeededPermission)(uint64 serverConnectionHandlerID, const char* permissionName, int* result);
};
TS3Functions.

--- End code ---

Basically the problem already appears at the first function... at "getClientLibVersion"... it's detected... but only as
public int(* getClientLibVersion): unsignedSo there's a problem with unsigned int as a return because it only picks up the first identifier...

It also corrupts the code-completion popup... sometimes you'll get a different declaration to the right then, the selected function on the left...
Looks like this:

ollydbg:

--- Quote from: ollydbg on September 12, 2014, 04:38:16 pm ---
--- Quote ---
--- Quote from: ollydbg on September 12, 2014, 04:15:54 am ---BTW: by the way, maybe, the two condition:
[...]
Those two conditions can be merged or some refactored, but I'm not quite sure. E.g. extract the handling macro usage, and merge handling of function decl or function ptr in one condition. This can be a new commit.  :D

--- End quote ---
I agree we can separate the macro handling and merge the function handling.
We can think about supporting more cases for macro handling too. We currently handle function-like macros, and only when m_Str is empty, eg:

--- Code: ---some code;
MACRO(); // expand this
more code;
--- End code ---
Sometimes the macro is not the first token in the line, so m_Str is non-empty, just like the bug reported by the original poster in this thread:

--- Code: ---FILE * _EXFUN(fopen, (const char *__restrict _name, const char *__restrict _type));
--- End code ---
Those can be handled.. and also variable-like macros..

--- End quote ---
Good catch, though it will increase the parsing time, but I think it is worthy. This can remove my own hack on the user defined macro replacement rule.

--- End quote ---

Maybe, a better method is to try expand every identifier like token if possible, I remembered you have a patch named "cc_parser_general.patch", but when I looked at that patch in my PC, I see that patch contains too many things. (a lot of them is already in trunk)

To enable this feature, we can just do this patch:

--- Code: --- src/plugins/codecompletion/parser/tokenizer.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/plugins/codecompletion/parser/tokenizer.cpp b/src/plugins/codecompletion/parser/tokenizer.cpp
index f47e8dd..31f0546 100644
--- a/src/plugins/codecompletion/parser/tokenizer.cpp
+++ b/src/plugins/codecompletion/parser/tokenizer.cpp
@@ -1246,8 +1246,8 @@ wxString Tokenizer::DoGetToken()
 void Tokenizer::ReplaceMacro(wxString& str)
 {
     // this indicates we are already in macro replacement mode
-    if (m_RepeatReplaceCount > 0)
-    {
+//    if (m_RepeatReplaceCount > 0)
+//    {
         const int id = m_TokenTree->TokenExists(str, -1, tkMacroDef);
         if (id != -1)
         {
@@ -1270,8 +1270,9 @@ void Tokenizer::ReplaceMacro(wxString& str)
         // if in macro expansion mode, we don't want to let the user replacement rule executed
         // again, so just returned
         return;
-    }
+//    }
 
+#if 0
     wxStringHashMap::const_iterator it = s_Replacements.find(str);
     if (it == s_Replacements.end())
         return;
@@ -1344,6 +1345,7 @@ void Tokenizer::ReplaceMacro(wxString& str)
         if (it->second != str && ReplaceBufferText(it->second, false))
             str = DoGetToken();
     }
+#endif
 }
 
 bool Tokenizer::CalcConditionExpression()

--- End code ---

Thus, we totally remove all the user defined replacement rules.
I just test the patch, the parsing time is a bit longer, but not too much.  ;D
Another smart method is that we can only check the macro usage on the identifier like token which has all capital characters or underscore.

ollydbg:

--- Quote from: White-Tiger on September 14, 2014, 04:30:30 pm ---yes an no.. the reported case works, same for the real world code I based it on... (at least it looks like that, didn't miss any function)
But another case I've used to work with, does not work.

I'll post the almost non-stripped code just in case there's another "bug" (had to strip it a bit because of 20k character limit for posts^^)
...

Basically the problem already appears at the first function... at "getClientLibVersion"... it's detected... but only as
public int(* getClientLibVersion): unsignedSo there's a problem with unsigned int as a return because it only picks up the first identifier...

--- End quote ---

Thanks for the sample code.
OK, I can strip the test code (can be run in cctest project)

--- Code: ---
struct TS3Functions {
unsigned int (*getClientLibVersion)(char** result);
unsigned int (*getClientLibVersionNumber)(uint64* result);
};

TS3Functions a;


//a.    //getClientLibVersion

--- End code ---

The result is:

--- Code: ---000001. --------------M-a-i-n--L-o-g--------------


000002. -----------I-n-t-e-r-i-m--L-o-g-----------
000003. InitTokenizer() : m_Filename='F:\cb_sf_git\trunk\src\plugins\codecompletion\testing\ccc_function_ptr.cpp', m_FileSize=255.
000004. Init() : m_Filename='F:\cb_sf_git\trunk\src\plugins\codecompletion\testing\ccc_function_ptr.cpp'
000005. F:\cb_sf_git\trunk\src\plugins\codecompletion\testing\ccc_function_ptr.cpp
000006. Parse() : Parsing 'F:\cb_sf_git\trunk\src\plugins\codecompletion\testing\ccc_function_ptr.cpp'
000007. SkipComment() : Start from line = 1
000008. DoParse() : Loop:m_Str='', token='struct'
000009. HandleClass() : Found class 'TS3Functions', next='{'
000010. GetRealTypeIfTokenIsMacro() : tokenIsMacro=no -> tokenName='TS3Functions'.
000011. DoAddToken() : Created token='TS3Functions', file_idx=1, line=5, ticket=256
000012. GetTokenBaseType() : Searching within m_Str=''
000013. GetTokenBaseType() : Compensated m_Str=''
000014. GetTokenBaseType() : Returning ''
000015. DoAddToken() : Prepending ''
000016. DoAddToken() : Added/updated token 'TS3Functions' (0), kind 'class', type '', actual ''. Parent is  (-1)
000017. DoParse() : Loop:m_Str='', token='unsigned'
000018. DoParse() : Loop:m_Str='unsigned ', token='int'
000019. ReadParentheses(): (* getClientLibVersion), line=6
000020. HandleFunction() : Adding function 'int': m_Str='unsigned '
000021. ReadParentheses(): (char** result), line=6
000022. HandleFunction() : name='int', args='(* getClientLibVersion)', peek='(char** result)'
000023. HandleFunction() : !(Ctor/Dtor) 'int', m_Str='unsigned ', localParent='<none>'
000024. HandleFunction() : Adding function 'int', ': m_Str='unsigned ', enc_ns='nil'.
000025. HandleFunction() : Possible macro '(char** result)' in function 'int' (file name='F:\cb_sf_git\trunk\src\plugins\codecompletion\testing\ccc_function_ptr.cpp', line numer 6).
000026. HandleFunction() : Add token name='int', args='(* getClientLibVersion)', return type='unsigned '
000027. GetBaseArgs() : args='(* getClientLibVersion)'.
000028. GetBaseArgs() : baseArgs='(*)'.
000029. DoAddToken() : Created token='int', file_idx=1, line=6, ticket=257
000030. GetTokenBaseType() : Searching within m_Str='unsigned'
000031. GetTokenBaseType() : Compensated m_Str='unsigned'
000032. GetTokenBaseType() : Found 'unsigned'
000033. DoAddToken() : Prepending ''
000034. DoAddToken() : Added/updated token 'int' (1), kind 'function', type 'unsigned', actual 'unsigned'. Parent is TS3Functions (0)
000035. DoParse() : Loop:m_Str='', token='(char** result)'
000036. DoParse() : Loop:m_Str='', token=';'
000037. DoParse() : Loop:m_Str='', token='unsigned'
000038. DoParse() : Loop:m_Str='unsigned ', token='int'
000039. ReadParentheses(): (* getClientLibVersionNumber), line=7
000040. HandleFunction() : Adding function 'int': m_Str='unsigned '
000041. ReadParentheses(): (uint64* result), line=7
000042. HandleFunction() : name='int', args='(* getClientLibVersionNumber)', peek='(uint64* result)'
000043. HandleFunction() : !(Ctor/Dtor) 'int', m_Str='unsigned ', localParent='<none>'
000044. HandleFunction() : Adding function 'int', ': m_Str='unsigned ', enc_ns='nil'.
000045. HandleFunction() : Possible macro '(uint64* result)' in function 'int' (file name='F:\cb_sf_git\trunk\src\plugins\codecompletion\testing\ccc_function_ptr.cpp', line numer 7).
000046. HandleFunction() : Add token name='int', args='(* getClientLibVersionNumber)', return type='unsigned '
000047. GetBaseArgs() : args='(* getClientLibVersionNumber)'.
000048. GetBaseArgs() : baseArgs='(*)'.
000049. DoAddToken() : Found token (parent).
000050. GetTokenBaseType() : Searching within m_Str='unsigned'
000051. GetTokenBaseType() : Compensated m_Str='unsigned'
000052. GetTokenBaseType() : Found 'unsigned'
000053. DoAddToken() : Prepending ''
000054. DoAddToken() : Added/updated token 'int' (1), kind 'function', type 'unsigned', actual 'unsigned'. Parent is TS3Functions (0)
000055. DoParse() : Loop:m_Str='', token='(uint64* result)'
000056. DoParse() : Loop:m_Str='', token=';'
000057. DoParse() : Loop:m_Str='', token='}'
000058. DoParse() : Loop:m_Str='', token='TS3Functions'
000059. DoParse() : Loop:m_Str='TS3Functions ', token='a'
000060. DoAddToken() : Created token='a', file_idx=1, line=10, ticket=258
000061. GetTokenBaseType() : Searching within m_Str='TS3Functions'
000062. GetTokenBaseType() : Compensated m_Str='TS3Functions'
000063. GetTokenBaseType() : Found 'TS3Functions'
000064. DoAddToken() : Prepending ''
000065. DoAddToken() : Added/updated token 'a' (2), kind 'variable', type 'TS3Functions', actual 'TS3Functions'. Parent is  (-1)
000066. DoParse() : Loop:m_Str='TS3Functions', token=';'
000067. SkipComment() : Start from line = 13
000068. SkipComment() : Need to call SkipToInlineCommentEnd() here at line = 13
000069. bool Tokenizer::SkipToInlineCommentEnd() : line=13, CurrentChar='a', PreviousChar='/', NextChar='.'
000070. SkipToInlineCommentEnd(): (END) We are now at line 13, CurrentChar='
********************************************************
  Testing in file: F:\cb_sf_git\trunk\src\plugins\codecompletion\testing\ccc_function_ptr.cpp
********************************************************
NativeParserBase::BreakUpComponents()
FindCCTokenStart() : Starting at 0 "a."
GetNextCCToken() : at 0 (a): res=
GetNextCCToken() : Done nest: at 1 (.): res=a
GetNextCCToken() : Return at 1 (.): res=a
GetCCToken() : FindCCTokenStart returned 1 "a."
GetCCToken() : GetNextCCToken returned 1 "a"
GetCCToken() : Left ""
NativeParserBase::GenerateResultSet_2()
Find 1 valid text matched tokens from the tree.
NativeParserBase::BreakUpComponents()
FindCCTokenStart() : Starting at 0 "TS3Functions"
GetNextCCToken() : at 0 (T): res=
GetNextCCToken() : Done nest: at 12 (
GetNextCCToken() : Return at 12 (
GetCCToken() : FindCCTokenStart returned 12 "TS3Functions"
GetCCToken() : GetNextCCToken returned 12 "TS3Functions"
GetCCToken() : Left ""
NativeParserBase::GenerateResultSet_2()
Find 1 valid text matched tokens from the tree.
NativeParserBase::GenerateResultSet_2()
*FAIL: a.  getClientLibVersion
--------------------------------------------------------
Total 1 tests, 0 PASS, 1 FAIL
--------------------------------------------------------

--- End code ---

Look: Adding function 'int': m_Str='unsigned ', the reason is we have such source code, the function name is "int".  ;D

--- Code: ---                    else if (!m_Options.useBuffer || m_Options.bufferSkipBlocks)
                    {
                        // pattern AAA BBB (...) in global namespace (not in local block)
                        // so, this is mostly like a function declaration, but in-fact this
                        // can also be a global variable initializized with ctor, but for
                        // simplicity, we drop the later case
                        HandleFunction(token); // function
                    }

--- End code ---

and
--- Code: ---unsigned int (*getClientLibVersion)(char** result);
--- End code ---
Satisfy "AAA BBB (...)" pattern. Maybe, we need to check whether there is a parenthesis after parenthesis.

ollydbg:
Candidate patch to fix your problem

--- Code: ---8ee75a7f4ee217a48380bcee26ad83d674cfd489
 src/plugins/codecompletion/parser/parserthread.cpp | 23 +++++++++++++++++++++-
 src/plugins/codecompletion/parser/parserthread.h   |  2 +-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/plugins/codecompletion/parser/parserthread.cpp b/src/plugins/codecompletion/parser/parserthread.cpp
index 9cb2690..96ba685 100644
--- a/src/plugins/codecompletion/parser/parserthread.cpp
+++ b/src/plugins/codecompletion/parser/parserthread.cpp
@@ -2148,18 +2148,39 @@ void ParserThread::HandleClass(EClassType ct)
     m_Tokenizer.SetState(oldState);
 }
 
-void ParserThread::HandleFunction(const wxString& name, bool isOperator, bool isPointer)
+void ParserThread::HandleFunction(wxString name, bool isOperator, bool isPointer)
 {
     TRACE(_T("HandleFunction() : Adding function '")+name+_T("': m_Str='")+m_Str+_T("'"));
     int lineNr = m_Tokenizer.GetLineNumber();
     wxString args = m_Tokenizer.GetToken();
     wxString peek = m_Tokenizer.PeekToken();
+    if (peek[0] == ParserConsts::opbracket_chr)
+    {
+        // pattern unsigned int (*getClientLibVersion)(char** result);
+        // currently, m_Str = unsigned, function name = int
+        // args = (*getClientLibVersion), peek = (char** result)
+        // this may be a function pointer declaration
+        m_Str<<name;
+        name = args;    // this is in-fact the function name "getClientLibVersion"
+        int pos = name.find(ParserConsts::ptr);
+        if (pos != wxNOT_FOUND)
+        {
+            args = peek; // peek becomes the function args
+            name.Trim(true).RemoveLast();
+            name.Remove(0, pos+1);
+            name.Trim(true).Trim(false);
+            isPointer = true;
+            m_Tokenizer.GetToken(); //consume the peek
+            peek = m_Tokenizer.PeekToken(); // update the peek value
+        }
+    }
     TRACE(_T("HandleFunction() : name='")+name+_T("', args='")+args+_T("', peek='")+peek+_T("'"));
 
     // special case for function pointers
     if (isPointer)
     {
         // pattern: m_Str AAA (*BBB) (...);
+        // name = *BBB, args = (...)
         if (peek == ParserConsts::semicolon)
         {
             TRACE(_T("HandleFunction() : Add token name='")+name+_T("', args='")+args+_T("', return type='") + m_Str+ _T("'"));
diff --git a/src/plugins/codecompletion/parser/parserthread.h b/src/plugins/codecompletion/parser/parserthread.h
index 7421177..3e26189 100644
--- a/src/plugins/codecompletion/parser/parserthread.h
+++ b/src/plugins/codecompletion/parser/parserthread.h
@@ -202,7 +202,7 @@ protected:
       * @param isOperator if true, means it is an operator overload function
       * @param isPointer if true, means it is a function pointer
       */
-    void HandleFunction(const wxString& name, bool isOperator = false, bool isPointer = false);
+    void HandleFunction(wxString name, bool isOperator = false, bool isPointer = false);
 
     /** parse for loop arguments:
       * for(int X; ... ; ...)


--- End code ---

But I have some code suggestion issue.


--- Code: ---struct TS3Functions {
unsigned int (*getClientLibVersion)(char** result);
unsigned int (*getClientLibVersionNumber)(uint64* result);
};

TS3Functions a;
a.

--- End code ---
Code suggest list shows Ok, but if I continue entering "get", then code suggesting list disappears, not sure why........(maybe some other local patches ;))

EDIT: update the patch, so no such issue. :)

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version