Skip to content

Commit fe74eee

Browse files
committed
Handle Windows CLI arguments as UTF-8
1 parent 802fec8 commit fe74eee

1 file changed

Lines changed: 58 additions & 1 deletion

File tree

‎app/cli/main.cpp‎

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
#include <utility>
2525
#include <vector>
2626

27+
#ifdef _WIN32
28+
#ifndef NOMINMAX
29+
#define NOMINMAX
30+
#endif
31+
#include <windows.h>
32+
#endif
33+
2734
#ifdef _OPENMP
2835
#include <omp.h>
2936
#endif
@@ -505,7 +512,35 @@ void run_streaming(
505512

506513
} // namespace
507514

508-
int main(int argc, char ** argv) {
515+
#ifdef _WIN32
516+
namespace {
517+
518+
std::string wide_arg_to_utf8(const wchar_t * arg) {
519+
const int size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, arg, -1, nullptr, 0, nullptr, nullptr);
520+
if (size <= 0) {
521+
throw std::runtime_error("failed to convert Windows command-line argument to UTF-8");
522+
}
523+
std::vector<char> buffer(static_cast<size_t>(size), '\0');
524+
const int written = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, arg, -1, buffer.data(), size, nullptr, nullptr);
525+
if (written != size) {
526+
throw std::runtime_error("failed to convert Windows command-line argument to UTF-8");
527+
}
528+
return std::string(buffer.data());
529+
}
530+
531+
std::vector<std::string> wide_args_to_utf8(int argc, wchar_t ** wargv) {
532+
std::vector<std::string> args;
533+
args.reserve(static_cast<size_t>(argc));
534+
for (int i = 0; i < argc; ++i) {
535+
args.push_back(wide_arg_to_utf8(wargv[i]));
536+
}
537+
return args;
538+
}
539+
540+
} // namespace
541+
#endif
542+
543+
int audiocpp_cli_main(int argc, char ** argv) {
509544
try {
510545
using namespace minitts::cli;
511546

@@ -764,3 +799,25 @@ int main(int argc, char ** argv) {
764799
return 1;
765800
}
766801
}
802+
803+
#ifdef _WIN32
804+
int wmain(int argc, wchar_t ** wargv) {
805+
try {
806+
auto utf8_args = wide_args_to_utf8(argc, wargv);
807+
std::vector<char *> argv;
808+
argv.reserve(utf8_args.size() + 1);
809+
for (auto & arg : utf8_args) {
810+
argv.push_back(arg.data());
811+
}
812+
argv.push_back(nullptr);
813+
return audiocpp_cli_main(argc, argv.data());
814+
} catch (const std::exception & ex) {
815+
std::cerr << "audiocpp_cli failed: " << ex.what() << "\n";
816+
return 1;
817+
}
818+
}
819+
#else
820+
int main(int argc, char ** argv) {
821+
return audiocpp_cli_main(argc, argv);
822+
}
823+
#endif

0 commit comments

Comments
 (0)