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:

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.

CVAPI    ---->   *

Here is the modified code, Tokenizer::MacroReplace function

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:


                   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:
   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