[Impeller] Convert the ImpellerC command line arguments to UTF-8 on Windows (flutter/engine#36335)

This commit is contained in:
Jason Simmons 2022-09-22 08:13:09 -07:00 committed by GitHub
parent 1e8cdf3f2c
commit 136cbcc67f
6 changed files with 65 additions and 3 deletions

View File

@ -335,6 +335,7 @@ FILE: ../../../flutter/fml/platform/linux/message_loop_linux.h
FILE: ../../../flutter/fml/platform/linux/paths_linux.cc
FILE: ../../../flutter/fml/platform/linux/timerfd.cc
FILE: ../../../flutter/fml/platform/linux/timerfd.h
FILE: ../../../flutter/fml/platform/posix/command_line_posix.cc
FILE: ../../../flutter/fml/platform/posix/file_posix.cc
FILE: ../../../flutter/fml/platform/posix/mapping_posix.cc
FILE: ../../../flutter/fml/platform/posix/native_library_posix.cc
@ -342,6 +343,7 @@ FILE: ../../../flutter/fml/platform/posix/paths_posix.cc
FILE: ../../../flutter/fml/platform/posix/posix_wrappers_posix.cc
FILE: ../../../flutter/fml/platform/posix/shared_mutex_posix.cc
FILE: ../../../flutter/fml/platform/posix/shared_mutex_posix.h
FILE: ../../../flutter/fml/platform/win/command_line_win.cc
FILE: ../../../flutter/fml/platform/win/errors_win.cc
FILE: ../../../flutter/fml/platform/win/errors_win.h
FILE: ../../../flutter/fml/platform/win/file_win.cc

View File

@ -214,6 +214,7 @@ source_set("fml") {
if (is_win) {
sources += [
"platform/win/command_line_win.cc",
"platform/win/errors_win.cc",
"platform/win/errors_win.h",
"platform/win/file_win.cc",
@ -226,6 +227,7 @@ source_set("fml") {
]
} else {
sources += [
"platform/posix/command_line_posix.cc",
"platform/posix/file_posix.cc",
"platform/posix/mapping_posix.cc",
"platform/posix/native_library_posix.cc",

View File

@ -38,6 +38,7 @@
#include <cstddef>
#include <initializer_list>
#include <optional>
#include <string>
#include <string_view>
#include <unordered_map>
@ -239,6 +240,13 @@ inline CommandLine CommandLineFromInitializerList(
// outlined at the top of this file.
std::vector<std::string> CommandLineToArgv(const CommandLine& command_line);
// Builds a |CommandLine| by obtaining the arguments of the process using host
// platform APIs. The resulting |CommandLine| will be encoded in UTF-8.
// Returns an empty optional if this is not supported on the host platform.
//
// This can be useful on platforms where argv may not be provided as UTF-8.
std::optional<CommandLine> CommandLineFromPlatform();
} // namespace fml
#endif // LIB_FML_COMMAND_LINE_H_

View File

@ -0,0 +1,13 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/fml/command_line.h"
namespace fml {
std::optional<CommandLine> CommandLineFromPlatform() {
return std::nullopt;
}
} // namespace fml

View File

@ -0,0 +1,35 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/fml/command_line.h"
#include <windows.h>
#include <Shellapi.h>
#include <memory>
namespace fml {
std::optional<CommandLine> CommandLineFromPlatform() {
wchar_t* command_line = GetCommandLineW();
int unicode_argc;
std::unique_ptr<wchar_t*[], decltype(::LocalFree)*> unicode_argv(
CommandLineToArgvW(command_line, &unicode_argc), ::LocalFree);
if (!unicode_argv) {
return std::nullopt;
}
std::vector<std::string> utf8_argv;
for (int i = 0; i < unicode_argc; ++i) {
wchar_t* arg = unicode_argv[i];
int arg_len = WideCharToMultiByte(CP_UTF8, 0, arg, wcslen(arg), nullptr, 0,
nullptr, nullptr);
std::string utf8_arg(arg_len, 0);
WideCharToMultiByte(CP_UTF8, 0, arg, -1, utf8_arg.data(), utf8_arg.size(),
nullptr, nullptr);
utf8_argv.push_back(std::move(utf8_arg));
}
return CommandLineFromIterators(utf8_argv.begin(), utf8_argv.end());
}
} // namespace fml

View File

@ -227,7 +227,9 @@ bool Main(const fml::CommandLine& command_line) {
} // namespace impeller
int main(int argc, char const* argv[]) {
return impeller::compiler::Main(fml::CommandLineFromArgcArgv(argc, argv))
? EXIT_SUCCESS
: EXIT_FAILURE;
std::optional<fml::CommandLine> command_line = fml::CommandLineFromPlatform();
if (!command_line) {
command_line = fml::CommandLineFromArgcArgv(argc, argv);
}
return impeller::compiler::Main(*command_line) ? EXIT_SUCCESS : EXIT_FAILURE;
}