Bugfix/escaped character parsing (#32)
So as it turns out there's a nasty little piece of code in rapidjson's source which breaks the preprocessor and will leave things a little bit weird. The test "preprocessor_parses_escaped_character" should prove its validity.
This commit is contained in:
parent
24365e8b82
commit
ca2fae08a2
3 changed files with 41 additions and 5 deletions
|
|
@ -740,11 +740,7 @@ detail::preprocessor_output detail::preprocess(const libclang_compile_config& co
|
||||||
if (next && next > p.ptr())
|
if (next && next > p.ptr())
|
||||||
p.bump(std::size_t(next - p.ptr() - 1)); // subtract one to get before that character
|
p.bump(std::size_t(next - p.ptr() - 1)); // subtract one to get before that character
|
||||||
|
|
||||||
if (starts_with(p, "\\\"")) // starts with \"
|
if (in_char == false && starts_with(p, "\"")) // starts with "
|
||||||
p.bump(2u);
|
|
||||||
else if (starts_with(p, "\\'")) // starts with \'
|
|
||||||
p.bump(2u);
|
|
||||||
else if (in_char == false && starts_with(p, "\"")) // starts with "
|
|
||||||
{
|
{
|
||||||
p.bump();
|
p.bump();
|
||||||
in_string.toggle();
|
in_string.toggle();
|
||||||
|
|
@ -756,6 +752,10 @@ detail::preprocessor_output detail::preprocess(const libclang_compile_config& co
|
||||||
}
|
}
|
||||||
else if (in_string == true || in_char == true)
|
else if (in_string == true || in_char == true)
|
||||||
p.bump();
|
p.bump();
|
||||||
|
else if (starts_with(p, "\\\"")) // starts with \"
|
||||||
|
p.bump(2u);
|
||||||
|
else if (starts_with(p, "\\'")) // starts with \'
|
||||||
|
p.bump(2u);
|
||||||
else if (auto macro = parse_macro(p, result, file_depth == 0u))
|
else if (auto macro = parse_macro(p, result, file_depth == 0u))
|
||||||
{
|
{
|
||||||
if (logger.is_verbose())
|
if (logger.is_verbose())
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,12 @@ set(tests
|
||||||
integration.cpp
|
integration.cpp
|
||||||
libclang_parser.cpp
|
libclang_parser.cpp
|
||||||
parser.cpp
|
parser.cpp
|
||||||
|
preprocessor.cpp
|
||||||
visitor.cpp)
|
visitor.cpp)
|
||||||
|
|
||||||
add_executable(cppast_test test.cpp test_parser.hpp ${tests})
|
add_executable(cppast_test test.cpp test_parser.hpp ${tests})
|
||||||
target_include_directories(cppast_test PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
|
target_include_directories(cppast_test PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
target_include_directories(cppast_test PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../src)
|
||||||
target_link_libraries(cppast_test PUBLIC cppast)
|
target_link_libraries(cppast_test PUBLIC cppast)
|
||||||
set_target_properties(cppast_test PROPERTIES CXX_STANDARD 11)
|
set_target_properties(cppast_test PROPERTIES CXX_STANDARD 11)
|
||||||
|
|
||||||
|
|
|
||||||
34
test/preprocessor.cpp
Normal file
34
test/preprocessor.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include <catch.hpp>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "libclang/preprocessor.hpp"
|
||||||
|
#include "test_parser.hpp"
|
||||||
|
|
||||||
|
using namespace cppast;
|
||||||
|
|
||||||
|
TEST_CASE("preprocessor_parses_escaped_character", "[!hide][clang4]")
|
||||||
|
{
|
||||||
|
write_file("ppec.hpp", R"(
|
||||||
|
)");
|
||||||
|
// This is an actual macro from the rapidjson source (reader.h)
|
||||||
|
write_file("ppec.cpp", R"(
|
||||||
|
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
static const char escape[256] = {
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
|
||||||
|
0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
|
||||||
|
0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
};
|
||||||
|
#undef Z16
|
||||||
|
|
||||||
|
#include "ppec.hpp"
|
||||||
|
)");
|
||||||
|
|
||||||
|
libclang_compile_config config;
|
||||||
|
config.set_flags(cpp_standard::cpp_latest);
|
||||||
|
|
||||||
|
auto&& preprocessed = detail::preprocess(config, "ppec.cpp", default_logger().get());
|
||||||
|
REQUIRE(preprocessed.includes.size() == 1);
|
||||||
|
REQUIRE(preprocessed.includes[0].file_name == "ppec.hpp");
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue