User forums > Using Code::Blocks
Conditional Code :: Blocks. highlighting in the editor
ollydbg:
OK, I see the method 2 is partially implemented, as I see we already have a function named:
--- Code: ---void EditorManager::CollectDefines(CodeBlocksEvent& event)
{
cbProject* prj = Manager::Get()->GetProjectManager()->GetActiveProject();
if ( !prj
|| !Manager::Get()->GetConfigManager(wxT("editor"))->ReadBool(wxT("/track_preprocessor"), true)
|| !Manager::Get()->GetConfigManager(wxT("editor"))->ReadBool(wxT("/collect_prj_defines"), true) )
{
event.Skip();
return;
}
wxArrayString compilerFlags = prj->GetCompilerOptions();
ProjectBuildTarget* tgt = prj->GetBuildTarget(prj->GetActiveBuildTarget());
FilesList* lst;
wxString id;
if (tgt)
{
AppendArray(tgt->GetCompilerOptions(), compilerFlags);
lst = &tgt->GetFilesList();
id = tgt->GetCompilerID();
}
else
{
lst = &prj->GetFilesList();
id = prj->GetCompilerID();
}
Compiler* comp = CompilerFactory::GetCompiler(id); // get global flags
if (comp)
AppendArray(comp->GetCompilerOptions(), compilerFlags);
wxArrayString defines;
for (size_t i = 0; i < compilerFlags.GetCount(); ++i)
{
if ( compilerFlags[i].StartsWith(wxT("-D"))
|| compilerFlags[i].StartsWith(wxT("/D")) )
{
defines.Add(compilerFlags[i].Mid(2));
}
else if (compilerFlags[i].Find(wxT("`")) != wxNOT_FOUND)
{
wxString str = compilerFlags[i];
ExpandBackticks(str);
str.Replace(wxT("`"), wxT(" ")); // remove any leftover backticks to prevent an infinite loop
AppendArray(GetArrayFromString(str, wxT(" ")), compilerFlags);
}
else if ( compilerFlags[i] == wxT("-ansi")
|| compilerFlags[i] == wxT("-std=c90")
|| compilerFlags[i] == wxT("-std=c++98"))
{
defines.Add(wxT("__STRICT_ANSI__"));
}
}
defines.Add(wxT("__cplusplus"));
for (FilesList::iterator it = lst->begin(); it != lst->end(); ++it)
{
if ((*it)->relativeFilename.EndsWith(wxT(".c")))
{
defines.RemoveAt(defines.GetCount() - 1); // do not define '__cplusplus' if even a single C file is found
break;
}
}
if (id.Find(wxT("gcc")) != wxNOT_FOUND)
{
defines.Add(wxT("__GNUC__"));
defines.Add(wxT("__GNUG__"));
}
else if (id.Find(wxT("msvc")) != wxNOT_FOUND)
{
defines.Add(wxT("_MSC_VER"));
defines.Add(wxT("__VISUALC__"));
}
if (Manager::Get()->GetConfigManager(wxT("editor"))->ReadBool(wxT("/platform_defines"), false))
{
if (platform::windows)
{
defines.Add(wxT("_WIN32"));
defines.Add(wxT("__WIN32"));
defines.Add(wxT("__WIN32__"));
defines.Add(wxT("WIN32"));
defines.Add(wxT("__WINNT"));
defines.Add(wxT("__WINNT__"));
defines.Add(wxT("WINNT"));
defines.Add(wxT("__WXMSW__"));
defines.Add(wxT("__WINDOWS__"));
if (platform::bits == 64)
{
defines.Add(wxT("_WIN64"));
defines.Add(wxT("__WIN64__"));
}
}
else if (platform::macosx)
{
defines.Add(wxT("__WXMAC__"));
defines.Add(wxT("__WXOSX__"));
defines.Add(wxT("__WXCOCOA__"));
defines.Add(wxT("__WXOSX_MAC__"));
defines.Add(wxT("__APPLE__"));
}
else if (platform::linux)
{
defines.Add(wxT("LINUX"));
defines.Add(wxT("linux"));
defines.Add(wxT("__linux"));
defines.Add(wxT("__linux__"));
}
else if (platform::freebsd)
{
defines.Add(wxT("FREEBSD"));
defines.Add(wxT("__FREEBSD__"));
}
else if (platform::netbsd)
{
defines.Add(wxT("NETBSD"));
defines.Add(wxT("__NETBSD__"));
}
else if (platform::openbsd)
{
defines.Add(wxT("OPENBSD"));
defines.Add(wxT("__OPENBSD__"));
}
else if (platform::darwin)
{
defines.Add(wxT("DARWIN"));
defines.Add(wxT("__APPLE__"));
}
else if (platform::solaris)
{
defines.Add(wxT("sun"));
defines.Add(wxT("__sun"));
defines.Add(wxT("__SUN__"));
defines.Add(wxT("__SUNOS__"));
defines.Add(wxT("__SOLARIS__"));
}
if (platform::unix)
{
defines.Add(wxT("unix"));
defines.Add(wxT("__unix"));
defines.Add(wxT("__unix__"));
defines.Add(wxT("__UNIX__"));
}
if (platform::gtk)
defines.Add(wxT("__WXGTK__"));
if (platform::bits == 32)
{
defines.Add(wxT("i386"));
defines.Add(wxT("__i386"));
defines.Add(wxT("__i386__"));
defines.Add(wxT("__i386__"));
defines.Add(wxT("_X86_"));
defines.Add(wxT("__INTEL__"));
}
else if (platform::bits == 64)
{
defines.Add(wxT("__amd64"));
defines.Add(wxT("__amd64__"));
defines.Add(wxT("__x86_64"));
defines.Add(wxT("__x86_64__"));
defines.Add(wxT("__IA64__"));
}
}
const wxString keywords = GetStringFromArray(MakeUniqueArray(defines, true), wxT(" "), false);
const HighlightLanguage hlCpp = m_Theme->GetHighlightLanguage(wxT("C/C++"));
if (m_Theme->GetKeywords(hlCpp, 4) == keywords)
return; // no change
m_Theme->SetKeywords(hlCpp, 4, keywords);
const wxString key = wxT("/colour_sets/") + m_Theme->GetName() + wxT("/cc/");
Manager::Get()->GetConfigManager(wxT("editor"))->Write(key + wxT("editor/keywords/set4"), keywords);
Manager::Get()->GetConfigManager(wxT("editor"))->Write(key + wxT("name"), wxT("C/C++"));
// update open editors
for (int index = 0; index < GetEditorsCount(); ++index)
{
cbEditor* ed = GetBuiltinEditor(index);
if ( ed && (ed->GetLanguage() == hlCpp) )
{
cbStyledTextCtrl* stc = ed->GetControl();
stc->SetKeyWords(4, keywords);
}
}
event.Skip();
}
--- End code ---
So, we can do quite similar thing inside the function void CodeCompletion::UpdateEditorSyntax(cbEditor* ed).
And we can set the "keywords 4", right?
ollydbg:
This is the code to read the macro definition string:
--- Code: ---int SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
WordList *wordListN = 0;
switch (n) {
case 0:
wordListN = &keywords;
break;
case 1:
wordListN = &keywords2;
break;
case 2:
wordListN = &keywords3;
break;
case 3:
wordListN = &keywords4;
break;
case 4:
wordListN = &ppDefinitions;
break;
case 5:
wordListN = &markerList;
break;
/* C::B begin */
case 6:
wordListN = &wxSmithIds;
break;
/* C::B end */
}
int firstModification = -1;
if (wordListN) {
WordList wlNew;
wlNew.Set(wl);
if (*wordListN != wlNew) {
wordListN->Set(wl);
firstModification = 0;
if (n == 4) {
// Rebuild preprocessorDefinitions
preprocessorDefinitionsStart.clear();
for (int nDefinition = 0; nDefinition < ppDefinitions.Length(); nDefinition++) {
const char *cpDefinition = ppDefinitions.WordAt(nDefinition);
const char *cpEquals = strchr(cpDefinition, '=');
if (cpEquals) {
std::string name(cpDefinition, cpEquals - cpDefinition);
std::string val(cpEquals+1);
size_t bracket = name.find('(');
size_t bracketEnd = name.find(')');
if ((bracket != std::string::npos) && (bracketEnd != std::string::npos)) {
// Macro
std::string args = name.substr(bracket + 1, bracketEnd - bracket - 1);
name = name.substr(0, bracket);
preprocessorDefinitionsStart[name] = SymbolValue(val, args);
} else {
preprocessorDefinitionsStart[name] = val;
}
} else {
std::string name(cpDefinition);
std::string val("1");
preprocessorDefinitionsStart[name] = val;
}
}
}
}
}
return firstModification;
}
--- End code ---
The bad thing is:
Currently, the WordList variable is construct with default arguments, that is:
--- Code: ---class WordList {
// Each word contains at least one character - a empty word acts as sentinel at the end.
char **words;
char *list;
int len;
bool onlyLineEnds; ///< Delimited by any white space or only line ends
int starts[256];
public:
explicit WordList(bool onlyLineEnds_ = false);
~WordList();
operator bool() const;
bool operator!=(const WordList &other) const;
int Length() const;
void Clear();
void Set(const char *s);
bool InList(const char *s) const;
bool InListAbbreviated(const char *s, const char marker) const;
const char *WordAt(int n) const;
};
--- End code ---
See the bool onlyLineEnds_ = false, that is, if our macro definition have spaces inside its definition, such as if we pass the string:
--- Code: ---_WIN32_
mydef(x,y)=x + y
--- End code ---
Then, it will read a single macro as "mydef(x,y)=x".
SmallTed:
OllyDbg after what you wrote, I can probably off because I have no such knowledge about these tools.
Will the new version of CodeBlocks improve this problem?
Now this statement do not want to cause war, but to present my conclusions from the last week. As I wrote in the first post. I'll be back after a few years to Code :: Blocks then seemed to me better than Eclipse, more intuitive. I used CodeBlocks for 5 years. Yesterday after problems with debugging under CodeBlocks tried to debug the same program in Eclipse and was held without a problem.
Eclipse took on the appearance of a serious tool. Maybe it's just a first impression. Unfortunately I can not say that about CodeBlocks, in general has not changed and it's not about looks, because it is sometimes an advantage. But this kind of trouble such as the debugging should not happen.
Regards
SmallTed
ollydbg:
Guys, I have implement this feature. It works quite well(but as you know, it does not work 100% correctly) as I tested.
--- Code: --- src/plugins/codecompletion/codecompletion.cpp | 22 ++++++++++++++++++++++
src/sdk/editormanager.cpp | 4 ++--
.../wxscintilla/src/scintilla/lexers/LexCPP.cxx | 2 +-
3 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/src/plugins/codecompletion/codecompletion.cpp b/src/plugins/codecompletion/codecompletion.cpp
index 0cf8427..f590dd4 100644
--- a/src/plugins/codecompletion/codecompletion.cpp
+++ b/src/plugins/codecompletion/codecompletion.cpp
@@ -3419,6 +3419,24 @@ void CodeCompletion::UpdateEditorSyntax(cbEditor* ed)
}
}
}
+
+ wxString macroText;
+ // the the current file index
+ size_t fileIdx = tree->GetFileIndex(ed->GetFilename());
+ // get all the tokens under global namespace
+ const
+ TokenIdxSet* globalTokens = tree->GetGlobalNameSpaces();
+ // loop those tokens, and add all the global macro definitions to a single
+ for (TokenIdxSet::const_iterator it = globalTokens->begin(); it != globalTokens->end(); ++it)
+ {
+ Token* token = tree->at(*it);
+ if (!token)
+ continue;
+ // exclude the macros defined in the current file
+ if (token->m_TokenKind == tkMacroDef && token->m_FileIdx != fileIdx)
+ macroText << token->m_Name << token->m_Args << wxT("=") << token->m_FullType << wxT("\n");
+ }
+
CC_LOCKER_TRACK_TT_MTX_UNLOCK(s_TokenTreeMutex)
EditorColourSet* colour_set = Manager::Get()->GetEditorManager()->GetColourSet();
@@ -3432,6 +3450,10 @@ void CodeCompletion::UpdateEditorSyntax(cbEditor* ed)
keywords += wxT(" ") + *keyIt;
}
ed->GetControl()->SetKeyWords(3, keywords);
+
+ // set the macro definition string
+ ed->GetControl()->SetKeyWords(4, macroText);
+
ed->GetControl()->Colourise(0, -1);
}
diff --git a/src/sdk/editormanager.cpp b/src/sdk/editormanager.cpp
index 3197755..db50655 100644
--- a/src/sdk/editormanager.cpp
+++ b/src/sdk/editormanager.cpp
@@ -1907,8 +1907,8 @@ void EditorManager::CollectDefines(CodeBlocksEvent& event)
defines.Add(wxT("__IA64__"));
}
}
-
- const wxString keywords = GetStringFromArray(MakeUniqueArray(defines, true), wxT(" "), false);
+ // \n is the delimiter
+ const wxString keywords = GetStringFromArray(MakeUniqueArray(defines, true), wxT("\n"), false);
const HighlightLanguage hlCpp = m_Theme->GetHighlightLanguage(wxT("C/C++"));
if (m_Theme->GetKeywords(hlCpp, 4) == keywords)
return; // no change
diff --git a/src/sdk/wxscintilla/src/scintilla/lexers/LexCPP.cxx b/src/sdk/wxscintilla/src/scintilla/lexers/LexCPP.cxx
index 3d37611..5aa46ac 100644
--- a/src/sdk/wxscintilla/src/scintilla/lexers/LexCPP.cxx
+++ b/src/sdk/wxscintilla/src/scintilla/lexers/LexCPP.cxx
@@ -606,7 +606,7 @@ int SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
}
int firstModification = -1;
if (wordListN) {
- WordList wlNew;
+ WordList wlNew(true);// onlyLineEnds = true
wlNew.Set(wl);
if (*wordListN != wlNew) {
wordListN->Set(wl);
--- End code ---
I just exclude the macro definition in the current opened editor, so that it can handle the macros correctly by the scintilla's C++ lexer.
yvesdm3000:
Mmh, I guess I'll have to do the same thing in Clang CC ;-)
It will get to be weird once we start using compiler-specific macro's as it should actually use the ones from the compiler and not Clang unless Clang is also the compiler...
Yves
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version