diff --git a/src/libclang/preprocessor.cpp b/src/libclang/preprocessor.cpp index 11efc1a..1c792de 100644 --- a/src/libclang/preprocessor.cpp +++ b/src/libclang/preprocessor.cpp @@ -201,7 +201,8 @@ namespace if (cur_line_ != line) { *result_ += "#line " + std::to_string(line) + "\n"; - cur_line_ = line; + cur_line_ = line; + cur_column_ = 0; } } @@ -212,8 +213,13 @@ namespace for (auto c : str) { *result_ += c; + ++cur_column_; + if (c == '\n') + { ++cur_line_; + cur_column_ = 0; + } } } @@ -222,8 +228,13 @@ namespace if (write_ == true) { result_->push_back(*ptr_); + ++cur_column_; + if (*ptr_ == '\n') + { ++cur_line_; + cur_column_ = 0; + } } ++ptr_; } @@ -247,10 +258,15 @@ namespace void skip_with_linecount() noexcept { - if (*ptr_ == '\n' && write_ == true) + if (write_ == true) { - result_->push_back('\n'); - ++cur_line_; + ++cur_column_; + if (*ptr_ == '\n') + { + result_->push_back('\n'); + ++cur_line_; + cur_column_ = 0; + } } ++ptr_; @@ -281,6 +297,11 @@ namespace return cur_line_; } + unsigned cur_column() const noexcept + { + return cur_column_; + } + bool was_newl() const noexcept { return result_->empty() || result_->back() == '\n'; @@ -288,7 +309,7 @@ namespace private: ts::object_ref result_; - unsigned cur_line_; + unsigned cur_line_, cur_column_; const char* ptr_; ts::flag write_; }; @@ -398,9 +419,14 @@ namespace detail::pp_doc_comment result; result.kind = detail::pp_doc_comment::c; + auto indent = p.cur_column() + 3; + if (starts_with(p, " ")) + { // skip one whitespace at most p.skip(); + ++indent; + } while (!starts_with(p, "*/")) { @@ -415,8 +441,16 @@ namespace result.comment += '\n'; // skip indentation - while (starts_with(p, " ")) + for (auto i = 0u; i < indent && starts_with(p, " "); ++i) p.skip(); + + auto extra_indent = 0u; + while (starts_with(p, " ")) + { + ++extra_indent; + p.skip(); + } + // skip continuation star, if any if (starts_with(p, "*") && !starts_with(p, "*/")) { @@ -425,6 +459,11 @@ namespace // skip one whitespace at most p.skip(); } + else + { + // insert extra indent again + result.comment += std::string(extra_indent, ' '); + } } else { diff --git a/test/cpp_preprocessor.cpp b/test/cpp_preprocessor.cpp index bbca7a4..e0695f6 100644 --- a/test/cpp_preprocessor.cpp +++ b/test/cpp_preprocessor.cpp @@ -186,6 +186,52 @@ lines REQUIRE((file->unmatched_comments().size() == 6u + 1u)); } +TEST_CASE("comment content") +{ + auto code = R"( +/// simple comment + +///no space + +/// multi +/// line +/// comment + +/** C comment */ +/**C comment no space*/ + +/** Multiline +C +comment */ + + /** Multiline + C + comment + with + indent */ + + /** Multiline + * C + * comment + * with + * indent + * star */ +)"; + + auto file = parse({}, "comment-content.cpp", code); + auto comments = file->unmatched_comments(); + REQUIRE((comments.size() == 8u)); + + REQUIRE(comments[0u].content == "simple comment"); + REQUIRE(comments[1u].content == "no space"); + REQUIRE(comments[2u].content == "multi\nline\ncomment"); + REQUIRE(comments[3u].content == "C comment"); + REQUIRE(comments[4u].content == "C comment no space"); + REQUIRE(comments[5u].content == "Multiline\nC\ncomment"); + REQUIRE(comments[6u].content == "Multiline\nC\n comment\n with\n indent"); + REQUIRE(comments[7u].content == "Multiline\nC\ncomment\nwith\nindent\nstar"); +} + TEST_CASE("comment matching") { auto code = R"(