Support Unicode command line arguments on Windows.
GitOrigin-RevId: c4e20183cac0e98964850fb6a78c020996489bc1
This commit is contained in:
parent
25accb2d4d
commit
72b63e2533
@ -337,6 +337,9 @@ if (WIN32)
|
|||||||
else()
|
else()
|
||||||
target_link_libraries(tdutils PRIVATE ws2_32 Mswsock Normaliz psapi)
|
target_link_libraries(tdutils PRIVATE ws2_32 Mswsock Normaliz psapi)
|
||||||
endif()
|
endif()
|
||||||
|
if (NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
|
||||||
|
target_link_libraries(tdutils PRIVATE shell32)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ANDROID)
|
if (ANDROID)
|
||||||
|
@ -9,9 +9,17 @@
|
|||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
#include "td/utils/PathView.h"
|
#include "td/utils/PathView.h"
|
||||||
|
|
||||||
|
#if TD_PORT_WINDOWS && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
#include "td/utils/port/wstring_convert.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#if TD_PORT_WINDOWS && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
#include <shellapi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
void OptionParser::set_usage(Slice executable_name, Slice usage) {
|
void OptionParser::set_usage(Slice executable_name, Slice usage) {
|
||||||
@ -63,6 +71,21 @@ void OptionParser::add_check(std::function<Status()> check) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result<vector<char *>> OptionParser::run(int argc, char *argv[], int expected_non_option_count) {
|
Result<vector<char *>> OptionParser::run(int argc, char *argv[], int expected_non_option_count) {
|
||||||
|
#if TD_PORT_WINDOWS && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
LPWSTR *utf16_argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||||
|
if (utf16_argv == nullptr) {
|
||||||
|
return Status::Error("Failed to parse command line");
|
||||||
|
}
|
||||||
|
vector<string> args_storage(argc);
|
||||||
|
vector<char *> args(argc);
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
TRY_RESULT_ASSIGN(args_storage[i], from_wstring(utf16_argv[i]));
|
||||||
|
args[i] = &args_storage[i][0];
|
||||||
|
}
|
||||||
|
LocalFree(utf16_argv);
|
||||||
|
argv = &args[0];
|
||||||
|
#endif
|
||||||
|
|
||||||
std::unordered_map<char, const Option *> short_options;
|
std::unordered_map<char, const Option *> short_options;
|
||||||
std::unordered_map<string, const Option *> long_options;
|
std::unordered_map<string, const Option *> long_options;
|
||||||
for (auto &opt : options_) {
|
for (auto &opt : options_) {
|
||||||
@ -91,7 +114,7 @@ Result<vector<char *>> OptionParser::run(int argc, char *argv[], int expected_no
|
|||||||
|
|
||||||
if (arg[1] == '-') {
|
if (arg[1] == '-') {
|
||||||
// long option
|
// long option
|
||||||
Slice long_arg(arg + 2, std::strlen(arg + 2));
|
Slice long_arg(arg + 2);
|
||||||
Slice parameter;
|
Slice parameter;
|
||||||
auto equal_pos = long_arg.find('=');
|
auto equal_pos = long_arg.find('=');
|
||||||
bool has_equal = equal_pos != Slice::npos;
|
bool has_equal = equal_pos != Slice::npos;
|
||||||
@ -117,7 +140,7 @@ Result<vector<char *>> OptionParser::run(int argc, char *argv[], int expected_no
|
|||||||
if (++arg_pos == argc) {
|
if (++arg_pos == argc) {
|
||||||
return Status::Error(PSLICE() << "Option \"" << long_arg << "\" requires an argument");
|
return Status::Error(PSLICE() << "Option \"" << long_arg << "\" requires an argument");
|
||||||
}
|
}
|
||||||
parameter = Slice(argv[arg_pos], std::strlen(argv[arg_pos]));
|
parameter = Slice(argv[arg_pos]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -145,9 +168,9 @@ Result<vector<char *>> OptionParser::run(int argc, char *argv[], int expected_no
|
|||||||
if (++arg_pos == argc) {
|
if (++arg_pos == argc) {
|
||||||
return Status::Error(PSLICE() << "Option \"" << arg[opt_pos] << "\" requires an argument");
|
return Status::Error(PSLICE() << "Option \"" << arg[opt_pos] << "\" requires an argument");
|
||||||
}
|
}
|
||||||
parameter = Slice(argv[arg_pos], std::strlen(argv[arg_pos]));
|
parameter = Slice(argv[arg_pos]);
|
||||||
} else {
|
} else {
|
||||||
parameter = Slice(arg + opt_pos + 1, std::strlen(arg + opt_pos + 1));
|
parameter = Slice(arg + opt_pos + 1);
|
||||||
opt_pos += parameter.size();
|
opt_pos += parameter.size();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user