Author Topic: A macro replacement rule, for OpenCV kind function prototype  (Read 6604 times)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5277
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
A macro replacement rule, for OpenCV kind function prototype
« on: March 02, 2010, 07:09:53 am »
I have noticed that there's some function prototypes in OpenCV code like below:
Code: [Select]
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: [Select]
CVAPI    ---->   *
Here is the modified code, Tokenizer::MacroReplace function
Code: [Select]
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: [Select]
                   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: [Select]
   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.

« Last Edit: March 02, 2010, 08:35:22 am by ollydbg »
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline blueshake

  • Regular
  • ***
  • Posts: 459
Re: A macro replacement rule, for OpenCV kind function prototype
« Reply #1 on: March 02, 2010, 08:31:37 am »
Seems the time for macro and template parse is coming. :D
Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?