diff --git a/src/source_clang.cc b/src/source_clang.cc index 901a583..ab1c960 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -104,7 +104,9 @@ void Source::ClangViewParse::parse_initialize() { } pos++; } - clang_tu = std::make_unique(clang_index, file_path.string(), get_compilation_commands(), buffer.raw()); + auto &buffer_raw=const_cast(buffer.raw()); + remove_include_guard(buffer_raw); + clang_tu = std::make_unique(clang_index, file_path.string(), get_compilation_commands(), buffer_raw); clang_tokens=clang_tu->get_tokens(0, buffer.bytes()-1); update_syntax(); @@ -133,7 +135,9 @@ void Source::ClangViewParse::parse_initialize() { }); } else if (parse_process_state==ParseProcessState::PROCESSING && parse_lock.try_lock()) { - auto status=clang_tu->ReparseTranslationUnit(parse_thread_buffer.raw()); + auto &parse_thread_buffer_raw=const_cast(parse_thread_buffer.raw()); + remove_include_guard(parse_thread_buffer_raw); + auto status=clang_tu->ReparseTranslationUnit(parse_thread_buffer_raw); parsing_in_progress->done("done"); if(status==0) { auto expected=ParseProcessState::PROCESSING; @@ -244,6 +248,92 @@ std::vector Source::ClangViewParse::get_compilation_commands() { return arguments; } +void Source::ClangViewParse::remove_include_guard(std::string &buffer) { + if(!(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr"))) + return; + + static std::regex ifndef_regex("^[ \t]*#ifndef.*$"); + static std::regex define_regex("^[ \t]*#define.*$"); + static std::regex endif_regex("^[ \t]*#endif.*$"); + std::vector> ranges; + bool found_ifndef=false, found_define=false; + bool line_comment=false, multiline_comment=false; + size_t start_of_line=0; + std::string line; + for(size_t c=0;c &offsets, int type) { @@ -689,7 +779,10 @@ void Source::ClangViewAutocomplete::autocomplete() { std::unique_lock lock(parse_mutex); if(parse_state==ParseState::PROCESSING) { parse_process_state=ParseProcessState::IDLE; - auto autocomplete_data=std::make_shared >(autocomplete_get_suggestions(buffer->raw(), line_nr, column_nr)); + + auto &buffer_raw=const_cast(buffer->raw()); + remove_include_guard(buffer_raw); + auto autocomplete_data=std::make_shared >(autocomplete_get_suggestions(buffer_raw, line_nr, column_nr)); if(parse_state==ParseState::PROCESSING) { dispatcher.post([this, autocomplete_data] { diff --git a/src/source_clang.h b/src/source_clang.h index 0baba5d..c2787b2 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -32,6 +32,8 @@ namespace Source { std::shared_ptr parsing_in_progress; + void remove_include_guard(std::string &buffer); + void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) override; void show_type_tooltips(const Gdk::Rectangle &rectangle) override; diff --git a/tests/source_clang_test.cc b/tests/source_clang_test.cc index 6e5fab5..6d82756 100644 --- a/tests/source_clang_test.cc +++ b/tests/source_clang_test.cc @@ -80,6 +80,53 @@ int main() { g_assert_cmpuint(clang_view->clang_diagnostics.size(), >, 0); g_assert_cmpuint(clang_view->get_fix_its().size(), >, 0); + // test remove_include_guard + { + clang_view->language=Gsv::LanguageManager::get_default()->get_language("chdr"); + std::string source="#ifndef F\n#define F\n#endif // F"; + clang_view->remove_include_guard(source); + g_assert_cmpstr(source.c_str(),==," \n \n "); + + source="#ifndef F\n#define F\n#endif // F\n"; + clang_view->remove_include_guard(source); + g_assert_cmpstr(source.c_str(),==," \n \n \n"); + + source="/*test*/\n#ifndef F\n#define F\n#endif // F\n"; + clang_view->remove_include_guard(source); + g_assert_cmpstr(source.c_str(),==,"/*test*/\n \n \n \n"); + + source="//test\n#ifndef F\n#define F\n#endif // F\n"; + clang_view->remove_include_guard(source); + g_assert_cmpstr(source.c_str(),==,"//test\n \n \n \n"); + + source="#ifndef F /*test*/\n#define F\n#endif // F"; + clang_view->remove_include_guard(source); + g_assert_cmpstr(source.c_str(),==," \n \n "); + + source="#ifndef F //test\n#define F\n#endif // F"; + clang_view->remove_include_guard(source); + g_assert_cmpstr(source.c_str(),==," \n \n "); + + source="#ifndef F\n//test\n#define F\n#endif // F\n"; + clang_view->remove_include_guard(source); + g_assert_cmpstr(source.c_str(),==," \n//test\n \n \n"); + + source="#ifndef F\ntest\n#define F\n#endif // F\n"; + auto old_source=source; + clang_view->remove_include_guard(source); + g_assert_cmpstr(old_source.c_str(),==,source.c_str()); + + source="test\n#ifndef F\n#define F\n#endif // F\n"; + old_source=source; + clang_view->remove_include_guard(source); + g_assert_cmpstr(old_source.c_str(),==,source.c_str()); + + source="#ifndef F\n#define F\n#endif // F\ntest\n"; + old_source=source; + clang_view->remove_include_guard(source); + g_assert_cmpstr(old_source.c_str(),==,source.c_str()); + } + clang_view->async_delete(); clang_view->delete_thread.join(); flush_events();