blob: d63627fb0cc1714888afcd17d10fe2d513d933e9 [file] [log] [blame]
// Copyright 2020 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "util/process_wrapper/utils.h"
#include <fstream>
#include <iostream>
#include <streambuf>
#if defined(PW_WIN_UNICODE)
#include <codecvt>
#include <locale>
#endif // defined(PW_WIN_UNICODE)
namespace process_wrapper {
System::StrType FromUtf8(const std::string& string) {
#if defined(PW_WIN_UNICODE)
return std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(string);
#else
return string;
#endif // defined(PW_WIN_UNICODE)
}
std::string ToUtf8(const System::StrType& string) {
#if defined(PW_WIN_UNICODE)
return std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(string);
#else
return string;
#endif // defined(PW_WIN_UNICODE)
}
void ReplaceToken(System::StrType& str, const System::StrType& token,
const System::StrType& replacement) {
std::size_t pos = str.find(token);
if (pos != std::string::npos) {
str.replace(pos, token.size(), replacement);
}
}
bool ReadFileToArray(const System::StrType& file_path,
System::StrVecType& vec) {
std::ifstream file(file_path);
if (file.fail()) {
std::cerr << "process wrapper error: failed to open file: "
<< ToUtf8(file_path) << '\n';
return false;
}
std::string read_line, escaped_line;
while (std::getline(file, read_line)) {
// handle CRLF files when as they might be
// written on windows and read from linux
if (!read_line.empty() && read_line.back() == '\r') {
read_line.pop_back();
}
// Skip empty lines if any
if (read_line.empty()) {
continue;
}
// a \ at the end of a line allows us to escape the new line break,
// \\ yields a single \, so \\\ translates to a single \ and a new line escape
int end_backslash_count = 0;
for (std::string::reverse_iterator rit = read_line.rbegin();
rit != read_line.rend() && *rit == '\\'; ++rit) {
end_backslash_count++;
}
// a 0 or pair number of backslashes do not lead to a new line escape
bool escape = false;
if (end_backslash_count & 1) {
escape = true;
}
// remove backslashes
while (end_backslash_count > 0) {
end_backslash_count -= 2;
read_line.pop_back();
}
if (escape) {
read_line.push_back('\n');
escaped_line += read_line;
} else {
vec.push_back(FromUtf8(escaped_line + read_line));
escaped_line.clear();
}
}
return true;
}
} // namespace process_wrapper