For example, when parsing this statement:
#define _NO_DEBUG_PLACEHOLDER _No_debug_placeholder = _No_debug_placeholder()
See the source code in parserthread.cpp
void ParserThread::HandleDefines()
{
wxString filename;
int lineNr = m_Tokenizer.GetLineNumber();
wxString token = m_Tokenizer.GetToken(); // read the token after #define
m_Str.Clear();
// now token holds something like:
// BLAH_BLAH
if (!token.IsEmpty())
{
// skip the rest of the #define
wxString defVal = token + m_Tokenizer.ReadToEOL();
wxString para(_T(""));
int start = defVal.Find('(');
int end = defVal.Find(')');
TRACE(_T("HandleDefines() : Saving nesting level: %d,%d"), start, end);
// make sure preprocessor definitions are not going under namespaces or classes!
if (start != wxNOT_FOUND && end != wxNOT_FOUND)
{
para = defVal.Mid(start, end-start+1);
m_Str = defVal.Mid(end + 1);
m_Str.Trim(false);
}
else
{
m_Str = defVal.substr(token.length());
m_Str.Trim(false);
//defVal = _T("");
}
Token* oldParent = m_pLastParent;
m_pLastParent = 0L;
DoAddToken(tkPreprocessor, token, lineNr, lineNr, m_Tokenizer.GetLineNumber(), para, false, true);
m_pLastParent = oldParent;
m_Str.Clear();
}
}
The "()" at the end of the line was mistakenly regarded as the "parameter" of the define, like below:
#define _NO_DEBUG_PLACEHOLDER() XXXXXX
it is better to replace
m_Str << m_Tokenizer.ReadToEOL();
with
if (!m_Str.IsEmpty())
m_Str << _T(" ") << m_Tokenizer.ReadToEOL();
we need a space between two word here.
if (!m_Str.IsEmpty())
m_Str << _T(" ") << m_Tokenizer.ReadToEOL();
we need a space between two word here.
Are you sure? Because in the case m_Str.IsEmpty(), m_Tokenizer.ReadToEOL() is not being called. Didn't you mean something like:
if (!m_Str.IsEmpty())
m_Str << _T(" "):
m_Str << m_Tokenizer.ReadToEOL();
???
haha,you are right. :D
if (!m_Str.IsEmpty())
m_Str << _T(" ");
m_Str << m_Tokenizer.ReadToEOL();
new patch:
I just add a line compare here.because for codes:
#define BOOST_ALIGNED_STORAGE_HPP
int main() {}
when we do this,
wxString para = m_Tokenizer.GetToken();
at this time ,m_Tokenizer will return int ,then we do this
m_Str << m_Tokenizer.ReadToEOL();
it will eat the whole line codes
that is why the tokens number are lost.
BTW. @morten
can we print the whole project's tokens name to the file??so when we make patch,when the tokens numbers are wrong.we can use diff tool to check whick tokens are lost.
Another update.
remove the compile warning.
forget to do this in last patch.
if (!m_Str.IsEmpty())
m_Str << _T(" ");
m_Str << m_Tokenizer.ReadToEOL();
Index: src/plugins/codecompletion/parser/parserthread.cpp
===================================================================
--- src/plugins/codecompletion/parser/parserthread.cpp (revision 6169)
+++ src/plugins/codecompletion/parser/parserthread.cpp (working copy)
@@ -1123,8 +1123,8 @@
void ParserThread::HandleDefines()
{
- wxString filename;
- int lineNr = m_Tokenizer.GetLineNumber();
+ //wxString filename;
+ size_t lineNr = m_Tokenizer.GetLineNumber();
wxString token = m_Tokenizer.GetToken(); // read the token after #define
m_Str.Clear();
// now token holds something like:
@@ -1132,31 +1132,30 @@
if (!token.IsEmpty())
{
// skip the rest of the #define
- wxString defVal = token + m_Tokenizer.ReadToEOL();
- wxString para(_T(""));
- int start = defVal.Find('(');
- int end = defVal.Find(')');
-
+ wxString para = m_Tokenizer.GetToken();
TRACE(_T("HandleDefines() : Saving nesting level: %d,%d"), start, end);
-
- // make sure preprocessor definitions are not going under namespaces or classes!
- if (start != wxNOT_FOUND && end != wxNOT_FOUND)
+ if (lineNr == m_Tokenizer.GetLineNumber())
{
- para = defVal.Mid(start, end-start+1);
- m_Str = defVal.Mid(end + 1);
- m_Str.Trim(false);
+ if (para.IsEmpty() || para.GetChar(0) != '(') //check if contain the open brace
+ {
+ m_Str = para;
+ para = wxEmptyString;
+ }
+ if (!m_Str.IsEmpty())
+ m_Str << _T(" ");
+ m_Str << m_Tokenizer.ReadToEOL();
}
else
{
- m_Str = defVal.substr(token.length());
- m_Str.Trim(false);
- //defVal = _T("");
+ m_Tokenizer.UngetToken();
+ para = wxEmptyString;
+ m_Str << m_Tokenizer.ReadToEOL();
}
Token* oldParent = m_pLastParent;
m_pLastParent = 0L;
DoAddToken(tkPreprocessor, token, lineNr, lineNr, m_Tokenizer.GetLineNumber(), para, false, true);
m_pLastParent = oldParent;
- m_Str.Clear();
+ //m_Str.Clear();
}
}