Author Topic: Code completion: ImageMagick API Can not find NewMagickWand()  (Read 331 times)

Offline wuher

  • Single posting newcomer
  • *
  • Posts: 4
Code completion: ImageMagick API Can not find NewMagickWand()
« on: November 18, 2017, 03:43:05 am »
Code::Blocks 16.01


<MagickWand.h>

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

Code completion:

Current input NewMagic:

Only the last NewMagickWandFromImage() can be found.

NewMagickWand can not be found.

How do I set it up?

thanks.
« Last Edit: November 18, 2017, 03:49:50 am by wuher »

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 10404
Re: Code completion: ImageMagick API Can not find NewMagickWand()
« Reply #1 on: November 18, 2017, 09:22:48 am »
This syntax is not supported by the parser.
You should separate the declarations on different lines.
<debugger plugin maintainer>
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline wuher

  • Single posting newcomer
  • *
  • Posts: 4
Re: Code completion: ImageMagick API Can not find NewMagickWand()
« Reply #2 on: November 18, 2017, 10:49:40 am »
Around 2013, the codeblocks version used supports parsing of this syntax. Just recently upgraded to the latest version only to find this problem may be the latest version of codeblocks made some adjustments?

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 10404
Re: Code completion: ImageMagick API Can not find NewMagickWand()
« Reply #3 on: November 18, 2017, 11:01:01 am »
I don't think, so. If you're on windows you could try the 17.xx-rc1.
<debugger plugin maintainer>
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline wuher

  • Single posting newcomer
  • *
  • Posts: 4
Re: Code completion: ImageMagick API Can not find NewMagickWand()
« Reply #4 on: November 18, 2017, 11:54:25 am »
I confirm Code :: Blocks 12.11 can be normal resolution.
But still very much appreciate your reply.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 4992
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion: ImageMagick API Can not find NewMagickWand()
« Reply #5 on: November 19, 2017, 03:53:08 pm »
Code: [Select]
extern WandExport MagickWand
  *CloneMagickWand(const MagickWand *),
  *DestroyMagickWand(MagickWand *),
  *NewMagickWand(void),
  *NewMagickWandFromImage(const Image *);

This code can be minimized to such code:
Code: [Select]
extern int *f1(), *f2();
f  // press f here, see whether f1 and f2 are prompted.

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

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 wuher

  • Single posting newcomer
  • *
  • Posts: 4
Re: Code completion: ImageMagick API Can not find NewMagickWand()
« Reply #6 on: November 21, 2017, 06:57:43 am »
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: [Select]
extern WandExport MagickWand *CloneMagickWand(const MagickWand *);

extern WandExport MagickWand *DestroyMagickWand(MagickWand *);

extern WandExport MagickWand *NewMagickWand(void);

extern WandExport MagickWand *NewMagickWandFromImage(const Image *);

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 4992
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion: ImageMagick API Can not find NewMagickWand()
« Reply #7 on: November 21, 2017, 08:04:37 am »
If you look at the source code of the parser in our C::B's code, you will see such code:

Code: [Select]
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

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