User forums > Using Code::Blocks

Code completion: ImageMagick API Can not find NewMagickWand()

<< < (2/2)

ollydbg:

--- Code: ---extern WandExport MagickWand
  *CloneMagickWand(const MagickWand *),
  *DestroyMagickWand(MagickWand *),
  *NewMagickWand(void),
  *NewMagickWandFromImage(const Image *);

--- End code ---

This code can be minimized to such code:

--- Code: ---extern int *f1(), *f2();
f  // press f here, see whether f1 and f2 are prompted.

--- End code ---

I see it just show a "f1", but no "f2".
From my point of view, I think our parser currently can't handle such syntax, it need to be fixed. :)

wuher:
thank you for your reply.

I recently spent some time writing a little gadget, converting the header files a bit, already complying with the Code :: Blocks 16.01 parsing specification.



--- Code: ---extern WandExport MagickWand *CloneMagickWand(const MagickWand *);

extern WandExport MagickWand *DestroyMagickWand(MagickWand *);

extern WandExport MagickWand *NewMagickWand(void);

extern WandExport MagickWand *NewMagickWandFromImage(const Image *);

--- End code ---

ollydbg:
If you look at the source code of the parser in our C::B's code, you will see such code:


--- Code: ---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();
    TRACE(_T("HandleFunction() : name='")+name+_T("', args='")+args+_T("', peek='")+peek+_T("'"));

    // special case for function pointers
    if (isPointer)
    {
        int pos = name.find(ParserConsts::ptr);

        // pattern: m_Str AAA (*BBB) (...);
        // pattern: m_Str AAA (*BBB) (...) = some_function;
        if (pos != wxNOT_FOUND && (peek == ParserConsts::semicolon || peek == ParserConsts::equals))
        {
            name.RemoveLast();  // remove ")"
            name.Remove(0, pos+1).Trim(false); // remove "(* "

            // pattern: m_Str AAA (*BBB[X][Y]) (...);
            // Trim(true) for safety, in case the name contains a trailing space
            pos = name.find(ParserConsts::oparray_chr);
            if (pos != wxNOT_FOUND)
                name.Remove(pos).Trim(true);

            TRACE(_T("HandleFunction() : Add token name='")+name+_T("', args='")+args+_T("', return type='") + m_Str+ _T("'"));
            Token* newToken =  DoAddToken(tkFunction, name, lineNr, 0, 0, args);
            if (newToken)
            {
                newToken->m_IsConst = false;
                newToken->m_TemplateArgument = m_TemplateArgument;
                if (!m_TemplateArgument.IsEmpty() && newToken->m_TemplateMap.empty())
                    ResolveTemplateArgs(newToken);
            }
            else
            {
                TRACE(_T("HandleFunction() : Unable to create/add new token: ") + name);
            }
            m_TemplateArgument.Clear();
        }
        return;
    }

    if (!m_Str.StartsWith(ParserConsts::kw_friend))
    {
        int lineStart = 0;
        int lineEnd = 0;
        bool isCtor = m_Str.IsEmpty();
        bool isDtor = m_Str.StartsWith(ParserConsts::tilde);
        Token* localParent = 0;

        if ((isCtor || isDtor) && !m_EncounteredTypeNamespaces.empty())
        {
            // probably a ctor/dtor
            std::queue<wxString> q = m_EncounteredTypeNamespaces; // preserve m_EncounteredTypeNamespaces; needed in DoAddToken()
            localParent = FindTokenFromQueue(q, m_LastParent);

            TRACE(_T("HandleFunction() : Ctor/Dtor '%s', m_Str='%s', localParent='%s'"),
                name.wx_str(),
                m_Str.wx_str(),
                localParent ? localParent->m_Name.wx_str() : _T("<none>"));
        }
        else
        {
            std::queue<wxString> q = m_EncounteredNamespaces; // preserve m_EncounteredNamespaces; needed in DoAddToken()
            localParent = FindTokenFromQueue(q, m_LastParent);

            TRACE(_T("HandleFunction() : !(Ctor/Dtor) '%s', m_Str='%s', localParent='%s'"),
                name.wx_str(),
                m_Str.wx_str(),
                localParent ? localParent->m_Name.wx_str() : _T("<none>"));
        }

        bool isCtorOrDtor = m_LastParent && name == m_LastParent->m_Name;

        if (!isCtorOrDtor)
            isCtorOrDtor = localParent && name == localParent->m_Name;

        if (!isCtorOrDtor && m_Options.useBuffer)
            isCtorOrDtor = isCtor || isDtor;

        TRACE(_T("HandleFunction() : Adding function '%s', ': m_Str='%s', enc_ns='%s'."),
              name.wx_str(),
              m_Str.wx_str(),
              m_EncounteredNamespaces.size() ? m_EncounteredNamespaces.front().wx_str() : wxT("nil"));

        bool isImpl = false;
        bool isConst = false;
        bool isNoExcept = false;
        while (!peek.IsEmpty()) // !eof
        {
            if (peek == ParserConsts::colon) // probably a ctor with member initializers
            {
                SkipToOneOfChars(ParserConsts::opbrace);
                m_Tokenizer.UngetToken(); // leave brace there
                peek = m_Tokenizer.PeekToken();
                continue;
            }
            else if (peek == ParserConsts::opbrace)// function implementation
            {
                isImpl = true;
                m_Tokenizer.GetToken(); // eat {
                lineStart = m_Tokenizer.GetLineNumber();
                SkipBlock(); // skip  to matching }
                lineEnd = m_Tokenizer.GetLineNumber();
                break;
            }
            else if (peek == ParserConsts::clbrace || peek == ParserConsts::semicolon)
                break; // function decl

--- End code ---

Now, you can see the last line is: if we see a semicolon, we found a "function declaration". So the best fix is adding the handling of the colon.

Navigation

[0] Message Index

[*] Previous page

Go to full version