This source file includes following definitions.
- WriteFile
- WriteDir
- WriteFile
- WriteFile
- WriteSourceRelativeString
- WritePathStr
#include "tools/gn/path_output.h"
#include "build/build_config.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/output_file.h"
#include "tools/gn/string_utils.h"
PathOutput::PathOutput(const SourceDir& current_dir,
EscapingMode escaping,
bool convert_slashes)
: current_dir_(current_dir) {
CHECK(current_dir.is_source_absolute())
<< "Currently this only supports writing to output directories inside "
"the source root. There needs to be some tweaks to PathOutput to make "
"doing this work correctly.";
inverse_current_dir_ = InvertDir(current_dir_);
options_.mode = escaping;
options_.convert_slashes = convert_slashes;
options_.inhibit_quoting = false;
if (convert_slashes)
ConvertPathToSystem(&inverse_current_dir_);
}
PathOutput::~PathOutput() {
}
void PathOutput::WriteFile(std::ostream& out, const SourceFile& file) const {
WritePathStr(out, file.value());
}
void PathOutput::WriteDir(std::ostream& out,
const SourceDir& dir,
DirSlashEnding slash_ending) const {
if (dir.value() == "/") {
if (slash_ending == DIR_NO_LAST_SLASH)
out << "/.";
else
out << "/";
} else if (dir.value() == "//") {
if (slash_ending == DIR_NO_LAST_SLASH) {
if (inverse_current_dir_.empty()) {
out << ".";
} else {
out.write(inverse_current_dir_.c_str(),
inverse_current_dir_.size() - 1);
}
} else {
if (inverse_current_dir_.empty())
out << "./";
else
out << inverse_current_dir_;
}
} else if (dir == current_dir_) {
if (slash_ending == DIR_INCLUDE_LAST_SLASH)
out << "./";
else
out << ".";
} else if (slash_ending == DIR_INCLUDE_LAST_SLASH) {
WritePathStr(out, dir.value());
} else {
WritePathStr(out, base::StringPiece(dir.value().data(),
dir.value().size() - 1));
}
}
void PathOutput::WriteFile(std::ostream& out, const OutputFile& file) const {
EscapeStringToStream(out, file.value(), options_);
}
void PathOutput::WriteFile(std::ostream& out,
const base::FilePath& file) const {
EscapeStringToStream(out, FilePathToUTF8(file), options_);
}
void PathOutput::WriteSourceRelativeString(
std::ostream& out,
const base::StringPiece& str) const {
if (options_.mode == ESCAPE_SHELL) {
std::string intermediate;
intermediate.reserve(inverse_current_dir_.size() + str.size());
intermediate.assign(inverse_current_dir_.c_str(),
inverse_current_dir_.size());
intermediate.append(str.data(), str.size());
EscapeStringToStream(out,
base::StringPiece(intermediate.c_str(), intermediate.size()),
options_);
} else {
out << inverse_current_dir_;
EscapeStringToStream(out, str, options_);
}
}
void PathOutput::WritePathStr(std::ostream& out,
const base::StringPiece& str) const {
DCHECK(str.size() > 0 && str[0] == '/');
if (str.substr(0, current_dir_.value().size()) ==
base::StringPiece(current_dir_.value())) {
EscapeStringToStream(out, str.substr(current_dir_.value().size()),
options_);
} else if (str.size() >= 2 && str[1] == '/') {
WriteSourceRelativeString(out, str.substr(2));
} else {
#if defined(OS_WIN)
EscapeStringToStream(out, str.substr(1), options_);
#else
EscapeStringToStream(out, str, options_);
#endif
}
}