1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "tools/gn/source_dir.h" 6 7 #include "base/logging.h" 8 #include "tools/gn/filesystem_utils.h" 9 #include "tools/gn/source_file.h" 10 11 namespace { 12 13 void AssertValueSourceDirString(const std::string& s) { 14 DCHECK(!s.empty()); 15 DCHECK(s[0] == '/'); 16 DCHECK(EndsWithSlash(s)); 17 } 18 19 } // namespace 20 21 SourceDir::SourceDir() { 22 } 23 24 SourceDir::SourceDir(const base::StringPiece& p) 25 : value_(p.data(), p.size()) { 26 if (!EndsWithSlash(value_)) 27 value_.push_back('/'); 28 AssertValueSourceDirString(value_); 29 } 30 31 SourceDir::~SourceDir() { 32 } 33 34 SourceFile SourceDir::ResolveRelativeFile(const base::StringPiece& p) const { 35 SourceFile ret; 36 37 // It's an error to resolve an empty string or one that is a directory 38 // (indicated by a trailing slash) because this is the function that expects 39 // to return a file. 40 if (p.empty() || (p.size() > 0 && p[p.size() - 1] == '/')) 41 return SourceFile(); 42 if (p[0] == '/') { 43 // Absolute path. 44 ret.value_.assign(p.data(), p.size()); 45 return ret; 46 } 47 48 ret.value_.reserve(value_.size() + p.size()); 49 ret.value_.assign(value_); 50 ret.value_.append(p.data(), p.size()); 51 52 NormalizePath(&ret.value_); 53 return ret; 54 } 55 56 SourceDir SourceDir::ResolveRelativeDir(const base::StringPiece& p) const { 57 SourceDir ret; 58 59 if (p.empty()) 60 return ret; 61 if (p[0] == '/') { 62 // Absolute path. 63 return SourceDir(p); 64 } 65 66 ret.value_.reserve(value_.size() + p.size()); 67 ret.value_.assign(value_); 68 ret.value_.append(p.data(), p.size()); 69 70 NormalizePath(&ret.value_); 71 if (!EndsWithSlash(ret.value_)) 72 ret.value_.push_back('/'); 73 AssertValueSourceDirString(ret.value_); 74 75 return ret; 76 } 77 78 base::FilePath SourceDir::Resolve(const base::FilePath& source_root) const { 79 if (is_null()) 80 return base::FilePath(); 81 82 std::string converted; 83 if (is_system_absolute()) { 84 converted = value_; 85 ConvertPathToSystem(&converted); 86 return base::FilePath(UTF8ToFilePath(converted)); 87 } 88 89 // String the double-leading slash for source-relative paths. 90 converted.assign(&value_[2], value_.size() - 2); 91 ConvertPathToSystem(&converted); 92 return source_root.Append(UTF8ToFilePath(converted)); 93 } 94 95 void SourceDir::SwapInValue(std::string* v) { 96 value_.swap(*v); 97 AssertValueSourceDirString(value_); 98 } 99