Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: tools/gn/source_dir.cc

Issue 630223002: gn: Support build directories outside the source tree. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Patch that compiles and passes unit tests on both Windows and Linux Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/setup.cc ('k') | tools/gn/source_dir_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/source_dir.h" 5 #include "tools/gn/source_dir.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "tools/gn/filesystem_utils.h" 8 #include "tools/gn/filesystem_utils.h"
9 #include "tools/gn/source_file.h" 9 #include "tools/gn/source_file.h"
10 10
11 namespace { 11 namespace {
12 12
13 void AssertValueSourceDirString(const std::string& s) { 13 void AssertValueSourceDirString(const std::string& s) {
14 if (!s.empty()) { 14 if (!s.empty()) {
15 #if defined(OS_WIN)
16 DCHECK(s[0] == '/' ||
17 (s.size() > 2 && s[0] != '/' && s[1] == ':' && IsSlash(s[2])));
18 #else
15 DCHECK(s[0] == '/'); 19 DCHECK(s[0] == '/');
20 #endif
16 DCHECK(EndsWithSlash(s)); 21 DCHECK(EndsWithSlash(s));
17 } 22 }
18 } 23 }
19 24
20 } // namespace 25 } // namespace
21 26
22 SourceDir::SourceDir() { 27 SourceDir::SourceDir() {
23 } 28 }
24 29
25 SourceDir::SourceDir(const base::StringPiece& p) 30 SourceDir::SourceDir(const base::StringPiece& p)
(...skipping 11 matching lines...) Expand all
37 } 42 }
38 43
39 SourceDir::~SourceDir() { 44 SourceDir::~SourceDir() {
40 } 45 }
41 46
42 SourceFile SourceDir::ResolveRelativeFile( 47 SourceFile SourceDir::ResolveRelativeFile(
43 const base::StringPiece& p, 48 const base::StringPiece& p,
44 const base::StringPiece& source_root) const { 49 const base::StringPiece& source_root) const {
45 SourceFile ret; 50 SourceFile ret;
46 51
52 DCHECK(source_root.empty() || !source_root.ends_with("/"));
53
47 // It's an error to resolve an empty string or one that is a directory 54 // It's an error to resolve an empty string or one that is a directory
48 // (indicated by a trailing slash) because this is the function that expects 55 // (indicated by a trailing slash) because this is the function that expects
49 // to return a file. 56 // to return a file.
50 if (p.empty() || (p.size() > 0 && p[p.size() - 1] == '/')) 57 if (p.empty() || (p.size() > 0 && p[p.size() - 1] == '/'))
51 return SourceFile(); 58 return SourceFile();
52 if (p.size() >= 2 && p[0] == '/' && p[1] == '/') { 59 if (p.size() >= 2 && p[0] == '/' && p[1] == '/') {
53 // Source-relative. 60 // Source-relative.
54 ret.value_.assign(p.data(), p.size()); 61 ret.value_.assign(p.data(), p.size());
55 NormalizePath(&ret.value_); 62 NormalizePath(&ret.value_);
56 return ret; 63 return ret;
57 } else if (IsPathAbsolute(p)) { 64 } else if (IsPathAbsolute(p)) {
58 if (source_root.empty() || 65 if (source_root.empty() ||
59 !MakeAbsolutePathRelativeIfPossible(source_root, p, &ret.value_)) { 66 !MakeAbsolutePathRelativeIfPossible(source_root, p, &ret.value_)) {
60 #if defined(OS_WIN) 67 #if defined(OS_WIN)
61 // On Windows we'll accept "C:\foo" as an absolute path, which we want 68 // On Windows we'll accept "C:\foo" as an absolute path, which we want
62 // to convert to "/C:..." here. 69 // to convert to "/C:..." here.
63 if (p[0] != '/') 70 if (p[0] != '/')
64 ret.value_ = "/"; 71 ret.value_ = "/";
65 #endif 72 #endif
66 ret.value_.append(p.data(), p.size()); 73 ret.value_.append(p.data(), p.size());
67 } 74 }
68 NormalizePath(&ret.value_); 75 NormalizePath(&ret.value_);
69 return ret; 76 return ret;
70 } 77 }
71 78
79 if (!source_root.empty()) {
80 std::string absolute =
81 FilePathToUTF8(Resolve(UTF8ToFilePath(source_root)).AppendASCII(
82 p.as_string()).value());
83 NormalizePath(&absolute);
84 if (!MakeAbsolutePathRelativeIfPossible(source_root, absolute,
85 &ret.value_))
86 ret.value_ = absolute;
87 return ret;
88 }
89
90 // With no source_root_, there's nothing we can do about
91 // e.g. p=../../../path/to/file and value_=//source and we'll
92 // errornously return //file.
72 ret.value_.reserve(value_.size() + p.size()); 93 ret.value_.reserve(value_.size() + p.size());
73 ret.value_.assign(value_); 94 ret.value_.assign(value_);
74 ret.value_.append(p.data(), p.size()); 95 ret.value_.append(p.data(), p.size());
75 96
76 NormalizePath(&ret.value_); 97 NormalizePath(&ret.value_);
77 return ret; 98 return ret;
78 } 99 }
79 100
80 SourceDir SourceDir::ResolveRelativeDir( 101 SourceDir SourceDir::ResolveRelativeDir(
81 const base::StringPiece& p, 102 const base::StringPiece& p,
82 const base::StringPiece& source_root) const { 103 const base::StringPiece& source_root) const {
83 SourceDir ret; 104 SourceDir ret;
84 105
106 DCHECK(source_root.empty() || !source_root.ends_with("/"));
107
85 if (p.empty()) 108 if (p.empty())
86 return ret; 109 return ret;
87 if (p.size() >= 2 && p[0] == '/' && p[1] == '/') { 110 if (p.size() >= 2 && p[0] == '/' && p[1] == '/') {
88 // Source-relative. 111 // Source-relative.
89 ret.value_.assign(p.data(), p.size()); 112 ret.value_.assign(p.data(), p.size());
90 if (!EndsWithSlash(ret.value_)) 113 if (!EndsWithSlash(ret.value_))
91 ret.value_.push_back('/'); 114 ret.value_.push_back('/');
92 NormalizePath(&ret.value_); 115 NormalizePath(&ret.value_);
93 return ret; 116 return ret;
94 } else if (IsPathAbsolute(p)) { 117 } else if (IsPathAbsolute(p)) {
95 if (source_root.empty() || 118 if (source_root.empty() ||
96 !MakeAbsolutePathRelativeIfPossible(source_root, p, &ret.value_)) { 119 !MakeAbsolutePathRelativeIfPossible(source_root, p, &ret.value_)) {
97 #if defined(OS_WIN) 120 #if defined(OS_WIN)
98 if (p[0] != '/') // See the file case for why we do this check. 121 if (p[0] != '/') // See the file case for why we do this check.
99 ret.value_ = "/"; 122 ret.value_ = "/";
100 #endif 123 #endif
101 ret.value_.append(p.data(), p.size()); 124 ret.value_.append(p.data(), p.size());
102 } 125 }
103 NormalizePath(&ret.value_); 126 NormalizePath(&ret.value_);
104 if (!EndsWithSlash(ret.value_)) 127 if (!EndsWithSlash(ret.value_))
105 ret.value_.push_back('/'); 128 ret.value_.push_back('/');
106 return ret; 129 return ret;
107 } 130 }
108 131
132 if (!source_root.empty()) {
133 std::string absolute =
134 FilePathToUTF8(Resolve(UTF8ToFilePath(source_root)).AppendASCII(
135 p.as_string()).value());
136 NormalizePath(&absolute);
137 if (!MakeAbsolutePathRelativeIfPossible(source_root, absolute, &ret.value_))
138 ret.value_ = absolute;
139 if (!EndsWithSlash(ret.value_))
140 ret.value_.push_back('/');
141 return ret;
142 }
143
109 ret.value_.reserve(value_.size() + p.size()); 144 ret.value_.reserve(value_.size() + p.size());
110 ret.value_.assign(value_); 145 ret.value_.assign(value_);
111 ret.value_.append(p.data(), p.size()); 146 ret.value_.append(p.data(), p.size());
112 147
113 NormalizePath(&ret.value_); 148 NormalizePath(&ret.value_);
114 if (!EndsWithSlash(ret.value_)) 149 if (!EndsWithSlash(ret.value_))
115 ret.value_.push_back('/'); 150 ret.value_.push_back('/');
116 AssertValueSourceDirString(ret.value_); 151 AssertValueSourceDirString(ret.value_);
117 152
118 return ret; 153 return ret;
(...skipping 17 matching lines...) Expand all
136 // String the double-leading slash for source-relative paths. 171 // String the double-leading slash for source-relative paths.
137 converted.assign(&value_[2], value_.size() - 2); 172 converted.assign(&value_[2], value_.size() - 2);
138 return source_root.Append(UTF8ToFilePath(converted)) 173 return source_root.Append(UTF8ToFilePath(converted))
139 .NormalizePathSeparatorsTo('/'); 174 .NormalizePathSeparatorsTo('/');
140 } 175 }
141 176
142 void SourceDir::SwapValue(std::string* v) { 177 void SourceDir::SwapValue(std::string* v) {
143 value_.swap(*v); 178 value_.swap(*v);
144 AssertValueSourceDirString(value_); 179 AssertValueSourceDirString(value_);
145 } 180 }
OLDNEW
« no previous file with comments | « tools/gn/setup.cc ('k') | tools/gn/source_dir_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698