Backslash escape in paths

Fixes #106.
This commit is contained in:
Fadhil Mandaga 2021-08-24 22:59:23 +07:00 • committed by Jonathan Müller
commit bf7ec70ea5

View file

@ -373,10 +373,8 @@ std::string write_macro_file(const libclang_compile_config& c, const std::string
std::ofstream stream(file); std::ofstream stream(file);
auto cmd = get_macro_command(c, full_path.c_str()); auto cmd = get_macro_command(c, full_path.c_str());
tpl::Process process(cmd, "", tpl::Process process(
[&](const char* str, std::size_t n) { cmd, "", [&](const char* str, std::size_t n) { stream.write(str, std::streamsize(n)); },
stream.write(str, std::streamsize(n));
},
diagnostic_logger); diagnostic_logger);
if (auto include_guard = get_include_guard_macro(full_path)) if (auto include_guard = get_include_guard_macro(full_path))
@ -435,7 +433,8 @@ clang_preprocess_result clang_preprocess_impl(const libclang_compile_config& c,
}; };
auto cmd = get_preprocess_command(c, full_path.c_str(), macro_path); auto cmd = get_preprocess_command(c, full_path.c_str(), macro_path);
tpl::Process process(cmd, "", tpl::Process process(
cmd, "",
[&](const char* str, std::size_t n) { [&](const char* str, std::size_t n) {
for (auto ptr = str; ptr != str + n; ++ptr) for (auto ptr = str; ptr != str + n; ++ptr)
if (*ptr == '\t') if (*ptr == '\t')
@ -1024,7 +1023,12 @@ ts::optional<linemarker> parse_linemarker(position& p)
std::string file_name; std::string file_name;
for (; !starts_with(p, "\""); p.skip()) for (; !starts_with(p, "\""); p.skip())
{
if (*p.ptr() == '\\')
file_name += "\\\\";
else
file_name += *p.ptr(); file_name += *p.ptr();
}
p.skip(); p.skip();
result.file = std::move(file_name); result.file = std::move(file_name);
@ -1067,6 +1071,13 @@ detail::preprocessor_output detail::preprocess(const libclang_compile_config& co
auto preprocessed = clang_preprocess(config, path, logger); auto preprocessed = clang_preprocess(config, path, logger);
std::string xpath;
for (const char* cpath = path; *cpath; cpath++)
if (*cpath == '\\')
xpath += "\\\\";
else
xpath += *cpath;
position p(ts::ref(result.source), preprocessed.file.c_str()); position p(ts::ref(result.source), preprocessed.file.c_str());
ts::flag in_string(false), in_char(false), first_line(true); ts::flag in_string(false), in_char(false), first_line(true);
while (p) while (p)
@ -1186,7 +1197,7 @@ detail::preprocessor_output detail::preprocess(const libclang_compile_config& co
{ {
// this is the first line marker // this is the first line marker
// just skip all builtin macro stuff until we reach the file again // just skip all builtin macro stuff until we reach the file again
auto closing_line_marker = std::string("# 1 \"") + path + "\" 2\n"; auto closing_line_marker = std::string("# 1 \"") + xpath + "\" 2\n";
auto ptr = std::strstr(p.ptr(), closing_line_marker.c_str()); auto ptr = std::strstr(p.ptr(), closing_line_marker.c_str());
DEBUG_ASSERT(ptr, detail::assert_handler{}); DEBUG_ASSERT(ptr, detail::assert_handler{});