Skip to content

Commit f55efe2

Browse files
committed
Handle argument file with none ascii chars
1 parent 63a8a70 commit f55efe2

File tree

4 files changed

+32
-11
lines changed

4 files changed

+32
-11
lines changed

build_defs/cpp_opts.bzl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ LINK_OPTS = select({
3333
"//build_defs:config_android-gnu-libstdcpp": [],
3434
"//build_defs:config_android-default": [],
3535
"//build_defs:config_msvc": [
36-
# Suppress linker warnings about files with no symbols defined.
36+
# Suppress linker warnings about files with no symbolignore:4221",
3737
"-ignore:4221",
38+
"Shell32.lib",
3839
],
3940
"@platforms//os:macos": [
4041
"-lpthread",

src/google/protobuf/compiler/command_line_interface.cc

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,7 @@ FieldOptions::OptionTargetType GetTargetType(const MethodDescriptor*) {
11711171
}
11721172
} // namespace
11731173

1174-
int CommandLineInterface::Run(int argc, const char* const argv[]) {
1174+
int CommandLineInterface::Run(int argc, const wchar_t* const argv[]) {
11751175
Clear();
11761176

11771177
switch (ParseArguments(argc, argv)) {
@@ -1771,14 +1771,15 @@ bool CommandLineInterface::MakeInputsBeProtoPathRelative(
17711771

17721772

17731773
bool CommandLineInterface::ExpandArgumentFile(
1774-
const std::string& file, std::vector<std::string>* arguments) {
1774+
const std::wstring& file, std::vector<std::string>* arguments) {
17751775
// The argument file is searched in the working directory only. We don't
17761776
// use the proto import path here.
17771777
std::ifstream file_stream(file.c_str());
17781778
if (!file_stream.is_open()) {
17791779
return false;
17801780
}
17811781
std::string argument;
1782+
17821783
// We don't support any kind of shell expansion right now.
17831784
while (std::getline(file_stream, argument)) {
17841785
arguments->push_back(argument);
@@ -1787,8 +1788,8 @@ bool CommandLineInterface::ExpandArgumentFile(
17871788
}
17881789

17891790
CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments(
1790-
int argc, const char* const argv[]) {
1791-
// executable_name_ = argv[0];
1791+
int argc, const wchar_t* const argv[]) {
1792+
executable_name_ = argv[0];
17921793

17931794
std::vector<std::string> arguments;
17941795
for (int i = 1; i < argc; ++i) {
@@ -1800,7 +1801,9 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments(
18001801
}
18011802
continue;
18021803
}
1803-
arguments.push_back(argv[i]);
1804+
// We handle arguments as normal char to not ripple wchar_t through the codebase
1805+
std::wstring tempWstring(argv[i]);
1806+
arguments.push_back(std::string(tempWstring.begin(), tempWstring.end()));
18041807
}
18051808

18061809
// if no arguments are given, show help

src/google/protobuf/compiler/command_line_interface.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class PROTOC_EXPORT CommandLineInterface {
179179
//
180180
// It may not be safe to call Run() in a multi-threaded environment because
181181
// it calls strerror(). I'm not sure why you'd want to do this anyway.
182-
int Run(int argc, const char* const argv[]);
182+
int Run(int argc, const wchar_t* const argv[]);
183183

184184
// DEPRECATED. Calling this method has no effect. Protocol compiler now
185185
// always try to find the .proto file relative to the current directory
@@ -231,11 +231,11 @@ class PROTOC_EXPORT CommandLineInterface {
231231
};
232232

233233
// Parse all command-line arguments.
234-
ParseArgumentStatus ParseArguments(int argc, const char* const argv[]);
234+
ParseArgumentStatus ParseArguments(int argc, const wchar_t* const argv[]);
235235

236236
// Read an argument file and append the file's content to the list of
237237
// arguments. Return false if the file cannot be read.
238-
bool ExpandArgumentFile(const std::string& file,
238+
bool ExpandArgumentFile(const std::wstring& file,
239239
std::vector<std::string>* arguments);
240240

241241
// Parses a command-line argument into a name/value pair. Returns

src/google/protobuf/compiler/main.cc

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@
2020

2121
// Must be included last.
2222
#include "google/protobuf/port_def.inc"
23+
#include <windows.h>
2324

2425
namespace google {
2526
namespace protobuf {
2627
namespace compiler {
2728

28-
int ProtobufMain(int argc, char* argv[]) {
29+
int ProtobufMain(int argc, wchar_t* argv[]) {
2930
absl::InitializeLog();
3031

3132
CommandLineInterface cli;
@@ -101,6 +102,22 @@ int ProtobufMain(int argc, char* argv[]) {
101102
} // namespace protobuf
102103
} // namespace google
103104

105+
104106
int main(int argc, char* argv[]) {
105-
return google::protobuf::compiler::ProtobufMain(argc, argv);
107+
108+
wchar_t** wargv;
109+
110+
#if defined(_MSC_VER)
111+
int wargCount;
112+
wargv = CommandLineToArgvW(GetCommandLineW(), &wargCount);
113+
#else
114+
// convert char** to wchar_t**
115+
wargv = new wchar_t*[argc];
116+
for (int i = 0; i < argc; ++i) {
117+
wargv[i] = new wchar_t[strlen(argv[i]) + 1];
118+
mbstowcs(wargv[i], argv[i], strlen(argv[i]) + 1);
119+
}
120+
#endif
121+
122+
return google::protobuf::compiler::ProtobufMain(argc, wargv);
106123
}

0 commit comments

Comments
 (0)