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.
This syntax is not supported by the parser.
You should separate the declarations on different lines.
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?
I don't think, so. If you're on windows you could try the 17.xx-rc1.
I confirm Code :: Blocks 12.11 can be normal resolution.
But still very much appreciate your reply.
extern WandExport MagickWand
*CloneMagickWand(const MagickWand *),
*DestroyMagickWand(MagickWand *),
*NewMagickWand(void),
*NewMagickWandFromImage(const Image *);
This code can be minimized to such code:
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. :)
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.
extern WandExport MagickWand *CloneMagickWand(const MagickWand *);
extern WandExport MagickWand *DestroyMagickWand(MagickWand *);
extern WandExport MagickWand *NewMagickWand(void);
extern WandExport MagickWand *NewMagickWandFromImage(const Image *);
If you look at the source code of the parser in our C::B's code, you will see such 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
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.