From 6b6d77cc84e4b08641bc2f3fd3c4cf2a22ffdddf Mon Sep 17 00:00:00 2001 From: kevkevinpal Date: Sat, 11 Jul 2026 10:22:19 -0400 Subject: [PATCH] windows: remove deprecated codecvt via UTF-8 narrow APIs Drop wstring_convert/codecvt and the related wide process calls (_wsystem, _wexecvp, CreateProcessW) in favor of ::system, _execvp, and CreateProcess. --- CMakeLists.txt | 1 - cmake/introspection.cmake | 3 +- src/common/system.cpp | 5 ---- src/util/exec.cpp | 11 +++----- src/util/subprocess.h | 58 ++++++++++++++++++--------------------- 5 files changed, 32 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d67320bd53..fec2b1a3fa0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -471,7 +471,6 @@ if(MSVC) try_append_cxx_flags("/wd4805" TARGET warn_interface SKIP_LINK) target_compile_definitions(warn_interface INTERFACE _CRT_SECURE_NO_WARNINGS - _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING ) else() try_append_cxx_flags("-Wall" TARGET warn_interface SKIP_LINK) diff --git a/cmake/introspection.cmake b/cmake/introspection.cmake index d6083f5243a..612362795a3 100644 --- a/cmake/introspection.cmake +++ b/cmake/introspection.cmake @@ -24,8 +24,7 @@ endif() # Even though ::system is part of the standard library, we still check # for it, to support building targets that don't have it, such as iOS. check_cxx_symbol_exists(std::system "cstdlib" HAVE_STD_SYSTEM) -check_cxx_symbol_exists(::_wsystem "stdlib.h" HAVE__WSYSTEM) -if(HAVE_STD_SYSTEM OR HAVE__WSYSTEM) +if(HAVE_STD_SYSTEM) set(HAVE_SYSTEM 1) endif() diff --git a/src/common/system.cpp b/src/common/system.cpp index 72bf9da9d71..33918dd8d60 100644 --- a/src/common/system.cpp +++ b/src/common/system.cpp @@ -14,7 +14,6 @@ #ifdef WIN32 #include #include -#include #include #else #include @@ -49,11 +48,7 @@ std::string ShellEscape(const std::string& arg) void runCommand(const std::string& strCommand) { if (strCommand.empty()) return; -#ifndef WIN32 int nErr = ::system(strCommand.c_str()); -#else - int nErr = ::_wsystem(std::wstring_convert,wchar_t>().from_bytes(strCommand).c_str()); -#endif if (nErr) { LogWarning("runCommand error: system(%s) returned %d", strCommand, nErr); } diff --git a/src/util/exec.cpp b/src/util/exec.cpp index 87d11237394..69361fbc517 100644 --- a/src/util/exec.cpp +++ b/src/util/exec.cpp @@ -14,8 +14,6 @@ #include #ifdef WIN32 -#include -#include #include #include #else @@ -28,17 +26,16 @@ int ExecVp(const char* file, char* const argv[]) #ifndef WIN32 return execvp(file, argv); #else - std::vector escaped_args; - std::wstring_convert> converter; + std::vector escaped_args; for (char* const* arg_ptr{argv}; *arg_ptr; ++arg_ptr) { - subprocess::util::quote_argument(converter.from_bytes(*arg_ptr), escaped_args.emplace_back(), false); + subprocess::util::quote_argument(std::string{*arg_ptr}, escaped_args.emplace_back(), /*force=*/false); } - std::vector new_argv; + std::vector new_argv; new_argv.reserve(escaped_args.size() + 1); for (const auto& s : escaped_args) new_argv.push_back(s.c_str()); new_argv.push_back(nullptr); - return _wexecvp(converter.from_bytes(file).c_str(), new_argv.data()); + return _execvp(file, new_argv.data()); #endif } diff --git a/src/util/subprocess.h b/src/util/subprocess.h index 3d01f4b7f9c..5a64b116ad0 100644 --- a/src/util/subprocess.h +++ b/src/util/subprocess.h @@ -48,22 +48,16 @@ Documentation for C++ subprocessing library. #include #include #include -#include #include #include #include #include #include -#ifdef WIN32 - #include -#endif - extern "C" { #ifdef WIN32 #include #include - #include #else #include #include @@ -168,9 +162,12 @@ public: namespace util { #ifdef WIN32 - inline void quote_argument(const std::wstring &argument, std::wstring &command_line, + inline void quote_argument(const std::string &argument, std::string &command_line, bool force) { + constexpr char quote = '"'; + constexpr char backslash = '\\'; + // // Unless we're told otherwise, don't quote unless we actually // need to do so --- hopefully avoid problems if programs won't @@ -178,16 +175,16 @@ namespace util // if (force == false && argument.empty() == false && - argument.find_first_of(L" \t\n\v") == argument.npos) { + argument.find_first_of(" \t\n\v") == argument.npos) { command_line.append(argument); } else { - command_line.push_back(L'"'); + command_line.push_back(quote); for (auto it = argument.begin();; ++it) { unsigned number_backslashes = 0; - while (it != argument.end() && *it == L'\\') { + while (it != argument.end() && *it == backslash) { ++it; ++number_backslashes; } @@ -200,17 +197,17 @@ namespace util // as a metacharacter. // - command_line.append(number_backslashes * 2, L'\\'); + command_line.append(number_backslashes * 2, backslash); break; } - else if (*it == L'"') { + else if (*it == quote) { // // Escape all backslashes and the following // double quotation mark. // - command_line.append(number_backslashes * 2 + 1, L'\\'); + command_line.append(number_backslashes * 2 + 1, backslash); command_line.push_back(*it); } else { @@ -219,12 +216,12 @@ namespace util // Backslashes aren't special here. // - command_line.append(number_backslashes, L'\\'); + command_line.append(number_backslashes, backslash); command_line.push_back(*it); } } - command_line.push_back(L'"'); + command_line.push_back(quote); } } @@ -1085,37 +1082,36 @@ inline void Popen::execute_process() noexcept(false) } this->exe_name_ = vargs_[0]; - std::wstring_convert> converter; - std::wstring argument; - std::wstring command_line; + std::string argument; + std::string command_line; bool first_arg = true; for (auto arg : this->vargs_) { if (!first_arg) { - command_line += L" "; + command_line += " "; } else { first_arg = false; } - argument = converter.from_bytes(arg); - util::quote_argument(argument, command_line, false); + argument = arg; + util::quote_argument(argument, command_line, /*force=*/false); } - // CreateProcessW can modify szCmdLine so we allocate needed memory - wchar_t *szCmdline = new wchar_t[command_line.size() + 1]; - wcscpy_s(szCmdline, command_line.size() + 1, command_line.c_str()); + // CreateProcessA can modify szCmdLine so we allocate needed memory + char *szCmdline = new char[command_line.size() + 1]; + strcpy_s(szCmdline, command_line.size() + 1, command_line.c_str()); PROCESS_INFORMATION piProcInfo; - STARTUPINFOW siStartInfo; + STARTUPINFOA siStartInfo; BOOL bSuccess = FALSE; - DWORD creation_flags = CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW; + DWORD creation_flags = CREATE_NO_WINDOW; // Set up members of the PROCESS_INFORMATION structure. ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION)); - // Set up members of the STARTUPINFOW structure. + // Set up members of the STARTUPINFOA structure. // This structure specifies the STDIN and STDOUT handles for redirection. - ZeroMemory(&siStartInfo, sizeof(STARTUPINFOW)); - siStartInfo.cb = sizeof(STARTUPINFOW); + ZeroMemory(&siStartInfo, sizeof(STARTUPINFOA)); + siStartInfo.cb = sizeof(STARTUPINFOA); siStartInfo.hStdError = this->stream_.g_hChildStd_ERR_Wr; siStartInfo.hStdOutput = this->stream_.g_hChildStd_OUT_Wr; @@ -1124,7 +1120,7 @@ inline void Popen::execute_process() noexcept(false) siStartInfo.dwFlags |= STARTF_USESTDHANDLES; // Create the child process. - bSuccess = CreateProcessW(NULL, + bSuccess = CreateProcessA(NULL, szCmdline, // command line NULL, // process security attributes NULL, // primary thread security attributes @@ -1132,7 +1128,7 @@ inline void Popen::execute_process() noexcept(false) creation_flags, // creation flags NULL, // use parent's environment NULL, // use parent's current directory - &siStartInfo, // STARTUPINFOW pointer + &siStartInfo, // STARTUPINFOA pointer &piProcInfo); // receives PROCESS_INFORMATION // If an error occurs, exit the application.