Code::Blocks Forums

Developer forums (C::B DEVELOPMENT STRICTLY!) => Development => CodeCompletion redesign => Topic started by: ollydbg on March 02, 2010, 07:09:53 am

Title: A macro replacement rule, for OpenCV kind function prototype
Post by: ollydbg on March 02, 2010, 07:09:53 am
I have noticed that there's some function prototypes in OpenCV code like below:
Code
CVAPI (int ) cvAdd(XXXXX);
CVAPI (float) cvAdd2(XXXXX);

So, I add a replacement rule to deal with this kind of macro, this rule is really simple, I just add a '*' handling condition.

Code
CVAPI    ---->   *

Here is the modified code, Tokenizer::MacroReplace function
Code
wxString Tokenizer::MacroReplace(const wxString str)
{
    ConfigManagerContainer::StringToStringMap::const_iterator it = s_Replacements.find(str);

    if (it != s_Replacements.end())
    {
        // match one!
        wxString key   = it->first;
        wxString value = it->second;
        TRACE(_T("MacroReplace() : Replacing '%s' with rule '%s' (file='%s')."), key.wx_str(), value.wx_str(), m_Filename.wx_str());
        if (value[0]=='+' && CurrentChar()=='(')
        {
            unsigned int start = m_TokenIndex;
            m_Buffer[start] = ' ';
            bool fillSpace = false;
            while (m_Buffer[start]!=')')
            {
                if (m_Buffer[start]==',')
                    fillSpace = true;

                if (fillSpace==true)
                    m_Buffer[start]=' ';

                start++;
            }
            m_Buffer[start] = '{';
            return value.Remove(0,1);
        }
        else if (value[0] == '-')
        {
            unsigned int lenKey = key.Len();
            value = value.Remove(0,1);
            unsigned int lenValue = value.Len();

            for (unsigned int i=1; i<=lenKey; i++)
            {
                if (i < lenValue)
                    m_Buffer[m_TokenIndex-i] = value[lenValue-i];
                else
                    m_Buffer[m_TokenIndex-i] = ' ';
            }

            int firstSpace = value.First(' ');
            // adjust m_TokenIndex
            m_TokenIndex = m_TokenIndex - lenValue + firstSpace;

            return value.Mid(0,firstSpace);
        }
        else if (value[0] == '*')
        {
            wxString arg = m_Buffer.Mid(m_TokenIndex,15);
            size_t left = arg.Find(_T('('));
            size_t right= arg.Find(_T(')'));
            if(left==wxNOT_FOUND||right==wxNOT_FOUND||left+2>right)
                return value;
            arg = arg.Mid(left+1,right-left-1);
            arg.Trim(false);
            arg.Trim(true);
            m_TokenIndex = m_TokenIndex + right + 1;
            TRACE(_T("MacroReplace() : Return %s, and move to '%s'"), arg.wx_str(), m_Buffer.Mid(m_TokenIndex,1).wc_str());
            return arg;
        }
        else
            return value;
    }

    return str;
}

Also, in the void ParserThread::DoParse() function body, I think it is the time to enable macro handing, (change it to true in the if condition:

Code
                    if (true /* TODO: Handle Macro detection properly */)
                    {
                        HandleMacro(token, peek);
                        m_Tokenizer.GetToken();
                        m_Str.Clear();
                    }
                    else
                    {
                        wxString arg = m_Tokenizer.GetToken(); // eat args ()
                        m_Str = token+arg;
                    }

So, we can parsing these kind of statement containing Macros like:
Code
    EVT_MENU(idMenuJumpToDeclaration, ClassBrowser::OnJumpTo)
    EVT_MENU(idMenuJumpToImplementation, ClassBrowser::OnJumpTo)
    EVT_MENU(idMenuRefreshTree, ClassBrowser::OnRefreshTree)
    EVT_MENU(idMenuForceReparse, ClassBrowser::OnForceReparse)


I have tested the new enhancement in our parserTest project and an OpenCV project and CB project, it works fine.

Title: Re: A macro replacement rule, for OpenCV kind function prototype
Post by: blueshake on March 02, 2010, 08:31:37 am
Seems the time for macro and template parse is coming. :D