User forums > Using Code::Blocks
Code completion: ImageMagick API Can not find NewMagickWand()
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