Skip to content

Commit

Permalink
Handle argument file with none ascii chars
Browse files Browse the repository at this point in the history
  • Loading branch information
hknielsen committed Sep 25, 2023
1 parent 63a8a70 commit f55efe2
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 11 deletions.
3 changes: 2 additions & 1 deletion build_defs/cpp_opts.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ LINK_OPTS = select({
"//build_defs:config_android-gnu-libstdcpp": [],
"//build_defs:config_android-default": [],
"//build_defs:config_msvc": [
# Suppress linker warnings about files with no symbols defined.
# Suppress linker warnings about files with no symbolignore:4221",
"-ignore:4221",
"Shell32.lib",
],
"@platforms//os:macos": [
"-lpthread",
Expand Down
13 changes: 8 additions & 5 deletions src/google/protobuf/compiler/command_line_interface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1171,7 +1171,7 @@ FieldOptions::OptionTargetType GetTargetType(const MethodDescriptor*) {
}
} // namespace

int CommandLineInterface::Run(int argc, const char* const argv[]) {
int CommandLineInterface::Run(int argc, const wchar_t* const argv[]) {
Clear();

switch (ParseArguments(argc, argv)) {
Expand Down Expand Up @@ -1771,14 +1771,15 @@ bool CommandLineInterface::MakeInputsBeProtoPathRelative(


bool CommandLineInterface::ExpandArgumentFile(
const std::string& file, std::vector<std::string>* arguments) {
const std::wstring& file, std::vector<std::string>* arguments) {
// The argument file is searched in the working directory only. We don't
// use the proto import path here.
std::ifstream file_stream(file.c_str());
if (!file_stream.is_open()) {
return false;
}
std::string argument;

// We don't support any kind of shell expansion right now.
while (std::getline(file_stream, argument)) {
arguments->push_back(argument);
Expand All @@ -1787,8 +1788,8 @@ bool CommandLineInterface::ExpandArgumentFile(
}

CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments(
int argc, const char* const argv[]) {
// executable_name_ = argv[0];
int argc, const wchar_t* const argv[]) {
executable_name_ = argv[0];

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

// if no arguments are given, show help
Expand Down
6 changes: 3 additions & 3 deletions src/google/protobuf/compiler/command_line_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ class PROTOC_EXPORT CommandLineInterface {
//
// It may not be safe to call Run() in a multi-threaded environment because
// it calls strerror(). I'm not sure why you'd want to do this anyway.
int Run(int argc, const char* const argv[]);
int Run(int argc, const wchar_t* const argv[]);

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

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

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

// Parses a command-line argument into a name/value pair. Returns
Expand Down
21 changes: 19 additions & 2 deletions src/google/protobuf/compiler/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@

// Must be included last.
#include "google/protobuf/port_def.inc"
#include <windows.h>

namespace google {
namespace protobuf {
namespace compiler {

int ProtobufMain(int argc, char* argv[]) {
int ProtobufMain(int argc, wchar_t* argv[]) {
absl::InitializeLog();

CommandLineInterface cli;
Expand Down Expand Up @@ -101,6 +102,22 @@ int ProtobufMain(int argc, char* argv[]) {
} // namespace protobuf
} // namespace google


int main(int argc, char* argv[]) {
return google::protobuf::compiler::ProtobufMain(argc, argv);

wchar_t** wargv;

#if defined(_MSC_VER)
int wargCount;
wargv = CommandLineToArgvW(GetCommandLineW(), &wargCount);
#else
// convert char** to wchar_t**
wargv = new wchar_t*[argc];
for (int i = 0; i < argc; ++i) {
wargv[i] = new wchar_t[strlen(argv[i]) + 1];
mbstowcs(wargv[i], argv[i], strlen(argv[i]) + 1);
}
#endif

return google::protobuf::compiler::ProtobufMain(argc, wargv);
}

0 comments on commit f55efe2

Please sign in to comment.