aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools
diff options
context:
space:
mode:
authorGravatar Yun Peng <pcloudy@google.com>2018-06-25 05:35:50 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-06-25 05:36:55 -0700
commit40f5a773e97d0e389838becd3fe0a8ab43853999 (patch)
tree2c2aec321caa559b43787281fd097a7545eacc28 /src/tools
parentd753745d58fc45fcb50623073829644812083da0 (diff)
Windows: Native launcher now works with unicode.
The native launcher can now launch Java and Bash binary in directory with non-English characters. Unfortunately, python doesn't support running python zip file under directory with non-English characters. eg. python ./??/bin.zip will still fail. See https://github.com/bazelbuild/bazel/issues/4473 Change-Id: I77fe9cdaabffc2e0d25c7097da5c0c9333a9c4a3 PiperOrigin-RevId: 201939391
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/launcher/bash_launcher.cc20
-rw-r--r--src/tools/launcher/bash_launcher.h4
-rw-r--r--src/tools/launcher/java_launcher.cc276
-rw-r--r--src/tools/launcher/java_launcher.h18
-rw-r--r--src/tools/launcher/launcher.cc132
-rw-r--r--src/tools/launcher/launcher.h44
-rw-r--r--src/tools/launcher/launcher_main.cc14
-rw-r--r--src/tools/launcher/python_launcher.cc10
-rw-r--r--src/tools/launcher/python_launcher.h4
-rw-r--r--src/tools/launcher/util/data_parser.cc14
-rw-r--r--src/tools/launcher/util/data_parser.h4
-rw-r--r--src/tools/launcher/util/data_parser_test.cc6
-rw-r--r--src/tools/launcher/util/launcher_util.cc131
-rw-r--r--src/tools/launcher/util/launcher_util.h39
-rw-r--r--src/tools/launcher/util/launcher_util_test.cc185
15 files changed, 465 insertions, 436 deletions
diff --git a/src/tools/launcher/bash_launcher.cc b/src/tools/launcher/bash_launcher.cc
index 2692c17b35..cd714abc38 100644
--- a/src/tools/launcher/bash_launcher.cc
+++ b/src/tools/launcher/bash_launcher.cc
@@ -22,33 +22,33 @@
namespace bazel {
namespace launcher {
-using std::ostringstream;
-using std::string;
using std::vector;
+using std::wostringstream;
+using std::wstring;
static constexpr const char* BASH_BIN_PATH = "bash_bin_path";
ExitCode BashBinaryLauncher::Launch() {
- string bash_binary = this->GetLaunchInfoByKey(BASH_BIN_PATH);
+ wstring bash_binary = this->GetLaunchInfoByKey(BASH_BIN_PATH);
// If specified bash binary path doesn't exist, then fall back to
// bash.exe and hope it's in PATH.
if (!DoesFilePathExist(bash_binary.c_str())) {
- bash_binary = "bash.exe";
+ bash_binary = L"bash.exe";
}
- vector<string> origin_args = this->GetCommandlineArguments();
- ostringstream bash_command;
- string bash_main_file = GetBinaryPathWithoutExtension(origin_args[0]);
+ vector<wstring> origin_args = this->GetCommandlineArguments();
+ wostringstream bash_command;
+ wstring bash_main_file = GetBinaryPathWithoutExtension(origin_args[0]);
bash_command << GetEscapedArgument(bash_main_file,
/*escape_backslash = */ true);
for (int i = 1; i < origin_args.size(); i++) {
- bash_command << ' ';
+ bash_command << L' ';
bash_command << GetEscapedArgument(origin_args[i],
/*escape_backslash = */ true);
}
- vector<string> args;
- args.push_back("-c");
+ vector<wstring> args;
+ args.push_back(L"-c");
args.push_back(
GetEscapedArgument(bash_command.str(), /*escape_backslash = */ true));
return this->LaunchProcess(bash_binary, args);
diff --git a/src/tools/launcher/bash_launcher.h b/src/tools/launcher/bash_launcher.h
index 758735561e..38c9d0e12b 100644
--- a/src/tools/launcher/bash_launcher.h
+++ b/src/tools/launcher/bash_launcher.h
@@ -23,8 +23,8 @@ namespace launcher {
class BashBinaryLauncher : public BinaryLauncherBase {
public:
BashBinaryLauncher(const LaunchDataParser::LaunchInfo& launch_info, int argc,
- char* argv[])
- : BinaryLauncherBase(launch_info, argc, argv){}
+ wchar_t* argv[])
+ : BinaryLauncherBase(launch_info, argc, argv) {}
ExitCode Launch();
};
diff --git a/src/tools/launcher/java_launcher.cc b/src/tools/launcher/java_launcher.cc
index 053218d4f2..82eeb0bcab 100644
--- a/src/tools/launcher/java_launcher.cc
+++ b/src/tools/launcher/java_launcher.cc
@@ -30,12 +30,12 @@ namespace bazel {
namespace launcher {
using std::getline;
-using std::ofstream;
-using std::ostringstream;
using std::string;
-using std::stringstream;
using std::vector;
+using std::wofstream;
+using std::wostringstream;
using std::wstring;
+using std::wstringstream;
// The runfile path of java binary, eg. local_jdk/bin/java.exe
static constexpr const char* JAVA_BIN_PATH = "java_bin_path";
@@ -47,15 +47,15 @@ static constexpr const char* JVM_FLAGS = "jvm_flags";
// Check if a string start with a certain prefix.
// If it's true, store the substring without the prefix in value.
// If value is quoted, then remove the quotes.
-static bool GetFlagValue(const string& str, const string& prefix,
- string* value_ptr) {
+static bool GetFlagValue(const wstring& str, const wstring& prefix,
+ wstring* value_ptr) {
if (str.compare(0, prefix.length(), prefix)) {
return false;
}
- string& value = *value_ptr;
+ wstring& value = *value_ptr;
value = str.substr(prefix.length());
int len = value.length();
- if (len >= 2 && value[0] == '"' && value[len - 1] == '"') {
+ if (len >= 2 && value[0] == L'"' && value[len - 1] == L'"') {
value = value.substr(1, len - 2);
}
return true;
@@ -64,34 +64,34 @@ static bool GetFlagValue(const string& str, const string& prefix,
// Parses one launcher flag and updates this object's state accordingly.
//
// Returns true if the flag is a valid launcher flag; false otherwise.
-bool JavaBinaryLauncher::ProcessWrapperArgument(const string& argument) {
- string flag_value;
- if (argument.compare("--debug") == 0) {
- string default_jvm_debug_port;
- if (GetEnv("DEFAULT_JVM_DEBUG_PORT", &default_jvm_debug_port)) {
+bool JavaBinaryLauncher::ProcessWrapperArgument(const wstring& argument) {
+ wstring flag_value;
+ if (argument.compare(L"--debug") == 0) {
+ wstring default_jvm_debug_port;
+ if (GetEnv(L"DEFAULT_JVM_DEBUG_PORT", &default_jvm_debug_port)) {
this->jvm_debug_port = default_jvm_debug_port;
} else {
- this->jvm_debug_port = "5005";
+ this->jvm_debug_port = L"5005";
}
- } else if (GetFlagValue(argument, "--debug=", &flag_value)) {
+ } else if (GetFlagValue(argument, L"--debug=", &flag_value)) {
this->jvm_debug_port = flag_value;
- } else if (GetFlagValue(argument, "--main_advice=", &flag_value)) {
+ } else if (GetFlagValue(argument, L"--main_advice=", &flag_value)) {
this->main_advice = flag_value;
- } else if (GetFlagValue(argument, "--main_advice_classpath=", &flag_value)) {
+ } else if (GetFlagValue(argument, L"--main_advice_classpath=", &flag_value)) {
this->main_advice_classpath = flag_value;
- } else if (GetFlagValue(argument, "--jvm_flag=", &flag_value)) {
+ } else if (GetFlagValue(argument, L"--jvm_flag=", &flag_value)) {
this->jvm_flags_cmdline.push_back(flag_value);
- } else if (GetFlagValue(argument, "--jvm_flags=", &flag_value)) {
- stringstream flag_value_ss(flag_value);
- string item;
- while (getline(flag_value_ss, item, ' ')) {
+ } else if (GetFlagValue(argument, L"--jvm_flags=", &flag_value)) {
+ wstringstream flag_value_ss(flag_value);
+ wstring item;
+ while (getline(flag_value_ss, item, L' ')) {
this->jvm_flags_cmdline.push_back(item);
}
- } else if (argument.compare("--singlejar") == 0) {
+ } else if (argument.compare(L"--singlejar") == 0) {
this->singlejar = true;
- } else if (argument.compare("--print_javabin") == 0) {
+ } else if (argument.compare(L"--print_javabin") == 0) {
this->print_javabin = true;
- } else if (GetFlagValue(argument, "--classpath_limit=", &flag_value)) {
+ } else if (GetFlagValue(argument, L"--classpath_limit=", &flag_value)) {
this->classpath_limit = std::stoi(flag_value);
} else {
return false;
@@ -99,8 +99,8 @@ bool JavaBinaryLauncher::ProcessWrapperArgument(const string& argument) {
return true;
}
-vector<string> JavaBinaryLauncher::ProcessesCommandLine() {
- vector<string> args;
+vector<wstring> JavaBinaryLauncher::ProcessesCommandLine() {
+ vector<wstring> args;
bool first = 1;
for (const auto& arg : this->GetCommandlineArguments()) {
// Skip the first arugment.
@@ -108,13 +108,13 @@ vector<string> JavaBinaryLauncher::ProcessesCommandLine() {
first = 0;
continue;
}
- string flag_value;
+ wstring flag_value;
// TODO(pcloudy): Should rename this flag to --native_launcher_flag.
// But keep it as it is for now to be consistent with the shell script
// launcher.
- if (GetFlagValue(arg, "--wrapper_script_flag=", &flag_value)) {
+ if (GetFlagValue(arg, L"--wrapper_script_flag=", &flag_value)) {
if (!ProcessWrapperArgument(flag_value)) {
- die("invalid wrapper argument '%s'", arg.c_str());
+ die(L"invalid wrapper argument '%s'", arg.c_str());
}
} else if (!args.empty() || !ProcessWrapperArgument(arg)) {
args.push_back(arg);
@@ -124,34 +124,34 @@ vector<string> JavaBinaryLauncher::ProcessesCommandLine() {
}
// Return an absolute normalized path for the directory of manifest jar
-static string GetManifestJarDir(const string& binary_base_path) {
- string abs_manifest_jar_dir;
- std::size_t slash = binary_base_path.find_last_of("/\\");
- if (slash == string::npos) {
- abs_manifest_jar_dir = "";
+static wstring GetManifestJarDir(const wstring& binary_base_path) {
+ wstring abs_manifest_jar_dir;
+ std::size_t slash = binary_base_path.find_last_of(L"/\\");
+ if (slash == wstring::npos) {
+ abs_manifest_jar_dir = L"";
} else {
abs_manifest_jar_dir = binary_base_path.substr(0, slash);
}
if (!blaze_util::IsAbsolute(binary_base_path)) {
- abs_manifest_jar_dir = blaze_util::GetCwd() + "\\" + abs_manifest_jar_dir;
+ abs_manifest_jar_dir = blaze_util::GetCwdW() + L"\\" + abs_manifest_jar_dir;
}
- string result;
+ wstring result;
if (!NormalizePath(abs_manifest_jar_dir, &result)) {
- die("GetManifestJarDir Failed");
+ die(L"GetManifestJarDir Failed");
}
return result;
}
-static void WriteJarClasspath(const string& jar_path,
- ostringstream* manifest_classpath) {
- *manifest_classpath << ' ';
- if (jar_path.find_first_of(" \\") != string::npos) {
+static void WriteJarClasspath(const wstring& jar_path,
+ wostringstream* manifest_classpath) {
+ *manifest_classpath << L' ';
+ if (jar_path.find_first_of(L" \\") != wstring::npos) {
for (const auto& x : jar_path) {
- if (x == ' ') {
- *manifest_classpath << "%20";
+ if (x == L' ') {
+ *manifest_classpath << L"%20";
}
- if (x == '\\') {
- *manifest_classpath << "/";
+ if (x == L'\\') {
+ *manifest_classpath << L"/";
} else {
*manifest_classpath << x;
}
@@ -161,119 +161,117 @@ static void WriteJarClasspath(const string& jar_path,
}
}
-string JavaBinaryLauncher::GetJunctionBaseDir() {
- string binary_base_path =
+wstring JavaBinaryLauncher::GetJunctionBaseDir() {
+ wstring binary_base_path =
GetBinaryPathWithExtension(this->GetCommandlineArguments()[0]);
- string result;
- if (!NormalizePath(binary_base_path + ".j", &result)) {
- die("Failed to get normalized junction base directory.");
+ wstring result;
+ if (!NormalizePath(binary_base_path + L".j", &result)) {
+ die(L"Failed to get normalized junction base directory.");
}
return result;
}
void JavaBinaryLauncher::DeleteJunctionBaseDir() {
- string junction_base_dir_norm = GetJunctionBaseDir();
+ wstring junction_base_dir_norm = GetJunctionBaseDir();
if (!DoesDirectoryPathExist(junction_base_dir_norm.c_str())) {
return;
}
- vector<string> junctions;
- blaze_util::GetAllFilesUnder(junction_base_dir_norm, &junctions);
+ vector<wstring> junctions;
+ blaze_util::GetAllFilesUnderW(junction_base_dir_norm, &junctions);
for (const auto& junction : junctions) {
if (!DeleteDirectoryByPath(junction.c_str())) {
- PrintError(GetLastErrorString().c_str());
+ PrintError(L"Failed to delete junction directory: %hs",
+ GetLastErrorString().c_str());
}
}
if (!DeleteDirectoryByPath(junction_base_dir_norm.c_str())) {
- PrintError(GetLastErrorString().c_str());
+ PrintError(L"Failed to delete junction directory: %hs",
+ GetLastErrorString().c_str());
}
}
-string JavaBinaryLauncher::CreateClasspathJar(const string& classpath) {
- string binary_base_path =
+wstring JavaBinaryLauncher::CreateClasspathJar(const wstring& classpath) {
+ wstring binary_base_path =
GetBinaryPathWithoutExtension(this->GetCommandlineArguments()[0]);
- string abs_manifest_jar_dir_norm = GetManifestJarDir(binary_base_path);
+ wstring abs_manifest_jar_dir_norm = GetManifestJarDir(binary_base_path);
- ostringstream manifest_classpath;
- manifest_classpath << "Class-Path:";
- stringstream classpath_ss(classpath);
- string path, path_norm;
+ wostringstream manifest_classpath;
+ manifest_classpath << L"Class-Path:";
+ wstringstream classpath_ss(classpath);
+ wstring path, path_norm;
// A set to store all junctions created.
// The key is the target path, the value is the junction path.
- std::unordered_map<string, string> jar_dirs;
- string junction_base_dir_norm = GetJunctionBaseDir();
+ std::unordered_map<wstring, wstring> jar_dirs;
+ wstring junction_base_dir_norm = GetJunctionBaseDir();
int junction_count = 0;
// Make sure the junction base directory doesn't exist already.
DeleteJunctionBaseDir();
- blaze_util::MakeDirectories(junction_base_dir_norm, 0755);
+ blaze_util::MakeDirectoriesW(junction_base_dir_norm, 0755);
- while (getline(classpath_ss, path, ';')) {
+ while (getline(classpath_ss, path, L';')) {
if (blaze_util::IsAbsolute(path)) {
if (!NormalizePath(path, &path_norm)) {
- die("CreateClasspathJar failed");
+ die(L"CreateClasspathJar failed");
}
// If two paths are under different drives, we should create a junction to
// the jar's directory
if (path_norm[0] != abs_manifest_jar_dir_norm[0]) {
- string jar_dir = GetParentDirFromPath(path_norm);
- string jar_base_name = GetBaseNameFromPath(path_norm);
- string junction;
+ wstring jar_dir = GetParentDirFromPath(path_norm);
+ wstring jar_base_name = GetBaseNameFromPath(path_norm);
+ wstring junction;
auto search = jar_dirs.find(jar_dir);
if (search == jar_dirs.end()) {
- junction =
- junction_base_dir_norm + "\\" + std::to_string(junction_count++);
-
- wstring wjar_dir(
- blaze_util::CstringToWstring(junction.c_str()).get());
- wstring wjunction(
- blaze_util::CstringToWstring(jar_dir.c_str()).get());
- wstring werror(bazel::windows::CreateJunction(wjar_dir, wjunction));
- if (!werror.empty()) {
- string error(werror.begin(), werror.end());
- die("CreateClasspathJar failed: %s", error.c_str());
+ junction = junction_base_dir_norm + L"\\" +
+ std::to_wstring(junction_count++);
+
+ wstring error(bazel::windows::CreateJunction(junction, jar_dir));
+ if (!error.empty()) {
+ die(L"CreateClasspathJar failed: %s", error.c_str());
}
jar_dirs.insert(std::make_pair(jar_dir, junction));
} else {
junction = search->second;
}
- path_norm = junction + "\\" + jar_base_name;
+ path_norm = junction + L"\\" + jar_base_name;
}
if (!RelativeTo(path_norm, abs_manifest_jar_dir_norm, &path)) {
- die("CreateClasspathJar failed");
+ die(L"CreateClasspathJar failed");
}
}
WriteJarClasspath(path, &manifest_classpath);
}
- string rand_id = "-" + GetRandomStr(10);
- string jar_manifest_file_path = binary_base_path + rand_id + ".jar_manifest";
- ofstream jar_manifest_file(jar_manifest_file_path);
- jar_manifest_file << "Manifest-Version: 1.0\n";
+ wstring rand_id = L"-" + GetRandomStr(10);
+ wstring jar_manifest_file_path =
+ binary_base_path + rand_id + L".jar_manifest";
+ wofstream jar_manifest_file(jar_manifest_file_path);
+ jar_manifest_file << L"Manifest-Version: 1.0\n";
// No line in the MANIFEST.MF file may be longer than 72 bytes.
// A space prefix indicates the line is still the content of the last
// attribute.
- string manifest_classpath_str = manifest_classpath.str();
+ wstring manifest_classpath_str = manifest_classpath.str();
for (size_t i = 0; i < manifest_classpath_str.length(); i += 71) {
if (i > 0) {
- jar_manifest_file << " ";
+ jar_manifest_file << L" ";
}
jar_manifest_file << manifest_classpath_str.substr(i, 71) << "\n";
}
jar_manifest_file.close();
// Create the command for generating classpath jar.
- string manifest_jar_path = binary_base_path + rand_id + "-classpath.jar";
- string jar_bin = this->Rlocation(this->GetLaunchInfoByKey(JAR_BIN_PATH));
- vector<string> arguments;
- arguments.push_back("cvfm");
+ wstring manifest_jar_path = binary_base_path + rand_id + L"-classpath.jar";
+ wstring jar_bin = this->Rlocation(this->GetLaunchInfoByKey(JAR_BIN_PATH));
+ vector<wstring> arguments;
+ arguments.push_back(L"cvfm");
arguments.push_back(manifest_jar_path);
arguments.push_back(jar_manifest_file_path);
if (this->LaunchProcess(jar_bin, arguments, /* suppressOutput */ true) != 0) {
- die("Couldn't create classpath jar: %s", manifest_jar_path.c_str());
+ die(L"Couldn't create classpath jar: %s", manifest_jar_path.c_str());
}
// Delete jar_manifest_file after classpath jar is created.
@@ -284,95 +282,95 @@ string JavaBinaryLauncher::CreateClasspathJar(const string& classpath) {
ExitCode JavaBinaryLauncher::Launch() {
// Parse the original command line.
- vector<string> remaining_args = this->ProcessesCommandLine();
+ vector<wstring> remaining_args = this->ProcessesCommandLine();
// Set JAVA_RUNFILES
- string java_runfiles;
- if (!GetEnv("JAVA_RUNFILES", &java_runfiles)) {
+ wstring java_runfiles;
+ if (!GetEnv(L"JAVA_RUNFILES", &java_runfiles)) {
java_runfiles = this->GetRunfilesPath();
}
- SetEnv("JAVA_RUNFILES", java_runfiles);
+ SetEnv(L"JAVA_RUNFILES", java_runfiles);
// Print Java binary path if needed
- string java_bin = this->Rlocation(this->GetLaunchInfoByKey(JAVA_BIN_PATH),
- /*need_workspace_name =*/false);
+ wstring java_bin = this->Rlocation(this->GetLaunchInfoByKey(JAVA_BIN_PATH),
+ /*need_workspace_name =*/false);
if (this->print_javabin ||
- this->GetLaunchInfoByKey(JAVA_START_CLASS) == "--print_javabin") {
- printf("%s\n", java_bin.c_str());
+ this->GetLaunchInfoByKey(JAVA_START_CLASS) == L"--print_javabin") {
+ wprintf(L"%s\n", java_bin.c_str());
return 0;
}
- ostringstream classpath;
+ wostringstream classpath;
// Run deploy jar if needed, otherwise generate the CLASSPATH by rlocation.
if (this->singlejar) {
- string deploy_jar =
+ wstring deploy_jar =
GetBinaryPathWithoutExtension(this->GetCommandlineArguments()[0]) +
- "_deploy.jar";
+ L"_deploy.jar";
if (!DoesFilePathExist(deploy_jar.c_str())) {
- die("Option --singlejar was passed, but %s does not exist.\n (You may "
+ die(L"Option --singlejar was passed, but %s does not exist.\n (You may "
"need to build it explicitly.)",
deploy_jar.c_str());
}
- classpath << deploy_jar << ';';
+ classpath << deploy_jar << L';';
} else {
// Add main advice classpath if exists
if (!this->main_advice_classpath.empty()) {
- classpath << this->main_advice_classpath << ';';
+ classpath << this->main_advice_classpath << L';';
}
- string path;
- stringstream classpath_ss(this->GetLaunchInfoByKey(CLASSPATH));
- while (getline(classpath_ss, path, ';')) {
- classpath << this->Rlocation(path) << ';';
+ wstring path;
+ wstringstream classpath_ss(this->GetLaunchInfoByKey(CLASSPATH));
+ while (getline(classpath_ss, path, L';')) {
+ classpath << this->Rlocation(path) << L';';
}
}
// Set jvm debug options
- ostringstream jvm_debug_flags;
+ wostringstream jvm_debug_flags;
if (!this->jvm_debug_port.empty()) {
- string jvm_debug_suspend;
- if (!GetEnv("DEFAULT_JVM_DEBUG_SUSPEND", &jvm_debug_suspend)) {
- jvm_debug_suspend = "y";
+ wstring jvm_debug_suspend;
+ if (!GetEnv(L"DEFAULT_JVM_DEBUG_SUSPEND", &jvm_debug_suspend)) {
+ jvm_debug_suspend = L"y";
}
- jvm_debug_flags << "-agentlib:jdwp=transport=dt_socket,server=y";
- jvm_debug_flags << ",suspend=" << jvm_debug_suspend;
- jvm_debug_flags << ",address=" << jvm_debug_port;
+ jvm_debug_flags << L"-agentlib:jdwp=transport=dt_socket,server=y";
+ jvm_debug_flags << L",suspend=" << jvm_debug_suspend;
+ jvm_debug_flags << L",address=" << jvm_debug_port;
- string value;
- if (GetEnv("PERSISTENT_TEST_RUNNER", &value) && value == "true") {
- jvm_debug_flags << ",quiet=y";
+ wstring value;
+ if (GetEnv(L"PERSISTENT_TEST_RUNNER", &value) && value == L"true") {
+ jvm_debug_flags << L",quiet=y";
}
}
// Get jvm flags from JVM_FLAGS environment variable and JVM_FLAGS launch info
- vector<string> jvm_flags;
- string jvm_flags_env;
- GetEnv("JVM_FLAGS", &jvm_flags_env);
- string flag;
- stringstream jvm_flags_env_ss(jvm_flags_env);
- while (getline(jvm_flags_env_ss, flag, ' ')) {
+ vector<wstring> jvm_flags;
+ wstring jvm_flags_env;
+ GetEnv(L"JVM_FLAGS", &jvm_flags_env);
+ wstring flag;
+ wstringstream jvm_flags_env_ss(jvm_flags_env);
+ while (getline(jvm_flags_env_ss, flag, L' ')) {
jvm_flags.push_back(flag);
}
- stringstream jvm_flags_launch_info_ss(this->GetLaunchInfoByKey(JVM_FLAGS));
- while (getline(jvm_flags_launch_info_ss, flag, ' ')) {
+ wstringstream jvm_flags_launch_info_ss(this->GetLaunchInfoByKey(JVM_FLAGS));
+ while (getline(jvm_flags_launch_info_ss, flag, L' ')) {
jvm_flags.push_back(flag);
}
// Check if TEST_TMPDIR is available to use for scratch.
- string test_tmpdir;
- if (GetEnv("TEST_TMPDIR", &test_tmpdir) &&
+ wstring test_tmpdir;
+ if (GetEnv(L"TEST_TMPDIR", &test_tmpdir) &&
DoesDirectoryPathExist(test_tmpdir.c_str())) {
- jvm_flags.push_back("-Djava.io.tmpdir=" + test_tmpdir);
+ jvm_flags.push_back(L"-Djava.io.tmpdir=" + test_tmpdir);
}
// Construct the final command line arguments
- vector<string> arguments;
+ vector<wstring> arguments;
// Add classpath flags
- arguments.push_back("-classpath");
+ arguments.push_back(L"-classpath");
// Check if CLASSPATH is over classpath length limit.
// If it does, then we create a classpath jar to pass CLASSPATH value.
- string classpath_str = classpath.str();
- string classpath_jar = "";
+ wstring classpath_str = classpath.str();
+ wstring classpath_jar = L"";
if (classpath_str.length() > this->classpath_limit) {
classpath_jar = CreateClasspathJar(classpath_str);
arguments.push_back(classpath_jar);
@@ -380,7 +378,7 @@ ExitCode JavaBinaryLauncher::Launch() {
arguments.push_back(classpath_str);
}
// Add JVM debug flags
- string jvm_debug_flags_str = jvm_debug_flags.str();
+ wstring jvm_debug_flags_str = jvm_debug_flags.str();
if (!jvm_debug_flags_str.empty()) {
arguments.push_back(jvm_debug_flags_str);
}
@@ -403,7 +401,7 @@ ExitCode JavaBinaryLauncher::Launch() {
arguments.push_back(arg);
}
- vector<string> escaped_arguments;
+ vector<wstring> escaped_arguments;
// Quote the arguments if having spaces
for (const auto& arg : arguments) {
escaped_arguments.push_back(
diff --git a/src/tools/launcher/java_launcher.h b/src/tools/launcher/java_launcher.h
index 93366b3a8a..d02a7165db 100644
--- a/src/tools/launcher/java_launcher.h
+++ b/src/tools/launcher/java_launcher.h
@@ -30,7 +30,7 @@ static const int MAX_ARG_STRLEN = 7000;
class JavaBinaryLauncher : public BinaryLauncherBase {
public:
JavaBinaryLauncher(const LaunchDataParser::LaunchInfo& launch_info, int argc,
- char* argv[])
+ wchar_t* argv[])
: BinaryLauncherBase(launch_info, argc, argv),
singlejar(false),
print_javabin(false),
@@ -68,19 +68,19 @@ class JavaBinaryLauncher : public BinaryLauncherBase {
// classpath jar.
//
// The remainder of the command line is passed to the program.
- bool ProcessWrapperArgument(const std::string& argument);
+ bool ProcessWrapperArgument(const std::wstring& argument);
// Parse arguments sequentially until the first unrecognized arg is
// encountered. Scan the remaining args for --wrapper_script_flag=X options
// and process them.
//
// Return the remaining arguments that should be passed to the program.
- std::vector<std::string> ProcessesCommandLine();
+ std::vector<std::wstring> ProcessesCommandLine();
- std::string jvm_debug_port;
- std::string main_advice;
- std::string main_advice_classpath;
- std::vector<std::string> jvm_flags_cmdline;
+ std::wstring jvm_debug_port;
+ std::wstring main_advice;
+ std::wstring main_advice_classpath;
+ std::vector<std::wstring> jvm_flags_cmdline;
bool singlejar;
bool print_javabin;
int classpath_limit;
@@ -89,11 +89,11 @@ class JavaBinaryLauncher : public BinaryLauncherBase {
// limit.
//
// Return the path of the classpath jar created.
- std::string CreateClasspathJar(const std::string& classpath);
+ std::wstring CreateClasspathJar(const std::wstring& classpath);
// Creat a directory based on the binary path, all the junctions will be
// generated under this directory.
- std::string GetJunctionBaseDir();
+ std::wstring GetJunctionBaseDir();
// Delete all the junction directory and all the junctions under it.
void DeleteJunctionBaseDir();
diff --git a/src/tools/launcher/launcher.cc b/src/tools/launcher/launcher.cc
index 9bcc3642c2..b663c2cc77 100644
--- a/src/tools/launcher/launcher.cc
+++ b/src/tools/launcher/launcher.cc
@@ -21,6 +21,7 @@
#include <vector>
#include "src/main/cpp/util/path_platform.h"
+#include "src/main/cpp/util/strings.h"
#include "src/tools/launcher/launcher.h"
#include "src/tools/launcher/util/data_parser.h"
#include "src/tools/launcher/util/launcher_util.h"
@@ -29,25 +30,26 @@ namespace bazel {
namespace launcher {
using std::ifstream;
-using std::ostringstream;
using std::string;
using std::unordered_map;
using std::vector;
+using std::wostringstream;
+using std::wstring;
-static std::string GetRunfilesDir(const char* argv0) {
- string runfiles_dir;
+static wstring GetRunfilesDir(const wchar_t* argv0) {
+ wstring runfiles_dir;
// If RUNFILES_DIR is already set (probably we are either in a test or in a
// data dependency) then use it.
- if (GetEnv("RUNFILES_DIR", &runfiles_dir)) {
+ if (GetEnv(L"RUNFILES_DIR", &runfiles_dir)) {
return runfiles_dir;
}
// Otherwise this is probably a top-level non-test binary (e.g. a genrule
// tool) and should look for its runfiles beside the executable.
- return GetBinaryPathWithExtension(argv0) + ".runfiles";
+ return GetBinaryPathWithExtension(argv0) + L".runfiles";
}
BinaryLauncherBase::BinaryLauncherBase(
- const LaunchDataParser::LaunchInfo& _launch_info, int argc, char* argv[])
+ const LaunchDataParser::LaunchInfo& _launch_info, int argc, wchar_t* argv[])
: launch_info(_launch_info),
manifest_file(FindManifestFile(argv[0])),
runfiles_dir(GetRunfilesDir(argv[0])),
@@ -58,22 +60,22 @@ BinaryLauncherBase::BinaryLauncherBase(
// Prefer to use the runfiles manifest, if it exists, but otherwise the
// runfiles directory will be used by default. On Windows, the manifest is
// used locally, and the runfiles directory is used remotely.
- if (manifest_file != "") {
+ if (!manifest_file.empty()) {
ParseManifestFile(&manifest_file_map, manifest_file);
}
}
-static bool FindManifestFileImpl(const char* argv0, string* result) {
+static bool FindManifestFileImpl(const wchar_t* argv0, wstring* result) {
// If this binary X runs as the data-dependency of some other binary Y, then
// X has no runfiles manifest/directory and should use Y's.
- if (GetEnv("RUNFILES_MANIFEST_FILE", result) &&
+ if (GetEnv(L"RUNFILES_MANIFEST_FILE", result) &&
DoesFilePathExist(result->c_str())) {
return true;
}
- string directory;
- if (GetEnv("RUNFILES_DIR", &directory)) {
- *result = directory + "/MANIFEST";
+ wstring directory;
+ if (GetEnv(L"RUNFILES_DIR", &directory)) {
+ *result = directory + L"/MANIFEST";
if (DoesFilePathExist(result->c_str())) {
return true;
}
@@ -82,13 +84,13 @@ static bool FindManifestFileImpl(const char* argv0, string* result) {
// If this binary X runs by itself (not as a data-dependency of another
// binary), then look for the manifest in a runfiles directory next to the
// main binary, then look for it (the manifest) next to the main binary.
- directory = GetBinaryPathWithExtension(argv0) + ".runfiles";
- *result = directory + "/MANIFEST";
+ directory = GetBinaryPathWithExtension(argv0) + L".runfiles";
+ *result = directory + L"/MANIFEST";
if (DoesFilePathExist(result->c_str())) {
return true;
}
- *result = directory + "_manifest";
+ *result = directory + L"_manifest";
if (DoesFilePathExist(result->c_str())) {
return true;
}
@@ -96,10 +98,10 @@ static bool FindManifestFileImpl(const char* argv0, string* result) {
return false;
}
-string BinaryLauncherBase::FindManifestFile(const char* argv0) {
- string manifest_file;
+wstring BinaryLauncherBase::FindManifestFile(const wchar_t* argv0) {
+ wstring manifest_file;
if (!FindManifestFileImpl(argv0, &manifest_file)) {
- return "";
+ return L"";
}
// The path will be set as the RUNFILES_MANIFEST_FILE envvar and used by the
// shell script, so let's convert backslashes to forward slashes.
@@ -107,35 +109,36 @@ string BinaryLauncherBase::FindManifestFile(const char* argv0) {
return manifest_file;
}
-string BinaryLauncherBase::GetRunfilesPath() const {
- string runfiles_path =
- GetBinaryPathWithExtension(this->commandline_arguments[0]) + ".runfiles";
- std::replace(runfiles_path.begin(), runfiles_path.end(), '/', '\\');
+wstring BinaryLauncherBase::GetRunfilesPath() const {
+ wstring runfiles_path =
+ GetBinaryPathWithExtension(this->commandline_arguments[0]) + L".runfiles";
+ std::replace(runfiles_path.begin(), runfiles_path.end(), L'/', L'\\');
return runfiles_path;
}
void BinaryLauncherBase::ParseManifestFile(ManifestFileMap* manifest_file_map,
- const string& manifest_path) {
+ const wstring& manifest_path) {
ifstream manifest_file(AsAbsoluteWindowsPath(manifest_path.c_str()).c_str());
if (!manifest_file) {
- die("Couldn't open MANIFEST file: %s", manifest_path.c_str());
+ die(L"Couldn't open MANIFEST file: %s", manifest_path.c_str());
}
string line;
while (getline(manifest_file, line)) {
size_t space_pos = line.find_first_of(' ');
if (space_pos == string::npos) {
- die("Wrong MANIFEST format at line: %s", line.c_str());
+ die(L"Wrong MANIFEST format at line: %s", line.c_str());
}
- string key = line.substr(0, space_pos);
- string value = line.substr(space_pos + 1);
+ wstring wline = blaze_util::CstringToWstring(line);
+ wstring key = wline.substr(0, space_pos);
+ wstring value = wline.substr(space_pos + 1);
manifest_file_map->insert(make_pair(key, value));
}
}
-string BinaryLauncherBase::Rlocation(const string& path,
- bool need_workspace_name) const {
+wstring BinaryLauncherBase::Rlocation(const wstring& path,
+ bool need_workspace_name) const {
// If the manifest file map is empty, then we're using the runfiles directory
// instead.
if (manifest_file_map.empty()) {
@@ -143,106 +146,111 @@ string BinaryLauncherBase::Rlocation(const string& path,
return path;
}
- string query_path = runfiles_dir;
+ wstring query_path = runfiles_dir;
if (need_workspace_name) {
- query_path += "/" + this->workspace_name;
+ query_path += L"/" + this->workspace_name;
}
- query_path += "/" + path;
+ query_path += L"/" + path;
return query_path;
}
- string query_path = path;
+ wstring query_path = path;
if (need_workspace_name) {
- query_path = this->workspace_name + "/" + path;
+ query_path = this->workspace_name + L"/" + path;
}
auto entry = manifest_file_map.find(query_path);
if (entry == manifest_file_map.end()) {
- die("Rlocation failed on %s, path doesn't exist in MANIFEST file",
+ die(L"Rlocation failed on %s, path doesn't exist in MANIFEST file",
query_path.c_str());
}
return entry->second;
}
-string BinaryLauncherBase::GetLaunchInfoByKey(const string& key) {
+wstring BinaryLauncherBase::Rlocation(const string& path,
+ bool need_workspace_name) const {
+ return this->Rlocation(blaze_util::CstringToWstring(path),
+ need_workspace_name);
+}
+
+wstring BinaryLauncherBase::GetLaunchInfoByKey(const string& key) {
auto item = launch_info.find(key);
if (item == launch_info.end()) {
- die("Cannot find key \"%s\" from launch data.\n", key.c_str());
+ die(L"Cannot find key \"%hs\" from launch data.\n", key.c_str());
}
return item->second;
}
-const vector<string>& BinaryLauncherBase::GetCommandlineArguments() const {
+const vector<wstring>& BinaryLauncherBase::GetCommandlineArguments() const {
return this->commandline_arguments;
}
void BinaryLauncherBase::CreateCommandLine(
- CmdLine* result, const string& executable,
- const vector<string>& arguments) const {
- ostringstream cmdline;
- cmdline << '\"' << executable << '\"';
+ CmdLine* result, const wstring& executable,
+ const vector<wstring>& arguments) const {
+ wostringstream cmdline;
+ cmdline << L'\"' << executable << L'\"';
for (const auto& s : arguments) {
- cmdline << ' ' << s;
+ cmdline << L' ' << s;
}
- string cmdline_str = cmdline.str();
+ wstring cmdline_str = cmdline.str();
if (cmdline_str.size() >= MAX_CMDLINE_LENGTH) {
- die("Command line too long: %s", cmdline_str.c_str());
+ die(L"Command line too long: %s", cmdline_str.c_str());
}
// Copy command line into a mutable buffer.
// CreateProcess is allowed to mutate its command line argument.
- strncpy(result->cmdline, cmdline_str.c_str(), MAX_CMDLINE_LENGTH - 1);
+ wcsncpy(result->cmdline, cmdline_str.c_str(), MAX_CMDLINE_LENGTH - 1);
result->cmdline[MAX_CMDLINE_LENGTH - 1] = 0;
}
bool BinaryLauncherBase::PrintLauncherCommandLine(
- const string& executable, const vector<string>& arguments) const {
+ const wstring& executable, const vector<wstring>& arguments) const {
bool has_print_cmd_flag = false;
for (const auto& arg : arguments) {
- has_print_cmd_flag |= (arg == "--print_launcher_command");
+ has_print_cmd_flag |= (arg == L"--print_launcher_command");
}
if (has_print_cmd_flag) {
- printf("%s\n", executable.c_str());
+ wprintf(L"%s\n", executable.c_str());
for (const auto& arg : arguments) {
- printf("%s\n", arg.c_str());
+ wprintf(L"%s\n", arg.c_str());
}
}
return has_print_cmd_flag;
}
-ExitCode BinaryLauncherBase::LaunchProcess(const string& executable,
- const vector<string>& arguments,
+ExitCode BinaryLauncherBase::LaunchProcess(const wstring& executable,
+ const vector<wstring>& arguments,
bool suppressOutput) const {
if (PrintLauncherCommandLine(executable, arguments)) {
return 0;
}
- if (manifest_file != "") {
- SetEnv("RUNFILES_MANIFEST_ONLY", "1");
- SetEnv("RUNFILES_MANIFEST_FILE", manifest_file);
+ if (!manifest_file.empty()) {
+ SetEnv(L"RUNFILES_MANIFEST_ONLY", L"1");
+ SetEnv(L"RUNFILES_MANIFEST_FILE", manifest_file);
} else {
- SetEnv("RUNFILES_DIR", runfiles_dir);
+ SetEnv(L"RUNFILES_DIR", runfiles_dir);
}
CmdLine cmdline;
CreateCommandLine(&cmdline, executable, arguments);
PROCESS_INFORMATION processInfo = {0};
- STARTUPINFOA startupInfo = {0};
+ STARTUPINFOW startupInfo = {0};
startupInfo.cb = sizeof(startupInfo);
- BOOL ok = CreateProcessA(
+ BOOL ok = CreateProcessW(
/* lpApplicationName */ NULL,
/* lpCommandLine */ cmdline.cmdline,
/* lpProcessAttributes */ NULL,
/* lpThreadAttributes */ NULL,
/* bInheritHandles */ FALSE,
/* dwCreationFlags */
- suppressOutput ? CREATE_NO_WINDOW // no console window => no output
- : 0,
+ suppressOutput ? CREATE_NO_WINDOW // no console window => no output
+ : 0,
/* lpEnvironment */ NULL,
/* lpCurrentDirectory */ NULL,
/* lpStartupInfo */ &startupInfo,
/* lpProcessInformation */ &processInfo);
if (!ok) {
- PrintError("Cannot launch process: %s\nReason: %s",
- cmdline.cmdline,
+ PrintError(L"Cannot launch process: %s\nReason: %hs", cmdline.cmdline,
GetLastErrorString().c_str());
return GetLastError();
}
diff --git a/src/tools/launcher/launcher.h b/src/tools/launcher/launcher.h
index 4dca6e000d..107ac17795 100644
--- a/src/tools/launcher/launcher.h
+++ b/src/tools/launcher/launcher.h
@@ -32,21 +32,21 @@ static constexpr const char* WORKSPACE_NAME = "workspace_name";
static const int MAX_CMDLINE_LENGTH = 32768;
struct CmdLine {
- char cmdline[MAX_CMDLINE_LENGTH];
+ wchar_t cmdline[MAX_CMDLINE_LENGTH];
};
class BinaryLauncherBase {
- typedef std::unordered_map<std::string, std::string> ManifestFileMap;
+ typedef std::unordered_map<std::wstring, std::wstring> ManifestFileMap;
public:
BinaryLauncherBase(const LaunchDataParser::LaunchInfo& launch_info, int argc,
- char* argv[]);
+ wchar_t* argv[]);
// Get launch information based on a launch info key.
- std::string GetLaunchInfoByKey(const std::string& key);
+ std::wstring GetLaunchInfoByKey(const std::string& key);
// Get the original command line arguments passed to this binary.
- const std::vector<std::string>& GetCommandlineArguments() const;
+ const std::vector<std::wstring>& GetCommandlineArguments() const;
// Map a runfile path to its absolute path.
//
@@ -54,8 +54,10 @@ class BinaryLauncherBase {
// path before doing rlocation.
// If need_workspace_name is false, then this method uses path directly.
// The default value of need_workspace_name is true.
- std::string Rlocation(const std::string& path,
- bool need_workspace_name = true) const;
+ std::wstring Rlocation(const std::wstring& path,
+ bool need_workspace_name = true) const;
+ std::wstring Rlocation(const std::string& path,
+ bool need_workspace_name = true) const;
// Lauch a process with given executable and command line arguments.
// If --print_launcher_command exists in arguments, then we print the full
@@ -65,8 +67,8 @@ class BinaryLauncherBase {
// arguments: the command line arguments to be passed to the exectuable,
// it doesn't include the exectuable itself.
// The arguments are expected to be quoted if having spaces.
- ExitCode LaunchProcess(const std::string& executable,
- const std::vector<std::string>& arguments,
+ ExitCode LaunchProcess(const std::wstring& executable,
+ const std::vector<std::wstring>& arguments,
bool suppressOutput = false) const;
// A launch function to be implemented for a specific language.
@@ -76,54 +78,54 @@ class BinaryLauncherBase {
//
// The method appends ".exe.runfiles" to the first command line argument,
// converts forward slashes to back slashes, then returns that.
- std::string GetRunfilesPath() const;
+ std::wstring GetRunfilesPath() const;
private:
// A map to store all the launch information.
const LaunchDataParser::LaunchInfo& launch_info;
// Absolute path to the runfiles manifest file, if one exists.
- const std::string manifest_file;
+ const std::wstring manifest_file;
// Path to the runfiles directory, if one exists.
- const std::string runfiles_dir;
+ const std::wstring runfiles_dir;
// The commandline arguments recieved.
// The first argument is the path of this launcher itself.
- std::vector<std::string> commandline_arguments;
+ std::vector<std::wstring> commandline_arguments;
// The workspace name of the repository this target belongs to.
- const std::string workspace_name;
+ const std::wstring workspace_name;
// A map to store all entries of the manifest file.
- std::unordered_map<std::string, std::string> manifest_file_map;
+ ManifestFileMap manifest_file_map;
// If --print_launcher_command is presented in arguments,
// then print the command line.
//
// Return true if command line is printed.
bool PrintLauncherCommandLine(
- const std::string& executable,
- const std::vector<std::string>& arguments) const;
+ const std::wstring& executable,
+ const std::vector<std::wstring>& arguments) const;
// Create a command line to be passed to Windows CreateProcessA API.
//
// exectuable: the binary to be executed.
// arguments: the command line arguments to be passed to the exectuable,
// it doesn't include the exectuable itself.
- void CreateCommandLine(CmdLine* result, const std::string& executable,
- const std::vector<std::string>& arguments) const;
+ void CreateCommandLine(CmdLine* result, const std::wstring& executable,
+ const std::vector<std::wstring>& arguments) const;
// Find manifest file of the binary.
//
// Expect the manifest file to be at
// 1. <path>/<to>/<binary>/<target_name>.runfiles/MANIFEST
// or 2. <path>/<to>/<binary>/<target_name>.runfiles_manifest
- static std::string FindManifestFile(const char* argv0);
+ static std::wstring FindManifestFile(const wchar_t* argv0);
// Parse manifest file into a map
static void ParseManifestFile(ManifestFileMap* manifest_file_map,
- const std::string& manifest_path);
+ const std::wstring& manifest_path);
};
} // namespace launcher
diff --git a/src/tools/launcher/launcher_main.cc b/src/tools/launcher/launcher_main.cc
index 6f9133b6f2..5e0e142e2e 100644
--- a/src/tools/launcher/launcher_main.cc
+++ b/src/tools/launcher/launcher_main.cc
@@ -33,30 +33,30 @@ using bazel::launcher::die;
using std::make_unique;
using std::unique_ptr;
-int main(int argc, char* argv[]) {
+int wmain(int argc, wchar_t* argv[]) {
LaunchDataParser::LaunchInfo launch_info;
if (!LaunchDataParser::GetLaunchInfo(GetBinaryPathWithExtension(argv[0]),
&launch_info)) {
- die("Failed to parse launch info.");
+ die(L"Failed to parse launch info.");
}
auto result = launch_info.find(BINARY_TYPE);
if (result == launch_info.end()) {
- die("Cannot find key \"%s\" from launch data.", BINARY_TYPE);
+ die(L"Cannot find key \"%hs\" from launch data.", BINARY_TYPE);
}
unique_ptr<BinaryLauncherBase> binary_launcher;
- if (result->second == "Python") {
+ if (result->second == L"Python") {
binary_launcher =
make_unique<PythonBinaryLauncher>(launch_info, argc, argv);
- } else if (result->second == "Bash") {
+ } else if (result->second == L"Bash") {
binary_launcher = make_unique<BashBinaryLauncher>(launch_info, argc, argv);
- } else if (result->second == "Java") {
+ } else if (result->second == L"Java") {
binary_launcher = make_unique<JavaBinaryLauncher>(launch_info, argc, argv);
} else {
- die("Unknown binary type, cannot launch anything.");
+ die(L"Unknown binary type, cannot launch anything.");
}
return binary_launcher->Launch();
diff --git a/src/tools/launcher/python_launcher.cc b/src/tools/launcher/python_launcher.cc
index 08533ffe74..a0f8775923 100644
--- a/src/tools/launcher/python_launcher.cc
+++ b/src/tools/launcher/python_launcher.cc
@@ -21,21 +21,21 @@
namespace bazel {
namespace launcher {
-using std::string;
using std::vector;
+using std::wstring;
static constexpr const char* PYTHON_BIN_PATH = "python_bin_path";
ExitCode PythonBinaryLauncher::Launch() {
- string python_binary = this->GetLaunchInfoByKey(PYTHON_BIN_PATH);
+ wstring python_binary = this->GetLaunchInfoByKey(PYTHON_BIN_PATH);
// If specified python binary path doesn't exist, then fall back to
// python.exe and hope it's in PATH.
if (!DoesFilePathExist(python_binary.c_str())) {
- python_binary = "python.exe";
+ python_binary = L"python.exe";
}
- vector<string> args = this->GetCommandlineArguments();
- string python_zip_file = GetBinaryPathWithoutExtension(args[0]) + ".zip";
+ vector<wstring> args = this->GetCommandlineArguments();
+ wstring python_zip_file = GetBinaryPathWithoutExtension(args[0]) + L".zip";
// Replace the first argument with python zip file path
args[0] = python_zip_file;
diff --git a/src/tools/launcher/python_launcher.h b/src/tools/launcher/python_launcher.h
index 1a21ca308e..ab624da240 100644
--- a/src/tools/launcher/python_launcher.h
+++ b/src/tools/launcher/python_launcher.h
@@ -23,8 +23,8 @@ namespace launcher {
class PythonBinaryLauncher : public BinaryLauncherBase {
public:
PythonBinaryLauncher(const LaunchDataParser::LaunchInfo& launch_info,
- int argc, char* argv[])
- : BinaryLauncherBase(launch_info, argc, argv){}
+ int argc, wchar_t* argv[])
+ : BinaryLauncherBase(launch_info, argc, argv) {}
ExitCode Launch();
};
diff --git a/src/tools/launcher/util/data_parser.cc b/src/tools/launcher/util/data_parser.cc
index 98c8b1daf6..cb77abefed 100644
--- a/src/tools/launcher/util/data_parser.cc
+++ b/src/tools/launcher/util/data_parser.cc
@@ -17,6 +17,7 @@
#include <string>
#include <unordered_map>
+#include "src/main/cpp/util/strings.h"
#include "src/tools/launcher/util/data_parser.h"
#include "src/tools/launcher/util/launcher_util.h"
@@ -28,6 +29,7 @@ using std::ios;
using std::make_unique;
using std::string;
using std::unique_ptr;
+using std::wstring;
int64_t LaunchDataParser::ReadDataSize(ifstream* binary) {
int64_t data_size;
@@ -63,34 +65,34 @@ bool LaunchDataParser::ParseLaunchData(LaunchInfo* launch_info,
end++;
}
if (equal == -1) {
- PrintError("Cannot find equal symbol in line: %s",
+ PrintError(L"Cannot find equal symbol in line: %hs",
string(launch_data + start, end - start).c_str());
return false;
} else if (start == equal) {
- PrintError("Key is empty string in line: %s",
+ PrintError(L"Key is empty string in line: %hs",
string(launch_data + start, end - start).c_str());
return false;
} else {
string key(launch_data + start, equal - start);
string value(launch_data + equal + 1, end - equal - 1);
if (launch_info->find(key) != launch_info->end()) {
- PrintError("Duplicated launch info key: %s", key.c_str());
+ PrintError(L"Duplicated launch info key: %hs", key.c_str());
return false;
}
- launch_info->insert(make_pair(key, value));
+ launch_info->insert(make_pair(key, blaze_util::CstringToWstring(value)));
}
start = end + 1;
}
return true;
}
-bool LaunchDataParser::GetLaunchInfo(const string& binary_path,
+bool LaunchDataParser::GetLaunchInfo(const wstring& binary_path,
LaunchInfo* launch_info) {
unique_ptr<ifstream> binary =
make_unique<ifstream>(binary_path, ios::binary | ios::in);
int64_t data_size = ReadDataSize(binary.get());
if (data_size == 0) {
- PrintError("No data appended, cannot launch anything!");
+ PrintError(L"No data appended, cannot launch anything!");
return false;
}
unique_ptr<char[]> launch_data(new char[data_size]);
diff --git a/src/tools/launcher/util/data_parser.h b/src/tools/launcher/util/data_parser.h
index ecaf12a9b9..586da42fbe 100644
--- a/src/tools/launcher/util/data_parser.h
+++ b/src/tools/launcher/util/data_parser.h
@@ -25,10 +25,10 @@ namespace launcher {
class LaunchDataParser {
public:
- typedef std::unordered_map<std::string, std::string> LaunchInfo;
+ typedef std::unordered_map<std::string, std::wstring> LaunchInfo;
LaunchDataParser() = delete;
~LaunchDataParser() = delete;
- static bool GetLaunchInfo(const std::string& binary_path,
+ static bool GetLaunchInfo(const std::wstring& binary_path,
LaunchInfo* launch_info);
private:
diff --git a/src/tools/launcher/util/data_parser_test.cc b/src/tools/launcher/util/data_parser_test.cc
index 1adaf3aebd..be270aa3c3 100644
--- a/src/tools/launcher/util/data_parser_test.cc
+++ b/src/tools/launcher/util/data_parser_test.cc
@@ -18,6 +18,7 @@
#include <memory>
#include <vector>
+#include "src/main/cpp/util/strings.h"
#include "src/tools/launcher/util/data_parser.h"
#include "gtest/gtest.h"
#include "src/tools/launcher/util/launcher_util.h"
@@ -89,7 +90,8 @@ class LaunchDataParserTest : public ::testing::Test {
static bool ParseBinaryFile(
const string& binary_file,
LaunchDataParser::LaunchInfo* parsed_launch_info) {
- if (LaunchDataParser::GetLaunchInfo(binary_file, parsed_launch_info)) {
+ if (LaunchDataParser::GetLaunchInfo(
+ blaze_util::CstringToWstring(binary_file), parsed_launch_info)) {
return true;
}
exit(-1);
@@ -100,7 +102,7 @@ class LaunchDataParserTest : public ::testing::Test {
if (item == parsed_launch_info->end()) {
return "Cannot find key: " + key;
}
- return item->second;
+ return blaze_util::WstringToString(item->second);
}
string test_tmpdir;
diff --git a/src/tools/launcher/util/launcher_util.cc b/src/tools/launcher/util/launcher_util.cc
index 3509ce3287..f14009caea 100644
--- a/src/tools/launcher/util/launcher_util.cc
+++ b/src/tools/launcher/util/launcher_util.cc
@@ -14,6 +14,8 @@
// For rand_s function, https://msdn.microsoft.com/en-us/library/sxtz2fa8.aspx
#define _CRT_RAND_S
+#include <fcntl.h>
+#include <io.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -29,10 +31,10 @@
namespace bazel {
namespace launcher {
-using std::ostringstream;
using std::string;
-using std::wstring;
using std::stringstream;
+using std::wostringstream;
+using std::wstring;
string GetLastErrorString() {
DWORD last_error = GetLastError();
@@ -53,88 +55,99 @@ string GetLastErrorString() {
return result.str();
}
-void die(const char* format, ...) {
+void die(const wchar_t* format, ...) {
+ // Set translation mode to _O_U8TEXT so that we can display
+ // error message containing unicode correctly.
+ _setmode(_fileno(stderr), _O_U8TEXT);
va_list ap;
va_start(ap, format);
- fputs("LAUNCHER ERROR: ", stderr);
- vfprintf(stderr, format, ap);
+ fputws(L"LAUNCHER ERROR: ", stderr);
+ vfwprintf(stderr, format, ap);
va_end(ap);
- fputc('\n', stderr);
+ fputwc(L'\n', stderr);
exit(1);
}
-void PrintError(const char* format, ...) {
+void PrintError(const wchar_t* format, ...) {
+ // Set translation mode to _O_U8TEXT so that we can display
+ // error message containing unicode correctly.
+ // _setmode returns -1 if it fails to set the mode.
+ int previous_mode = _setmode(_fileno(stderr), _O_U8TEXT);
va_list ap;
va_start(ap, format);
- fputs("LAUNCHER ERROR: ", stderr);
- vfprintf(stderr, format, ap);
+ fputws(L"LAUNCHER ERROR: ", stderr);
+ vfwprintf(stderr, format, ap);
va_end(ap);
- fputc('\n', stderr);
+ fputwc(L'\n', stderr);
+ // Set translation mode back to the original one if it's changed.
+ if (previous_mode != -1) {
+ _setmode(_fileno(stderr), previous_mode);
+ }
}
-wstring AsAbsoluteWindowsPath(const char* path) {
+wstring AsAbsoluteWindowsPath(const wchar_t* path) {
wstring wpath;
string error;
if (!blaze_util::AsAbsoluteWindowsPath(path, &wpath, &error)) {
- die("Couldn't convert %s to absolute Windows path: %s", path,
+ die(L"Couldn't convert %s to absolute Windows path: %hs", path,
error.c_str());
}
return wpath;
}
-bool DoesFilePathExist(const char* path) {
+bool DoesFilePathExist(const wchar_t* path) {
DWORD dwAttrib = GetFileAttributesW(AsAbsoluteWindowsPath(path).c_str());
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
-bool DoesDirectoryPathExist(const char* path) {
+bool DoesDirectoryPathExist(const wchar_t* path) {
DWORD dwAttrib = GetFileAttributesW(AsAbsoluteWindowsPath(path).c_str());
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
-bool DeleteFileByPath(const char* path) {
+bool DeleteFileByPath(const wchar_t* path) {
return DeleteFileW(AsAbsoluteWindowsPath(path).c_str());
}
-bool DeleteDirectoryByPath(const char* path) {
+bool DeleteDirectoryByPath(const wchar_t* path) {
return RemoveDirectoryW(AsAbsoluteWindowsPath(path).c_str());
}
-string GetBinaryPathWithoutExtension(const string& binary) {
- if (binary.find(".exe", binary.size() - 4) != string::npos) {
+wstring GetBinaryPathWithoutExtension(const wstring& binary) {
+ if (binary.find(L".exe", binary.size() - 4) != wstring::npos) {
return binary.substr(0, binary.length() - 4);
}
return binary;
}
-string GetBinaryPathWithExtension(const string& binary) {
- return GetBinaryPathWithoutExtension(binary) + ".exe";
+wstring GetBinaryPathWithExtension(const wstring& binary) {
+ return GetBinaryPathWithoutExtension(binary) + L".exe";
}
-string GetEscapedArgument(const string& argument, bool escape_backslash) {
- string escaped_arg;
+wstring GetEscapedArgument(const wstring& argument, bool escape_backslash) {
+ wstring escaped_arg;
// escaped_arg will be at least this long
escaped_arg.reserve(argument.size());
- bool has_space = argument.find_first_of(' ') != string::npos;
+ bool has_space = argument.find_first_of(L' ') != wstring::npos;
if (has_space) {
- escaped_arg += '\"';
+ escaped_arg += L'\"';
}
- for (const char ch : argument) {
+ for (const wchar_t ch : argument) {
switch (ch) {
- case '"':
+ case L'"':
// Escape double quotes
- escaped_arg += "\\\"";
+ escaped_arg += L"\\\"";
break;
- case '\\':
+ case L'\\':
// Escape back slashes if escape_backslash is true
- escaped_arg += (escape_backslash ? "\\\\" : "\\");
+ escaped_arg += (escape_backslash ? L"\\\\" : L"\\");
break;
default:
@@ -143,7 +156,7 @@ string GetEscapedArgument(const string& argument, bool escape_backslash) {
}
if (has_space) {
- escaped_arg += '\"';
+ escaped_arg += L'\"';
}
return escaped_arg;
}
@@ -152,54 +165,54 @@ string GetEscapedArgument(const string& argument, bool escape_backslash) {
// https://msdn.microsoft.com/en-us/library/ms683188.aspx
static const int BUFFER_SIZE = 32767;
-bool GetEnv(const string& env_name, string* value) {
- char buffer[BUFFER_SIZE];
- if (!GetEnvironmentVariableA(env_name.c_str(), buffer, BUFFER_SIZE)) {
+bool GetEnv(const wstring& env_name, wstring* value) {
+ wchar_t buffer[BUFFER_SIZE];
+ if (!GetEnvironmentVariableW(env_name.c_str(), buffer, BUFFER_SIZE)) {
return false;
}
*value = buffer;
return true;
}
-bool SetEnv(const string& env_name, const string& value) {
- return SetEnvironmentVariableA(env_name.c_str(), value.c_str());
+bool SetEnv(const wstring& env_name, const wstring& value) {
+ return SetEnvironmentVariableW(env_name.c_str(), value.c_str());
}
-string GetRandomStr(size_t len) {
- static const char alphabet[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
- string rand_str;
+wstring GetRandomStr(size_t len) {
+ static const wchar_t alphabet[] =
+ L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ wstring rand_str;
rand_str.reserve(len);
unsigned int x;
for (size_t i = 0; i < len; i++) {
rand_s(&x);
- rand_str += alphabet[x % strlen(alphabet)];
+ rand_str += alphabet[x % wcslen(alphabet)];
}
return rand_str;
}
-bool NormalizePath(const string& path, string* result) {
+bool NormalizePath(const wstring& path, wstring* result) {
string error;
if (!blaze_util::AsWindowsPath(path, result, &error)) {
- PrintError("Failed to normalize %s: %s", path.c_str(), error.c_str());
+ PrintError(L"Failed to normalize %s: %hs", path.c_str(), error.c_str());
return false;
}
std::transform(result->begin(), result->end(), result->begin(), ::tolower);
return true;
}
-string GetBaseNameFromPath(const string& path) {
- return path.substr(path.find_last_of("\\/") + 1);
+wstring GetBaseNameFromPath(const wstring& path) {
+ return path.substr(path.find_last_of(L"\\/") + 1);
}
-string GetParentDirFromPath(const string& path) {
- return path.substr(0, path.find_last_of("\\/"));
+wstring GetParentDirFromPath(const wstring& path) {
+ return path.substr(0, path.find_last_of(L"\\/"));
}
-bool RelativeTo(const string& path, const string& base, string* result) {
+bool RelativeTo(const wstring& path, const wstring& base, wstring* result) {
if (blaze_util::IsAbsolute(path) != blaze_util::IsAbsolute(base)) {
PrintError(
- "Cannot calculate relative path from an absolute and a non-absolute"
+ L"Cannot calculate relative path from an absolute and a non-absolute"
" path.\npath = %s\nbase = %s",
path.c_str(), base.c_str());
return false;
@@ -208,7 +221,7 @@ bool RelativeTo(const string& path, const string& base, string* result) {
if (blaze_util::IsAbsolute(path) && blaze_util::IsAbsolute(base) &&
path[0] != base[0]) {
PrintError(
- "Cannot calculate relative path from absolute path under different "
+ L"Cannot calculate relative path from absolute path under different "
"drives."
"\npath = %s\nbase = %s",
path.c_str(), base.c_str());
@@ -218,21 +231,21 @@ bool RelativeTo(const string& path, const string& base, string* result) {
// Record the back slash position after the last matched path fragment
int pos = 0;
int back_slash_pos = -1;
- while (path[pos] == base[pos] && base[pos] != '\0') {
- if (path[pos] == '\\') {
+ while (path[pos] == base[pos] && base[pos] != L'\0') {
+ if (path[pos] == L'\\') {
back_slash_pos = pos;
}
pos++;
}
- if (base[pos] == '\0' && path[pos] == '\0') {
+ if (base[pos] == L'\0' && path[pos] == L'\0') {
// base == path in this case
- result->assign("");
+ result->assign(L"");
return true;
}
- if ((base[pos] == '\0' && path[pos] == '\\') ||
- (base[pos] == '\\' && path[pos] == '\0')) {
+ if ((base[pos] == L'\0' && path[pos] == L'\\') ||
+ (base[pos] == L'\\' && path[pos] == L'\0')) {
// In this case, one of the paths is the parent of another one.
// We should move back_slash_pos to the end of the shorter path.
// eg. path = c:\foo\bar, base = c:\foo => back_slash_pos = 6
@@ -240,7 +253,7 @@ bool RelativeTo(const string& path, const string& base, string* result) {
back_slash_pos = pos;
}
- ostringstream buffer;
+ wostringstream buffer;
// Create the ..\\ prefix
// eg. path = C:\foo\bar1, base = C:\foo\bar2, we need ..\ prefix
@@ -249,11 +262,11 @@ bool RelativeTo(const string& path, const string& base, string* result) {
// back_slash_pos + 1 == base.length() is not possible because the last
// character of a normalized path won't be back slash.
if (back_slash_pos + 1 < base.length()) {
- buffer << "..\\";
+ buffer << L"..\\";
}
for (int i = back_slash_pos + 1; i < base.length(); i++) {
- if (base[i] == '\\') {
- buffer << "..\\";
+ if (base[i] == L'\\') {
+ buffer << L"..\\";
}
}
diff --git a/src/tools/launcher/util/launcher_util.h b/src/tools/launcher/util/launcher_util.h
index 760eb7266e..deb4065ab7 100644
--- a/src/tools/launcher/util/launcher_util.h
+++ b/src/tools/launcher/util/launcher_util.h
@@ -25,77 +25,78 @@ namespace launcher {
std::string GetLastErrorString();
// Prints the specified error message and exits nonzero.
-__declspec(noreturn) void die(const char* format, ...) PRINTF_ATTRIBUTE(1, 2);
+__declspec(noreturn) void die(const wchar_t* format, ...)
+ PRINTF_ATTRIBUTE(1, 2);
// Prints the specified error message.
-void PrintError(const char* format, ...) PRINTF_ATTRIBUTE(1, 2);
+void PrintError(const wchar_t* format, ...) PRINTF_ATTRIBUTE(1, 2);
// Strip the .exe extension from binary path.
//
// On Windows, if the binary path is foo/bar/bin.exe then return foo/bar/bin
-std::string GetBinaryPathWithoutExtension(const std::string& binary);
+std::wstring GetBinaryPathWithoutExtension(const std::wstring& binary);
// Add exectuable extension to binary path
//
// On Windows, if the binary path is foo/bar/bin then return foo/bar/bin.exe
-std::string GetBinaryPathWithExtension(const std::string& binary);
+std::wstring GetBinaryPathWithExtension(const std::wstring& binary);
// Escape a command line argument.
//
// If the argument has space, then we quote it.
// Escape " to \"
// Escape \ to \\ if escape_backslash is true
-std::string GetEscapedArgument(const std::string& argument,
- bool escape_backslash);
+std::wstring GetEscapedArgument(const std::wstring& argument,
+ bool escape_backslash);
// Convert a path to an absolute Windows path with \\?\ prefix.
// This method will print an error and exit if it cannot convert the path.
-std::wstring AsAbsoluteWindowsPath(const char* path);
+std::wstring AsAbsoluteWindowsPath(const wchar_t* path);
// Check if a file exists at a given path.
-bool DoesFilePathExist(const char* path);
+bool DoesFilePathExist(const wchar_t* path);
// Check if a directory exists at a given path.
-bool DoesDirectoryPathExist(const char* path);
+bool DoesDirectoryPathExist(const wchar_t* path);
// Delete a file at a given path.
-bool DeleteFileByPath(const char* path);
+bool DeleteFileByPath(const wchar_t* path);
// Delete a directory at a given path,.
// If it's a real directory, it must be empty
// If it's a junction, the target directory it points to doesn't have to be
// empty, the junction will be deleted regardless of the state of the target.
-bool DeleteDirectoryByPath(const char* path);
+bool DeleteDirectoryByPath(const wchar_t* path);
// Get the value of a specific environment variable
//
// Return true if succeeded and the result is stored in buffer.
// Return false if the environment variable doesn't exist or the value is empty.
-bool GetEnv(const std::string& env_name, std::string* buffer);
+bool GetEnv(const std::wstring& env_name, std::wstring* buffer);
// Set the value of a specific environment variable
//
// Return true if succeeded, otherwise false.
-bool SetEnv(const std::string& env_name, const std::string& value);
+bool SetEnv(const std::wstring& env_name, const std::wstring& value);
// Return a random string with a given length.
// The string consists of a-zA-Z0-9
-std::string GetRandomStr(size_t len);
+std::wstring GetRandomStr(size_t len);
// Normalize a path to a Windows path in lower case
-bool NormalizePath(const std::string& path, std::string* result);
+bool NormalizePath(const std::wstring& path, std::wstring* result);
// Get the base name from a normalized absoulute path
-std::string GetBaseNameFromPath(const std::string& path);
+std::wstring GetBaseNameFromPath(const std::wstring& path);
// Get parent directory from a normalized absoulute path
-std::string GetParentDirFromPath(const std::string& path);
+std::wstring GetParentDirFromPath(const std::wstring& path);
// Calculate a relative path from `path` to `base`.
// This function expects normalized Windows path in lower case.
// `path` and `base` should be both absolute or both relative.
-bool RelativeTo(const std::string& path, const std::string& base,
- std::string* result);
+bool RelativeTo(const std::wstring& path, const std::wstring& base,
+ std::wstring* result);
} // namespace launcher
} // namespace bazel
diff --git a/src/tools/launcher/util/launcher_util_test.cc b/src/tools/launcher/util/launcher_util_test.cc
index f8ddf803f3..82b3f9898b 100644
--- a/src/tools/launcher/util/launcher_util_test.cc
+++ b/src/tools/launcher/util/launcher_util_test.cc
@@ -18,6 +18,7 @@
#include <iostream>
#include <string>
+#include "src/main/cpp/util/strings.h"
#include "src/tools/launcher/util/launcher_util.h"
#include "gtest/gtest.h"
@@ -28,6 +29,7 @@ using std::getenv;
using std::ios;
using std::ofstream;
using std::string;
+using std::wstring;
class LaunchUtilTest : public ::testing::Test {
protected:
@@ -38,141 +40,142 @@ class LaunchUtilTest : public ::testing::Test {
void SetUp() override {
char* tmpdir = getenv("TEST_TMPDIR");
if (tmpdir != NULL) {
- test_tmpdir = string(tmpdir);
+ test_tmpdir = blaze_util::CstringToWstring(string(tmpdir));
} else {
tmpdir = getenv("TEMP");
ASSERT_FALSE(tmpdir == NULL);
- test_tmpdir = string(tmpdir);
+ test_tmpdir = blaze_util::CstringToWstring(string(tmpdir));
}
}
void TearDown() override {}
- string GetTmpDir() { return this->test_tmpdir; }
+ wstring GetTmpDir() { return this->test_tmpdir; }
// Create an empty file at path
- static void CreateEmptyFile(const string& path) {
+ static void CreateEmptyFile(const wstring& path) {
ofstream file_stream(path.c_str(), ios::out | ios::binary);
file_stream.put('\0');
}
private:
- string test_tmpdir;
+ wstring test_tmpdir;
};
TEST_F(LaunchUtilTest, GetBinaryPathWithoutExtensionTest) {
- ASSERT_EQ("foo", GetBinaryPathWithoutExtension("foo.exe"));
- ASSERT_EQ("foo.sh", GetBinaryPathWithoutExtension("foo.sh.exe"));
- ASSERT_EQ("foo.sh", GetBinaryPathWithoutExtension("foo.sh"));
+ ASSERT_EQ(L"foo", GetBinaryPathWithoutExtension(L"foo.exe"));
+ ASSERT_EQ(L"foo.sh", GetBinaryPathWithoutExtension(L"foo.sh.exe"));
+ ASSERT_EQ(L"foo.sh", GetBinaryPathWithoutExtension(L"foo.sh"));
}
TEST_F(LaunchUtilTest, GetBinaryPathWithExtensionTest) {
- ASSERT_EQ("foo.exe", GetBinaryPathWithExtension("foo"));
- ASSERT_EQ("foo.sh.exe", GetBinaryPathWithExtension("foo.sh.exe"));
- ASSERT_EQ("foo.sh.exe", GetBinaryPathWithExtension("foo.sh"));
+ ASSERT_EQ(L"foo.exe", GetBinaryPathWithExtension(L"foo"));
+ ASSERT_EQ(L"foo.sh.exe", GetBinaryPathWithExtension(L"foo.sh.exe"));
+ ASSERT_EQ(L"foo.sh.exe", GetBinaryPathWithExtension(L"foo.sh"));
}
TEST_F(LaunchUtilTest, GetEscapedArgumentTest) {
- ASSERT_EQ("foo", GetEscapedArgument("foo", true));
- ASSERT_EQ("\"foo bar\"", GetEscapedArgument("foo bar", true));
- ASSERT_EQ("\"\\\"foo bar\\\"\"", GetEscapedArgument("\"foo bar\"", true));
- ASSERT_EQ("foo\\\\bar", GetEscapedArgument("foo\\bar", true));
- ASSERT_EQ("foo\\\"bar", GetEscapedArgument("foo\"bar", true));
- ASSERT_EQ("C:\\\\foo\\\\bar\\\\", GetEscapedArgument("C:\\foo\\bar\\", true));
- ASSERT_EQ("\"C:\\\\foo foo\\\\bar\\\\\"",
- GetEscapedArgument("C:\\foo foo\\bar\\", true));
-
- ASSERT_EQ("foo\\bar", GetEscapedArgument("foo\\bar", false));
- ASSERT_EQ("C:\\foo\\bar\\", GetEscapedArgument("C:\\foo\\bar\\", false));
- ASSERT_EQ("\"C:\\foo foo\\bar\\\"",
- GetEscapedArgument("C:\\foo foo\\bar\\", false));
+ ASSERT_EQ(L"foo", GetEscapedArgument(L"foo", true));
+ ASSERT_EQ(L"\"foo bar\"", GetEscapedArgument(L"foo bar", true));
+ ASSERT_EQ(L"\"\\\"foo bar\\\"\"", GetEscapedArgument(L"\"foo bar\"", true));
+ ASSERT_EQ(L"foo\\\\bar", GetEscapedArgument(L"foo\\bar", true));
+ ASSERT_EQ(L"foo\\\"bar", GetEscapedArgument(L"foo\"bar", true));
+ ASSERT_EQ(L"C:\\\\foo\\\\bar\\\\",
+ GetEscapedArgument(L"C:\\foo\\bar\\", true));
+ ASSERT_EQ(L"\"C:\\\\foo foo\\\\bar\\\\\"",
+ GetEscapedArgument(L"C:\\foo foo\\bar\\", true));
+
+ ASSERT_EQ(L"foo\\bar", GetEscapedArgument(L"foo\\bar", false));
+ ASSERT_EQ(L"C:\\foo\\bar\\", GetEscapedArgument(L"C:\\foo\\bar\\", false));
+ ASSERT_EQ(L"\"C:\\foo foo\\bar\\\"",
+ GetEscapedArgument(L"C:\\foo foo\\bar\\", false));
}
TEST_F(LaunchUtilTest, DoesFilePathExistTest) {
- string file1 = GetTmpDir() + "/foo";
- string file2 = GetTmpDir() + "/bar";
+ wstring file1 = GetTmpDir() + L"/foo";
+ wstring file2 = GetTmpDir() + L"/bar";
CreateEmptyFile(file1);
ASSERT_TRUE(DoesFilePathExist(file1.c_str()));
ASSERT_FALSE(DoesFilePathExist(file2.c_str()));
}
TEST_F(LaunchUtilTest, DoesDirectoryPathExistTest) {
- string dir1 = GetTmpDir() + "/dir1";
- string dir2 = GetTmpDir() + "/dir2";
- CreateDirectory(dir1.c_str(), NULL);
+ wstring dir1 = GetTmpDir() + L"/dir1";
+ wstring dir2 = GetTmpDir() + L"/dir2";
+ CreateDirectoryW(dir1.c_str(), NULL);
ASSERT_TRUE(DoesDirectoryPathExist(dir1.c_str()));
ASSERT_FALSE(DoesDirectoryPathExist(dir2.c_str()));
}
TEST_F(LaunchUtilTest, SetAndGetEnvTest) {
- ASSERT_TRUE(SetEnv("foo", "bar"));
- string value;
- ASSERT_TRUE(GetEnv("foo", &value));
- ASSERT_EQ(value, "bar");
- SetEnv("FOO", "");
- ASSERT_FALSE(GetEnv("FOO", &value));
+ ASSERT_TRUE(SetEnv(L"foo", L"bar"));
+ wstring value;
+ ASSERT_TRUE(GetEnv(L"foo", &value));
+ ASSERT_EQ(value, L"bar");
+ SetEnv(L"FOO", L"");
+ ASSERT_FALSE(GetEnv(L"FOO", &value));
}
TEST_F(LaunchUtilTest, NormalizePathTest) {
- string value;
- ASSERT_TRUE(NormalizePath("C:\\foo\\bar\\", &value));
- ASSERT_EQ("c:\\foo\\bar", value);
- ASSERT_TRUE(NormalizePath("c:/foo/bar/", &value));
- ASSERT_EQ("c:\\foo\\bar", value);
- ASSERT_TRUE(NormalizePath("FoO\\\\bAr\\", &value));
- ASSERT_EQ("foo\\bar", value);
- ASSERT_TRUE(NormalizePath("X\\Y/Z\\", &value));
- ASSERT_EQ("x\\y\\z", value);
- ASSERT_TRUE(NormalizePath("c://foo//bar", &value));
- ASSERT_EQ("c:\\foo\\bar", value);
- ASSERT_FALSE(NormalizePath("c:foo\\bar", &value));
+ wstring value;
+ ASSERT_TRUE(NormalizePath(L"C:\\foo\\bar\\", &value));
+ ASSERT_EQ(L"c:\\foo\\bar", value);
+ ASSERT_TRUE(NormalizePath(L"c:/foo/bar/", &value));
+ ASSERT_EQ(L"c:\\foo\\bar", value);
+ ASSERT_TRUE(NormalizePath(L"FoO\\\\bAr\\", &value));
+ ASSERT_EQ(L"foo\\bar", value);
+ ASSERT_TRUE(NormalizePath(L"X\\Y/Z\\", &value));
+ ASSERT_EQ(L"x\\y\\z", value);
+ ASSERT_TRUE(NormalizePath(L"c://foo//bar", &value));
+ ASSERT_EQ(L"c:\\foo\\bar", value);
+ ASSERT_FALSE(NormalizePath(L"c:foo\\bar", &value));
}
TEST_F(LaunchUtilTest, RelativeToTest) {
- string value;
- ASSERT_TRUE(RelativeTo("c:\\foo\\bar1", "c:\\foo\\bar2", &value));
- ASSERT_EQ("..\\bar1", value);
- ASSERT_TRUE(RelativeTo("c:\\foo\\bar", "c:\\", &value));
- ASSERT_EQ("foo\\bar", value);
- ASSERT_TRUE(RelativeTo("c:\\foo\\bar", "c:\\foo\\bar", &value));
- ASSERT_EQ("", value);
- ASSERT_TRUE(RelativeTo("c:\\foo\\bar", "c:\\foo", &value));
- ASSERT_EQ("bar", value);
- ASSERT_TRUE(RelativeTo("c:\\foo\\bar", "c:\\foo\\ba", &value));
- ASSERT_EQ("..\\bar", value);
- ASSERT_TRUE(RelativeTo("c:\\", "c:\\foo", &value));
- ASSERT_EQ("..\\", value);
- ASSERT_TRUE(RelativeTo("c:\\", "c:\\a\\b\\c", &value));
- ASSERT_EQ("..\\..\\..\\", value);
- ASSERT_TRUE(RelativeTo("c:\\aa\\bb\\cc", "c:\\a\\b", &value));
- ASSERT_EQ("..\\..\\aa\\bb\\cc", value);
-
- ASSERT_TRUE(RelativeTo("foo\\bar", "foo\\bar", &value));
- ASSERT_EQ("", value);
- ASSERT_TRUE(RelativeTo("foo\\bar1", "foo\\bar2", &value));
- ASSERT_EQ("..\\bar1", value);
- ASSERT_TRUE(RelativeTo("foo\\bar1", "foo\\bar", &value));
- ASSERT_EQ("..\\bar1", value);
- ASSERT_TRUE(RelativeTo("foo\\bar1", "foo", &value));
- ASSERT_EQ("bar1", value);
- ASSERT_TRUE(RelativeTo("foo\\bar1", "fo", &value));
- ASSERT_EQ("..\\foo\\bar1", value);
- ASSERT_TRUE(RelativeTo("foo\\ba", "foo\\bar", &value));
- ASSERT_EQ("..\\ba", value);
- ASSERT_TRUE(RelativeTo("foo", "foo\\bar", &value));
- ASSERT_EQ("..\\", value);
- ASSERT_TRUE(RelativeTo("fo", "foo\\bar", &value));
- ASSERT_EQ("..\\..\\fo", value);
- ASSERT_TRUE(RelativeTo("", "foo\\bar", &value));
- ASSERT_EQ("..\\..\\", value);
- ASSERT_TRUE(RelativeTo("foo\\bar", "", &value));
- ASSERT_EQ("foo\\bar", value);
- ASSERT_TRUE(RelativeTo("a\\b\\c", "x\\y", &value));
- ASSERT_EQ("..\\..\\a\\b\\c", value);
-
- ASSERT_FALSE(RelativeTo("c:\\foo\\bar1", "foo\\bar2", &value));
- ASSERT_FALSE(RelativeTo("c:foo\\bar1", "c:\\foo\\bar2", &value));
- ASSERT_FALSE(RelativeTo("c:\\foo\\bar1", "d:\\foo\\bar2", &value));
+ wstring value;
+ ASSERT_TRUE(RelativeTo(L"c:\\foo\\bar1", L"c:\\foo\\bar2", &value));
+ ASSERT_EQ(L"..\\bar1", value);
+ ASSERT_TRUE(RelativeTo(L"c:\\foo\\bar", L"c:\\", &value));
+ ASSERT_EQ(L"foo\\bar", value);
+ ASSERT_TRUE(RelativeTo(L"c:\\foo\\bar", L"c:\\foo\\bar", &value));
+ ASSERT_EQ(L"", value);
+ ASSERT_TRUE(RelativeTo(L"c:\\foo\\bar", L"c:\\foo", &value));
+ ASSERT_EQ(L"bar", value);
+ ASSERT_TRUE(RelativeTo(L"c:\\foo\\bar", L"c:\\foo\\ba", &value));
+ ASSERT_EQ(L"..\\bar", value);
+ ASSERT_TRUE(RelativeTo(L"c:\\", L"c:\\foo", &value));
+ ASSERT_EQ(L"..\\", value);
+ ASSERT_TRUE(RelativeTo(L"c:\\", L"c:\\a\\b\\c", &value));
+ ASSERT_EQ(L"..\\..\\..\\", value);
+ ASSERT_TRUE(RelativeTo(L"c:\\aa\\bb\\cc", L"c:\\a\\b", &value));
+ ASSERT_EQ(L"..\\..\\aa\\bb\\cc", value);
+
+ ASSERT_TRUE(RelativeTo(L"foo\\bar", L"foo\\bar", &value));
+ ASSERT_EQ(L"", value);
+ ASSERT_TRUE(RelativeTo(L"foo\\bar1", L"foo\\bar2", &value));
+ ASSERT_EQ(L"..\\bar1", value);
+ ASSERT_TRUE(RelativeTo(L"foo\\bar1", L"foo\\bar", &value));
+ ASSERT_EQ(L"..\\bar1", value);
+ ASSERT_TRUE(RelativeTo(L"foo\\bar1", L"foo", &value));
+ ASSERT_EQ(L"bar1", value);
+ ASSERT_TRUE(RelativeTo(L"foo\\bar1", L"fo", &value));
+ ASSERT_EQ(L"..\\foo\\bar1", value);
+ ASSERT_TRUE(RelativeTo(L"foo\\ba", L"foo\\bar", &value));
+ ASSERT_EQ(L"..\\ba", value);
+ ASSERT_TRUE(RelativeTo(L"foo", L"foo\\bar", &value));
+ ASSERT_EQ(L"..\\", value);
+ ASSERT_TRUE(RelativeTo(L"fo", L"foo\\bar", &value));
+ ASSERT_EQ(L"..\\..\\fo", value);
+ ASSERT_TRUE(RelativeTo(L"", L"foo\\bar", &value));
+ ASSERT_EQ(L"..\\..\\", value);
+ ASSERT_TRUE(RelativeTo(L"foo\\bar", L"", &value));
+ ASSERT_EQ(L"foo\\bar", value);
+ ASSERT_TRUE(RelativeTo(L"a\\b\\c", L"x\\y", &value));
+ ASSERT_EQ(L"..\\..\\a\\b\\c", value);
+
+ ASSERT_FALSE(RelativeTo(L"c:\\foo\\bar1", L"foo\\bar2", &value));
+ ASSERT_FALSE(RelativeTo(L"c:foo\\bar1", L"c:\\foo\\bar2", &value));
+ ASSERT_FALSE(RelativeTo(L"c:\\foo\\bar1", L"d:\\foo\\bar2", &value));
}
} // namespace launcher