Index: tools/gn/source_dir.cc |
diff --git a/tools/gn/source_dir.cc b/tools/gn/source_dir.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..5739b527f5620703dc98d6d3d9a1dae52ddc4511 |
--- /dev/null |
+++ b/tools/gn/source_dir.cc |
@@ -0,0 +1,98 @@ |
+// Copyright (c) 2013 The Chromium 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 "tools/gn/source_dir.h" |
+ |
+#include "base/logging.h" |
+#include "tools/gn/filesystem_utils.h" |
+#include "tools/gn/source_file.h" |
+ |
+namespace { |
+ |
+void AssertValueSourceDirString(const std::string& s) { |
+ DCHECK(!s.empty()); |
+ DCHECK(s[0] == '/'); |
+ DCHECK(EndsWithSlash(s)); |
+} |
+ |
+} // namespace |
+ |
+SourceDir::SourceDir() { |
+} |
+ |
+SourceDir::SourceDir(const base::StringPiece& p) |
+ : value_(p.data(), p.size()) { |
+ if (!EndsWithSlash(value_)) |
+ value_.push_back('/'); |
+ AssertValueSourceDirString(value_); |
+} |
+ |
+SourceDir::~SourceDir() { |
+} |
+ |
+SourceFile SourceDir::ResolveRelativeFile(const base::StringPiece& p) const { |
+ SourceFile ret; |
+ |
+ // It's an error to resolve an empty string or one that is a directory |
+ // (indicated by a trailing slash) because this is the function that expects |
+ // to return a file. |
+ if (p.empty() || (p.size() > 0 && p[p.size() - 1] == '/')) |
+ return SourceFile(); |
+ if (p[0] == '/') { |
+ // Absolute path. |
+ ret.value_.assign(p.data(), p.size()); |
+ return ret; |
+ } |
+ |
+ ret.value_.reserve(value_.size() + p.size()); |
+ ret.value_.assign(value_); |
+ ret.value_.append(p.data(), p.size()); |
+ |
+ NormalizePath(&ret.value_); |
+ return ret; |
+} |
+ |
+SourceDir SourceDir::ResolveRelativeDir(const base::StringPiece& p) const { |
+ SourceDir ret; |
+ |
+ if (p.empty()) |
+ return ret; |
+ if (p[0] == '/') { |
+ // Absolute path. |
+ return SourceDir(p); |
+ } |
+ |
+ ret.value_.reserve(value_.size() + p.size()); |
+ ret.value_.assign(value_); |
+ ret.value_.append(p.data(), p.size()); |
+ |
+ NormalizePath(&ret.value_); |
+ if (!EndsWithSlash(ret.value_)) |
+ ret.value_.push_back('/'); |
+ AssertValueSourceDirString(ret.value_); |
+ |
+ return ret; |
+} |
+ |
+base::FilePath SourceDir::Resolve(const base::FilePath& source_root) const { |
+ if (is_null()) |
+ return base::FilePath(); |
+ |
+ std::string converted; |
+ if (is_system_absolute()) { |
+ converted = value_; |
+ ConvertPathToSystem(&converted); |
+ return base::FilePath(UTF8ToFilePath(converted)); |
+ } |
+ |
+ // String the double-leading slash for source-relative paths. |
+ converted.assign(&value_[2], value_.size() - 2); |
+ ConvertPathToSystem(&converted); |
+ return source_root.Append(UTF8ToFilePath(converted)); |
+} |
+ |
+void SourceDir::SwapInValue(std::string* v) { |
+ value_.swap(*v); |
+ AssertValueSourceDirString(value_); |
+} |