switched to unicode

changed zlib to use vs instead of jom because it doesn't handle non-ascii characters
fixed async_pipe corrupting the stack when io was pending
vcvars uses cmd /U to dump `set` to a utf16 file, or else PATH has trouble with non-ascii characters
fixed no colors on terminal
This commit is contained in:
isanae
2020-05-12 12:00:02 -04:00
parent 9f98d8f614
commit dbda7c5936
19 changed files with 254 additions and 125 deletions
+7 -5
View File
@@ -399,10 +399,12 @@ fs::path find_third_party_directory()
fs::path find_in_path(const std::string& exe)
{
const std::size_t buffer_size = MAX_PATH;
char buffer[buffer_size + 1] = {};
const std::wstring wexe = utf8_to_utf16(exe);
if (SearchPathA(nullptr, exe.c_str(), nullptr, buffer_size, buffer, nullptr))
const std::size_t size = MAX_PATH;
wchar_t buffer[size + 1] = {};
if (SearchPathW(nullptr, wexe.c_str(), nullptr, size, buffer, nullptr))
return buffer;
else
return {};
@@ -950,7 +952,7 @@ void dump_options()
string_map tools;
for (auto&& [k, v] : g_tools)
tools[k] = v.string();
tools[k] = path_to_utf8(v);
table("tools", tools);
string_map prebuilt;
@@ -962,7 +964,7 @@ void dump_options()
string_map paths;
for (auto&& [k, v] : g_paths)
paths[k] = v.string();
paths[k] = path_to_utf8(v);
table("paths", paths);
}
+3 -3
View File
@@ -197,8 +197,8 @@ void context::set_log_file(const fs::path& p)
{
if (!p.empty())
{
HANDLE h = CreateFileA(
p.string().c_str(), GENERIC_WRITE, FILE_SHARE_READ,
HANDLE h = CreateFileW(
p.native().c_str(), GENERIC_WRITE, FILE_SHARE_READ,
nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (h == INVALID_HANDLE_VALUE)
@@ -242,8 +242,8 @@ void context::emit_log(level lv, const std::string& utf8) const
if (log_enabled(lv, conf::output_log_level()))
{
u8cout << utf8 << "\n";
auto c = level_color(lv);
u8cout << utf8 << "\n";
}
if (g_log_file && log_enabled(lv, conf::file_log_level()))
+56 -30
View File
@@ -33,15 +33,16 @@ env get_vcvars_env(arch a)
// "vcvarsall.bat" amd64 && set > temp_file
std::string cmd =
"\"" + tools::vs::vcvars().string() + "\" " + arch_s +
" && set > \"" + tmp.string() + "\"";
"\"" + path_to_utf8(tools::vs::vcvars()) + "\" " + arch_s +
" && set > \"" + path_to_utf8(tmp) + "\"";
process::raw(gcx(), cmd)
.cmd_unicode(true)
.run();
gcx().trace(context::generic, "reading from {}", tmp);
std::stringstream ss(op::read_text_file(gcx(), tmp));
std::stringstream ss(op::read_text_file(gcx(), encodings::utf16, tmp));
op::delete_file(gcx(), tmp);
env e;
@@ -119,7 +120,7 @@ env& env::append_path(const std::vector<fs::path>& v)
if (!path.empty())
path += ";";
path += p.string();
path += path_to_utf8(p);
}
set("PATH", path, replace);
@@ -172,13 +173,15 @@ void env::set_from(const env& e)
void env::create() const
{
sys_.clear();
for (auto&& v : vars_)
{
string_ += v.first + "=" + v.second;
string_.append(1, '\0');
sys_ += utf8_to_utf16(v.first + "=" + v.second);
sys_.append(1, L'\0');
}
string_.append(1, '\0');
sys_.append(1, L'\0');
}
env::map::const_iterator env::find(const std::string& name) const
@@ -192,79 +195,102 @@ env::map::const_iterator env::find(const std::string& name) const
return vars_.end();
}
void* env::get_pointers() const
void* env::get_unicode_pointers() const
{
if (vars_.empty())
return nullptr;
if (string_.empty())
if (sys_.empty())
create();
return (void*)string_.c_str();
return (void*)sys_.c_str();
}
void this_env::set(const std::string& k, const std::string& v, env::flags f)
{
const std::wstring wk = utf8_to_utf16(k);
const std::wstring wv = utf8_to_utf16(v);
switch (f)
{
case env::replace:
::SetEnvironmentVariableA(k.c_str(), v.c_str());
{
::SetEnvironmentVariableW(wk.c_str(), wv.c_str());
break;
}
case env::append:
::SetEnvironmentVariableA(k.c_str(), (get(k) + v).c_str());
{
const std::wstring current = get_impl(k);
::SetEnvironmentVariableW(wk.c_str(), (current + wv).c_str());
break;
}
case env::prepend:
::SetEnvironmentVariableA(k.c_str(), (v + get(k)).c_str());
{
const std::wstring current = get_impl(k);
::SetEnvironmentVariableW(wk.c_str(), (wv + current).c_str());
break;
}
}
}
void this_env::prepend_to_path(const fs::path& p)
{
gcx().trace(context::generic, "prepending to PATH: {}", p);
set("PATH", p.string() + ";", env::prepend);
set("PATH", path_to_utf8(p) + ";", env::prepend);
}
std::string this_env::get(const std::string& name)
{
const std::size_t buffer_size = GetEnvironmentVariableA(
name.c_str(), nullptr, 0);
return utf16_to_utf8(get_impl(name));
}
std::wstring this_env::get_impl(const std::string& k)
{
const std::wstring wk = utf8_to_utf16(k);
const std::size_t buffer_size = GetEnvironmentVariableW(
wk.c_str(), nullptr, 0);
if (buffer_size == 0)
bail_out("environment variable {} doesn't exist", name);
bail_out("environment variable {} doesn't exist", k);
auto buffer = std::make_unique<char[]>(buffer_size + 1);
auto buffer = std::make_unique<wchar_t[]>(buffer_size + 1);
std::fill(buffer.get(), buffer.get() + buffer_size + 1, 0);
GetEnvironmentVariableA(
name.c_str(), buffer.get(), static_cast<DWORD>(buffer_size));
const std::size_t written = GetEnvironmentVariableW(
wk.c_str(), buffer.get(), static_cast<DWORD>(buffer_size));
return buffer.get();
if (written == 0)
bail_out("environment variable {} doesn't exist", k);
MOB_ASSERT((written + 1) == buffer_size);
return {buffer.get(), buffer.get() + written};
}
env this_env::get()
{
env e;
auto free = [](char* p) { FreeEnvironmentStrings(p); };
auto free = [](wchar_t* p) { FreeEnvironmentStringsW(p); };
auto env_block = std::unique_ptr<char, decltype(free)>{
GetEnvironmentStrings(), free};
auto env_block = std::unique_ptr<wchar_t, decltype(free)>{
GetEnvironmentStringsW(), free};
for (const char* name = env_block.get(); *name != '\0'; )
for (const wchar_t* name = env_block.get(); *name != L'\0'; )
{
const char* equal = std::strchr(name, '=');
std::string key(name, static_cast<std::size_t>(equal - name));
const wchar_t* equal = std::wcschr(name, '=');
std::wstring key(name, static_cast<std::size_t>(equal - name));
const char* pValue = equal + 1;
std::string value(pValue);
const wchar_t* pValue = equal + 1;
std::wstring value(pValue);
if (!key.empty())
e.set(key, value);
e.set(utf16_to_utf8(key), utf16_to_utf8(value));
name = pValue + value.length() + 1;
}
+5 -2
View File
@@ -27,13 +27,13 @@ public:
std::string get(const std::string& k) const;
void* get_pointers() const;
void* get_unicode_pointers() const;
private:
using map = std::map<std::string, std::string>;
map vars_;
mutable std::string string_;
mutable std::wstring sys_;
void create() const;
map::const_iterator find(const std::string& name) const;
@@ -51,6 +51,9 @@ struct this_env
static env get();
static std::string get(const std::string& k);
private:
static std::wstring get_impl(const std::string& k);
};
} // namespace
+2 -2
View File
@@ -320,11 +320,11 @@ int main(int argc, char** argv)
if (r == 0)
{
mob::gcx().debug(mob::context::generic, "mob done");
mob::gcx().info(mob::context::generic, "mob done");
}
else
{
mob::gcx().debug(mob::context::generic,
mob::gcx().info(mob::context::generic,
"mob finished with exit code {}", r);
}
+2 -2
View File
@@ -225,8 +225,8 @@ void curl_downloader::on_write(char* ptr, std::size_t n) noexcept
cx_.trace(context::net, "opening {}", path_);
HANDLE h = ::CreateFileA(
path_.string().c_str(), GENERIC_WRITE, FILE_SHARE_READ,
HANDLE h = ::CreateFileW(
path_.native().c_str(), GENERIC_WRITE, FILE_SHARE_READ,
nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (h == INVALID_HANDLE_VALUE)
+45 -9
View File
@@ -221,7 +221,7 @@ void copy_file_to_dir_if_better(
check(cx, dir);
}
if (file.string().find("*") != std::string::npos)
if (file.u8string().find(u8"*") != std::string::npos)
cx.bail_out(context::fs, "{} contains a glob", file);
if (!conf::dry())
@@ -266,7 +266,7 @@ void copy_file_to_file_if_better(
check(cx, dest);
}
if (src.string().find("*") != std::string::npos)
if (src.u8string().find(u8"*") != std::string::npos)
cx.bail_out(context::fs, "{} contains a glob", src);
if (!conf::dry())
@@ -309,13 +309,13 @@ void copy_glob_to_dir_if_better(
const fs::path& src_glob, const fs::path& dest_dir, flags f)
{
const auto file_parent = src_glob.parent_path();
const auto wildcard = src_glob.filename().string();
const auto wildcard = src_glob.filename().native();
for (auto&& e : fs::directory_iterator(file_parent))
{
const auto name = e.path().filename().string();
const auto name = e.path().filename().native();
if (!PathMatchSpecA(name.c_str(), wildcard.c_str()))
if (!PathMatchSpecW(name.c_str(), wildcard.c_str()))
{
cx.trace(context::fs,
"{} did not match {}; skipping", name, wildcard);
@@ -355,12 +355,12 @@ void copy_glob_to_dir_if_better(
}
}
std::string read_text_file(const context& cx, const fs::path& p, flags f)
std::string read_text_file_impl(const context& cx, const fs::path& p, flags f)
{
cx.trace(context::fs, "reading {}", p);
std::string s;
std::ifstream in(p);
std::ifstream in(p, std::ios::binary);
in.seekg(0, std::ios::end);
s.resize(static_cast<std::size_t>(in.tellg()));
@@ -382,6 +382,42 @@ std::string read_text_file(const context& cx, const fs::path& p, flags f)
return s;
}
std::string read_text_file(
const context& cx, encodings e, const fs::path& p, flags f)
{
cx.trace(context::fs, "reading {}", p);
std::string bytes = read_text_file_impl(cx, p, f);
if (bytes.empty())
return bytes;
std::string utf8;
switch (e)
{
case encodings::utf16:
{
const auto* wbuf = reinterpret_cast<const wchar_t*>(bytes.data());
const std::size_t n = bytes.size() / sizeof(wchar_t);
const std::wstring ws(wbuf, wbuf + n);
utf8 = utf16_to_utf8(ws);
break;
}
case encodings::utf8:
case encodings::dont_know:
default:
{
utf8 = std::move(bytes);
break;
}
}
utf8 = replace_all(utf8, "\r\n", "\n");
return utf8;
}
void write_text_file(
const context& cx, const fs::path& p, std::string_view s, flags f)
{
@@ -531,8 +567,8 @@ void check(const context& cx, const fs::path& p)
auto is_inside = [](auto&& p, auto&& dir)
{
const std::string s = p.string();
const std::string prefix = dir.string();
const std::string s = path_to_utf8(p);
const std::string prefix = path_to_utf8(dir);
if (s.size() < prefix.size())
return false;
+1 -1
View File
@@ -52,7 +52,7 @@ void copy_glob_to_dir_if_better(
const fs::path& src_glob, const fs::path& dest_dir, flags f);
std::string read_text_file(
const context& cx, const fs::path& p, flags f=noflags);
const context& cx, encodings e, const fs::path& p, flags f=noflags);
void write_text_file(
const context& cx, const fs::path& p, std::string_view s, flags f=noflags);
+91 -48
View File
@@ -15,12 +15,11 @@ const DWORD process_wait_timeout = 50;
HANDLE get_bit_bucket()
{
SECURITY_ATTRIBUTES sa { .nLength = sizeof(sa), .bInheritHandle = TRUE };
return ::CreateFileA("NUL", GENERIC_WRITE, 0, &sa, OPEN_EXISTING, 0, 0);
return ::CreateFileW(L"NUL", GENERIC_WRITE, 0, &sa, OPEN_EXISTING, 0, 0);
}
async_pipe::async_pipe()
: pending_(false)
: pending_(false), closed_(true)
{
buffer_ = std::make_unique<char[]>(buffer_size);
std::memset(buffer_.get(), 0, buffer_size);
@@ -28,6 +27,11 @@ async_pipe::async_pipe()
std::memset(&ov_, 0, sizeof(ov_));
}
bool async_pipe::closed() const
{
return closed_;
}
handle_ptr async_pipe::create()
{
// creating pipe
@@ -44,6 +48,7 @@ handle_ptr async_pipe::create()
}
event_.reset(ov_.hEvent);
closed_ = false;
return out;
}
@@ -60,8 +65,8 @@ HANDLE async_pipe::create_pipe()
{
static std::atomic<int> pipe_id(0);
const std::string pipe_name_prefix = "\\\\.\\pipe\\mob_pipe";
const std::string pipe_name = pipe_name_prefix + std::to_string(++pipe_id);
const std::wstring pipe_name =
L"\\\\.\\pipe\\mob_pipe" + std::to_wstring(++pipe_id);
SECURITY_ATTRIBUTES sa = {};
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
@@ -71,7 +76,7 @@ HANDLE async_pipe::create_pipe()
// creating pipe
{
HANDLE pipe_handle = ::CreateNamedPipeA(
HANDLE pipe_handle = ::CreateNamedPipeW(
pipe_name.c_str(), PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT,
1, buffer_size, buffer_size, pipe_timeout, &sa);
@@ -79,7 +84,7 @@ HANDLE async_pipe::create_pipe()
if (pipe_handle == INVALID_HANDLE_VALUE)
{
const auto e = GetLastError();
bail_out("CreateNamedPipe failed", error_message(e));
bail_out("CreateNamedPipeW failed", error_message(e));
}
pipe.reset(pipe_handle);
@@ -104,7 +109,7 @@ HANDLE async_pipe::create_pipe()
// creating handle to pipe which is passed to CreateProcess()
HANDLE output_write = ::CreateFileA(
HANDLE output_write = ::CreateFileW(
pipe_name.c_str(), FILE_WRITE_DATA|SYNCHRONIZE, 0,
&sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
@@ -135,7 +140,8 @@ std::string_view async_pipe::try_read()
case ERROR_BROKEN_PIPE:
{
// broken pipe probably means the process is finished
// broken pipe means the process is finished
closed_ = true;
break;
}
@@ -183,7 +189,8 @@ std::string_view async_pipe::check_pending()
case ERROR_BROKEN_PIPE:
{
// broken pipe probably means lootcli is finished
// broken pipe means the process is finished
closed_ = true;
break;
}
@@ -222,7 +229,7 @@ process::impl& process::impl::operator=(const impl& i)
process::process()
: cx_(&gcx()), flags_(process::noflags), code_(0)
: cx_(&gcx()), unicode_(false), flags_(process::noflags), code_(0)
{
}
@@ -260,7 +267,7 @@ process& process::name(const std::string& name)
std::string process::name() const
{
if (name_.empty())
return bin_.stem().string();
return path_to_utf8(bin_.stem());
else
return name_;
}
@@ -323,6 +330,12 @@ process& process::stderr_filter(filter_fun f)
return *this;
}
process& process::cmd_unicode(bool b)
{
unicode_ = b;
return *this;
}
process& process::external_error_log(const fs::path& p)
{
error_log_file_ = p;
@@ -359,7 +372,7 @@ std::string process::make_cmd() const
if (!raw_.empty())
return raw_;
return "\"" + bin_.string() + "\"" + cmd_;
return "\"" + path_to_utf8(bin_) + "\"" + cmd_;
}
void process::pipe_into(const process& p)
@@ -394,10 +407,10 @@ void process::do_run(const std::string& what)
op::delete_file(*cx_, error_log_file_, op::optional);
}
STARTUPINFOA si = { .cb=sizeof(si) };
STARTUPINFOW si = { .cb=sizeof(si) };
PROCESS_INFORMATION pi = {};
handle_ptr stdout_pipe, stderr_pipe;
handle_ptr stdout_pipe, stderr_pipe, stdin_pipe;
switch (stdout_.flags)
{
@@ -445,28 +458,31 @@ void process::do_run(const std::string& what)
}
}
si.hStdInput = get_bit_bucket();
stdin_pipe.reset(get_bit_bucket());
si.hStdInput = stdin_pipe.get();
si.dwFlags = STARTF_USESTDHANDLES;
const std::string cmd = this_env::get("COMSPEC");
const std::string args = "/C \"" + what + "\"";
const std::wstring cmd = utf8_to_utf16(this_env::get("COMSPEC"));
std::wstring args = make_cmd_args(what);
const char* cwd_p = nullptr;
std::string cwd_s;
const wchar_t* cwd_p = nullptr;
std::wstring cwd_s;
if (!cwd_.empty())
{
op::create_directories(*cx_, cwd_);
cwd_s = cwd_.string();
cwd_s = cwd_.native();
cwd_p = (cwd_s.empty() ? nullptr : cwd_s.c_str());
}
cx_->trace(context::cmd, "creating process");
const auto r = ::CreateProcessA(
cmd.c_str(), const_cast<char*>(args.c_str()),
nullptr, nullptr, TRUE, CREATE_NEW_PROCESS_GROUP,
env_.get_pointers(), cwd_p, &si, &pi);
const auto r = ::CreateProcessW(
cmd.c_str(), args.data(),
nullptr, nullptr, TRUE,
CREATE_NEW_PROCESS_GROUP|CREATE_UNICODE_ENVIRONMENT,
env_.get_unicode_pointers(), cwd_p, &si, &pi);
if (!r)
{
@@ -481,6 +497,18 @@ void process::do_run(const std::string& what)
impl_.handle.reset(pi.hProcess);
}
std::wstring process::make_cmd_args(const std::string& what) const
{
std::wstring s;
if (unicode_)
s += L"/U ";
s += L"/C \"" + utf8_to_utf16(what) + L"\"";
return s;
}
void process::interrupt()
{
impl_.interrupt = true;
@@ -523,30 +551,19 @@ void process::join()
cx_->trace(context::cmd, "process interrupted and finished");
}
bool process::read_pipes()
void process::read_pipes()
{
bool read_something = false;
if (read_pipe(stdout_, impl_.stdout_pipe, context::std_out))
read_something = true;
if (read_pipe(stderr_, impl_.stderr_pipe, context::std_err))
read_something = true;
return read_something;
read_pipe(stdout_, impl_.stdout_pipe, context::std_out);
read_pipe(stderr_, impl_.stderr_pipe, context::std_err);
}
bool process::read_pipe(stream& s, async_pipe& pipe, context::reason r)
void process::read_pipe(stream& s, async_pipe& pipe, context::reason r)
{
bool read_something = false;
switch (s.flags)
{
case forward_to_log:
{
const std::string_view buffer = pipe.read();
if (!buffer.empty())
read_something = true;
for_each_line(buffer, [&](auto&& line)
{
@@ -562,15 +579,14 @@ bool process::read_pipe(stream& s, async_pipe& pipe, context::reason r)
cx_->log(f.r, f.lv, "{}", f.line);
});
s.string.append(buffer.begin(), buffer.end());
break;
}
case keep_in_string:
{
const std::string_view buffer = pipe.read();
if (!buffer.empty())
read_something = true;
s.string.append(buffer.begin(), buffer.end());
break;
}
@@ -579,8 +595,6 @@ bool process::read_pipe(stream& s, async_pipe& pipe, context::reason r)
case inherit:
break;
}
return read_something;
}
void process::on_completed()
@@ -588,7 +602,9 @@ void process::on_completed()
// one last time
for (;;)
{
if (!read_pipes())
read_pipes();
if (impl_.stdout_pipe.closed() && impl_.stderr_pipe.closed())
break;
}
@@ -620,6 +636,7 @@ void process::on_completed()
else
{
dump_error_log_file();
dump_stderr();
cx_->bail_out(context::cmd, "{} returned {}", make_name(), code_);
}
}
@@ -669,7 +686,7 @@ void process::dump_error_log_file() noexcept
if (fs::exists(error_log_file_))
{
std::string log = op::read_text_file(
*cx_, error_log_file_, op::optional);
*cx_, encodings::dont_know, error_log_file_, op::optional);
if (log.empty())
return;
@@ -694,6 +711,32 @@ void process::dump_error_log_file() noexcept
}
}
void process::dump_stderr() noexcept
{
try
{
if (!stderr_.string.empty())
{
cx_->error(context::cmd,
"{} failed, content of stderr:", make_name());
for_each_line(stderr_.string, [&](auto&& line)
{
cx_->error(context::cmd, " {}", line);
});
}
else
{
cx_->error(context::cmd,
"{} failed, stderr was empty", make_name());
}
}
catch(...)
{
// eat it
}
}
int process::exit_code() const
{
return static_cast<int>(code_);
@@ -752,7 +795,7 @@ std::string process::arg_to_string(const std::string& s, bool force_quote)
std::string process::arg_to_string(const fs::path& p, bool)
{
return "\"" + p.string() + "\"";
return "\"" + path_to_utf8(p) + "\"";
}
std::string process::arg_to_string(const url& u, bool force_quote)
+10 -3
View File
@@ -16,7 +16,8 @@ public:
async_pipe();
handle_ptr create();
std::string_view read();
std::string_view read();
bool closed() const;
private:
static const std::size_t buffer_size = 50'000;
@@ -26,6 +27,7 @@ private:
std::unique_ptr<char[]> buffer_;
OVERLAPPED ov_;
bool pending_;
bool closed_;
HANDLE create_pipe();
std::string_view try_read();
@@ -111,6 +113,8 @@ public:
process& stderr_level(context::level lv);
process& stderr_filter(filter_fun f);
process& cmd_unicode(bool b);
process& external_error_log(const fs::path& p);
process& flags(flags_t f);
@@ -182,6 +186,7 @@ private:
std::string name_;
fs::path bin_;
fs::path cwd_;
bool unicode_;
flags_t flags_;
stream stdout_;
stream stderr_;
@@ -195,15 +200,17 @@ private:
std::string make_name() const;
std::string make_cmd() const;
std::wstring make_cmd_args(const std::string& what) const;
void pipe_into(const process& p);
void do_run(const std::string& what);
bool read_pipes();
bool read_pipe(stream& s, async_pipe& pipe, context::reason r);
void read_pipes();
void read_pipe(stream& s, async_pipe& pipe, context::reason r);
void on_completed();
void on_timeout(bool& already_interrupted);
void dump_error_log_file() noexcept;
void dump_stderr() noexcept;
void add_arg(const std::string& k, const std::string& v, arg_flags f);
+2 -2
View File
@@ -111,8 +111,8 @@ void pyqt::sip_build()
python::source_path(),
python::scripts_path()})
.set("CL", " /MP")
.set("LIB", ";" + paths::install_libs().string(), env::append)
.set("PYTHONHOME", python::source_path().string());
.set("LIB", ";" + path_to_utf8(paths::install_libs()), env::append)
.set("PYTHONHOME", path_to_utf8(python::source_path()));
bypass_file built_bypass(cx(), source_path(), "built");
+6 -6
View File
@@ -127,12 +127,12 @@ void python::build_and_install_from_source()
"python", "pythonw", "python3dll", "select", "pyexpat",
"unicodedata", "_queue", "_bz2", "_ssl"})
.parameters({
"bz2Dir=" + bzip2::source_path().string(),
"zlibDir=" + zlib::source_path().string(),
"opensslIncludeDir=" + openssl::include_path().string(),
"opensslOutDir=" + openssl::source_path().string(),
"libffiIncludeDir=" + libffi::include_path().string(),
"libffiOutDir=" + libffi::lib_path().string()}));
"bz2Dir=" + path_to_utf8(bzip2::source_path()),
"zlibDir=" + path_to_utf8(zlib::source_path()),
"opensslIncludeDir=" + path_to_utf8(openssl::include_path()),
"opensslOutDir=" + path_to_utf8(openssl::source_path()),
"libffiIncludeDir=" + path_to_utf8(libffi::include_path()),
"libffiOutDir=" + path_to_utf8(libffi::lib_path())}));
package();
install_pip();
+3 -4
View File
@@ -41,13 +41,12 @@ void zlib::do_fetch()
void zlib::do_build_and_install()
{
const auto build_path = run_tool(cmake()
.generator(cmake::jom)
.generator(cmake::vs)
.root(source_path())
.prefix(source_path()));
run_tool(jom()
.path(build_path)
.target("install"));
run_tool(msbuild()
.solution(source_path() / "vsbuild" / "INSTALL.vcxproj"));
op::copy_file_to_dir_if_better(cx(),
build_path / "zconf.h",
+1 -1
View File
@@ -37,7 +37,7 @@ cmake& cmake::def(const std::string& name, const std::string& value)
cmake& cmake::def(const std::string& name, const fs::path& p)
{
def(name, p.string());
def(name, path_to_utf8(p));
return *this;
}
+3 -3
View File
@@ -67,7 +67,7 @@ void extractor::do_run()
// so the handling of a duplicate directory is done manually in
// check_duplicate_directory() below
if (file_.string().ends_with(".tar.gz"))
if (file_.u8string().ends_with(u8".tar.gz"))
{
cx_->trace(context::generic, "this is a tar.gz, piping");
@@ -109,7 +109,7 @@ void extractor::do_run()
void extractor::check_duplicate_directory(const fs::path& ifile)
{
const auto dir_name = where_.filename().string();
const auto dir_name = where_.filename();
// check for a folder with the same name
if (!fs::exists(where_ / dir_name))
@@ -160,7 +160,7 @@ void extractor::check_duplicate_directory(const fs::path& ifile)
// give it a temp name in case there's yet another directory with the
// same name in it
const auto temp_dir = where_ / ("_mob_" + dir_name );
const auto temp_dir = where_ / (u8"_mob_" + dir_name.u8string());
cx_->trace(context::generic,
"renaming dir to {} to avoid clashes", temp_dir);
+1
View File
@@ -25,6 +25,7 @@ int basic_process_runner::execute_and_join()
process_.set_context(cx_);
process_.run();
join();
return process_.exit_code();
}
+1 -1
View File
@@ -483,7 +483,7 @@ std::string cp_to_utf8(std::string_view s)
return *s8;
}
std::string path_to_utf8(const fs::path& p)
std::string path_to_utf8(fs::path p)
{
return utf16_to_utf8(p.native());
}
+13 -1
View File
@@ -32,6 +32,14 @@ inline void mob_assert(
}
enum class encodings
{
dont_know = 0,
utf8,
utf16
};
class context;
class url;
@@ -214,7 +222,11 @@ std::string trim_copy(const std::string& s, const std::string& what=" \t\r\n");
std::wstring utf8_to_utf16(std::string_view s);
std::string utf16_to_utf8(std::wstring_view ws);
std::string path_to_utf8(const fs::path& p);
template <class T>
std::string path_to_utf8(T&&) = delete;
std::string path_to_utf8(fs::path p);
class u8stream
+2 -2
View File
@@ -22,13 +22,13 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">