source_dir.cc revision 3551c9c881056c480085172ff9840cab31610854
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 11namespace { 12 13void AssertValueSourceDirString(const std::string& s) { 14 DCHECK(!s.empty()); 15 DCHECK(s[0] == '/'); 16 DCHECK(EndsWithSlash(s)); 17} 18 19} // namespace 20 21SourceDir::SourceDir() { 22} 23 24SourceDir::SourceDir(const base::StringPiece& p) 25 : value_(p.data(), p.size()) { 26 if (!EndsWithSlash(value_)) 27 value_.push_back('/'); 28 AssertValueSourceDirString(value_); 29} 30 31SourceDir::~SourceDir() { 32} 33 34SourceFile SourceDir::ResolveRelativeFile( 35 const base::StringPiece& p, 36 const base::StringPiece& source_root) const { 37 SourceFile ret; 38 39 // It's an error to resolve an empty string or one that is a directory 40 // (indicated by a trailing slash) because this is the function that expects 41 // to return a file. 42 if (p.empty() || (p.size() > 0 && p[p.size() - 1] == '/')) 43 return SourceFile(); 44 if (p.size() >= 2 && p[0] == '/' && p[1] == '/') { 45 // Source-relative. 46 ret.value_.assign(p.data(), p.size()); 47 NormalizePath(&ret.value_); 48 return ret; 49 } else if (IsPathAbsolute(p)) { 50 if (source_root.empty() || 51 !MakeAbsolutePathRelativeIfPossible(source_root, p, &ret.value_)) 52 ret.value_.assign(p.data(), p.size()); 53 NormalizePath(&ret.value_); 54 return ret; 55 } 56 57 ret.value_.reserve(value_.size() + p.size()); 58 ret.value_.assign(value_); 59 ret.value_.append(p.data(), p.size()); 60 61 NormalizePath(&ret.value_); 62 return ret; 63} 64 65SourceDir SourceDir::ResolveRelativeDir( 66 const base::StringPiece& p, 67 const base::StringPiece& source_root) const { 68 SourceDir ret; 69 70 if (p.empty()) 71 return ret; 72 if (p.size() >= 2 && p[0] == '/' && p[1] == '/') { 73 // Source-relative. 74 ret.value_.assign(p.data(), p.size()); 75 if (!EndsWithSlash(ret.value_)) 76 ret.value_.push_back('/'); 77 NormalizePath(&ret.value_); 78 return ret; 79 } else if (IsPathAbsolute(p)) { 80 if (source_root.empty() || 81 !MakeAbsolutePathRelativeIfPossible(source_root, p, &ret.value_)) 82 ret.value_.assign(p.data(), p.size()); 83 NormalizePath(&ret.value_); 84 if (!EndsWithSlash(ret.value_)) 85 ret.value_.push_back('/'); 86 return SourceDir(p); 87 } 88 89 ret.value_.reserve(value_.size() + p.size()); 90 ret.value_.assign(value_); 91 ret.value_.append(p.data(), p.size()); 92 93 NormalizePath(&ret.value_); 94 if (!EndsWithSlash(ret.value_)) 95 ret.value_.push_back('/'); 96 AssertValueSourceDirString(ret.value_); 97 98 return ret; 99} 100 101base::FilePath SourceDir::Resolve(const base::FilePath& source_root) const { 102 if (is_null()) 103 return base::FilePath(); 104 105 std::string converted; 106 if (is_system_absolute()) { 107 converted = value_; 108 ConvertPathToSystem(&converted); 109 return base::FilePath(UTF8ToFilePath(converted)); 110 } 111 112 // String the double-leading slash for source-relative paths. 113 converted.assign(&value_[2], value_.size() - 2); 114 ConvertPathToSystem(&converted); 115 return source_root.Append(UTF8ToFilePath(converted)); 116} 117 118void SourceDir::SwapInValue(std::string* v) { 119 value_.swap(*v); 120 AssertValueSourceDirString(value_); 121} 122