OLD | NEW |
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/label.h" | 5 #include "tools/gn/label.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "tools/gn/err.h" | 8 #include "tools/gn/err.h" |
9 #include "tools/gn/parse_tree.h" | 9 #include "tools/gn/parse_tree.h" |
10 #include "tools/gn/value.h" | 10 #include "tools/gn/value.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 } | 21 } |
22 | 22 |
23 // Given the separate-out input (everything before the colon) in the dep rule, | 23 // Given the separate-out input (everything before the colon) in the dep rule, |
24 // computes the final build rule. Sets err on failure. On success, | 24 // computes the final build rule. Sets err on failure. On success, |
25 // |*used_implicit| will be set to whether the implicit current directory was | 25 // |*used_implicit| will be set to whether the implicit current directory was |
26 // used. The value is used only for generating error messages. | 26 // used. The value is used only for generating error messages. |
27 bool ComputeBuildLocationFromDep(const Value& input_value, | 27 bool ComputeBuildLocationFromDep(const Value& input_value, |
28 const SourceDir& current_dir, | 28 const SourceDir& current_dir, |
29 const base::StringPiece& input, | 29 const base::StringPiece& input, |
30 SourceDir* result, | 30 SourceDir* result, |
| 31 const base::FilePath& source_root, |
31 Err* err) { | 32 Err* err) { |
32 // No rule, use the current locaton. | 33 // No rule, use the current locaton. |
33 if (input.empty()) { | 34 if (input.empty()) { |
34 *result = current_dir; | 35 *result = current_dir; |
35 return true; | 36 return true; |
36 } | 37 } |
37 | 38 |
38 // Don't allow directories to start with a single slash. All labels must be | 39 // Don't allow directories to start with a single slash. All labels must be |
39 // in the source root. | 40 // in the source root. |
40 if (input[0] == '/' && (input.size() == 1 || input[1] != '/')) { | 41 if (input[0] == '/' && (input.size() == 1 || input[1] != '/')) { |
41 *err = Err(input_value, "Label can't start with a single slash", | 42 *err = Err(input_value, "Label can't start with a single slash", |
42 "Labels must be either relative (no slash at the beginning) or be " | 43 "Labels must be either relative (no slash at the beginning) or be " |
43 "absolute\ninside the source root (two slashes at the beginning)."); | 44 "absolute\ninside the source root (two slashes at the beginning)."); |
44 return false; | 45 return false; |
45 } | 46 } |
46 | 47 |
47 *result = current_dir.ResolveRelativeDir(input); | 48 *result = current_dir.ResolveRelativeDir(input, source_root); |
48 return true; | 49 return true; |
49 } | 50 } |
50 | 51 |
51 // Given the separated-out target name (after the colon) computes the final | 52 // Given the separated-out target name (after the colon) computes the final |
52 // name, using the implicit name from the previously-generated | 53 // name, using the implicit name from the previously-generated |
53 // computed_location if necessary. The input_value is used only for generating | 54 // computed_location if necessary. The input_value is used only for generating |
54 // error messages. | 55 // error messages. |
55 bool ComputeTargetNameFromDep(const Value& input_value, | 56 bool ComputeTargetNameFromDep(const Value& input_value, |
56 const SourceDir& computed_location, | 57 const SourceDir& computed_location, |
57 const base::StringPiece& input, | 58 const base::StringPiece& input, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 // Returns true on success. On failure, the out* variables might be written to | 93 // Returns true on success. On failure, the out* variables might be written to |
93 // but shouldn't be used. | 94 // but shouldn't be used. |
94 bool Resolve(const SourceDir& current_dir, | 95 bool Resolve(const SourceDir& current_dir, |
95 const Label& current_toolchain, | 96 const Label& current_toolchain, |
96 const Value& original_value, | 97 const Value& original_value, |
97 const base::StringPiece& input, | 98 const base::StringPiece& input, |
98 SourceDir* out_dir, | 99 SourceDir* out_dir, |
99 std::string* out_name, | 100 std::string* out_name, |
100 SourceDir* out_toolchain_dir, | 101 SourceDir* out_toolchain_dir, |
101 std::string* out_toolchain_name, | 102 std::string* out_toolchain_name, |
| 103 const base::FilePath& source_root, |
102 Err* err) { | 104 Err* err) { |
103 // To workaround the problem that StringPiece operator[] doesn't return a ref. | 105 // To workaround the problem that StringPiece operator[] doesn't return a ref. |
104 const char* input_str = input.data(); | 106 const char* input_str = input.data(); |
105 | 107 |
106 size_t path_separator = input.find_first_of(":("); | 108 size_t path_separator = input.find_first_of(":("); |
107 base::StringPiece location_piece; | 109 base::StringPiece location_piece; |
108 base::StringPiece name_piece; | 110 base::StringPiece name_piece; |
109 base::StringPiece toolchain_piece; | 111 base::StringPiece toolchain_piece; |
110 if (path_separator == std::string::npos) { | 112 if (path_separator == std::string::npos) { |
111 location_piece = input; | 113 location_piece = input; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 // Absolute: "//foo:bar" -> /foo:bar | 155 // Absolute: "//foo:bar" -> /foo:bar |
154 // Target in current file: ":foo" -> <currentdir>:foo | 156 // Target in current file: ":foo" -> <currentdir>:foo |
155 // Path with implicit name: "/foo" -> /foo:foo | 157 // Path with implicit name: "/foo" -> /foo:foo |
156 if (location_piece.empty() && name_piece.empty()) { | 158 if (location_piece.empty() && name_piece.empty()) { |
157 // Can't use both implicit filename and name (":"). | 159 // Can't use both implicit filename and name (":"). |
158 *err = Err(original_value, "This doesn't specify a dependency."); | 160 *err = Err(original_value, "This doesn't specify a dependency."); |
159 return false; | 161 return false; |
160 } | 162 } |
161 | 163 |
162 if (!ComputeBuildLocationFromDep(original_value, current_dir, location_piece, | 164 if (!ComputeBuildLocationFromDep(original_value, current_dir, location_piece, |
163 out_dir, err)) | 165 out_dir, source_root, err)) |
164 return false; | 166 return false; |
165 | 167 |
166 if (!ComputeTargetNameFromDep(original_value, *out_dir, name_piece, | 168 if (!ComputeTargetNameFromDep(original_value, *out_dir, name_piece, |
167 out_name, err)) | 169 out_name, err)) |
168 return false; | 170 return false; |
169 | 171 |
170 // Last, do the toolchains. | 172 // Last, do the toolchains. |
171 if (out_toolchain_dir) { | 173 if (out_toolchain_dir) { |
172 // Handle empty toolchain strings. We don't allow normal labels to be | 174 // Handle empty toolchain strings. We don't allow normal labels to be |
173 // empty so we can't allow the recursive call of this function to do this | 175 // empty so we can't allow the recursive call of this function to do this |
174 // check. | 176 // check. |
175 if (toolchain_piece.empty()) { | 177 if (toolchain_piece.empty()) { |
176 *out_toolchain_dir = current_toolchain.dir(); | 178 *out_toolchain_dir = current_toolchain.dir(); |
177 *out_toolchain_name = current_toolchain.name(); | 179 *out_toolchain_name = current_toolchain.name(); |
178 return true; | 180 return true; |
179 } else { | 181 } else { |
180 return Resolve(current_dir, current_toolchain, | 182 return Resolve(current_dir, current_toolchain, |
181 original_value, toolchain_piece, | 183 original_value, toolchain_piece, |
182 out_toolchain_dir, out_toolchain_name, NULL, NULL, err); | 184 out_toolchain_dir, out_toolchain_name, NULL, NULL, |
| 185 source_root, err); |
183 } | 186 } |
184 } | 187 } |
185 return true; | 188 return true; |
186 } | 189 } |
187 | 190 |
188 } // namespace | 191 } // namespace |
189 | 192 |
190 Label::Label() { | 193 Label::Label() { |
191 } | 194 } |
192 | 195 |
(...skipping 12 matching lines...) Expand all Loading... |
205 name_.assign(name.data(), name.size()); | 208 name_.assign(name.data(), name.size()); |
206 } | 209 } |
207 | 210 |
208 Label::~Label() { | 211 Label::~Label() { |
209 } | 212 } |
210 | 213 |
211 // static | 214 // static |
212 Label Label::Resolve(const SourceDir& current_dir, | 215 Label Label::Resolve(const SourceDir& current_dir, |
213 const Label& current_toolchain, | 216 const Label& current_toolchain, |
214 const Value& input, | 217 const Value& input, |
| 218 const base::FilePath& source_root, |
215 Err* err) { | 219 Err* err) { |
216 Label ret; | 220 Label ret; |
217 if (input.type() != Value::STRING) { | 221 if (input.type() != Value::STRING) { |
218 *err = Err(input, "Dependency is not a string."); | 222 *err = Err(input, "Dependency is not a string."); |
219 return ret; | 223 return ret; |
220 } | 224 } |
221 const std::string& input_string = input.string_value(); | 225 const std::string& input_string = input.string_value(); |
222 if (input_string.empty()) { | 226 if (input_string.empty()) { |
223 *err = Err(input, "Dependency string is empty."); | 227 *err = Err(input, "Dependency string is empty."); |
224 return ret; | 228 return ret; |
225 } | 229 } |
226 | 230 |
227 if (!::Resolve(current_dir, current_toolchain, input, input_string, | 231 if (!::Resolve(current_dir, current_toolchain, input, input_string, |
228 &ret.dir_, &ret.name_, | 232 &ret.dir_, &ret.name_, |
229 &ret.toolchain_dir_, &ret.toolchain_name_, | 233 &ret.toolchain_dir_, &ret.toolchain_name_, |
230 err)) | 234 source_root, err)) |
231 return Label(); | 235 return Label(); |
232 return ret; | 236 return ret; |
233 } | 237 } |
234 | 238 |
235 Label Label::GetToolchainLabel() const { | 239 Label Label::GetToolchainLabel() const { |
236 return Label(toolchain_dir_, toolchain_name_); | 240 return Label(toolchain_dir_, toolchain_name_); |
237 } | 241 } |
238 | 242 |
239 Label Label::GetWithNoToolchain() const { | 243 Label Label::GetWithNoToolchain() const { |
240 return Label(dir_, name_); | 244 return Label(dir_, name_); |
(...skipping 21 matching lines...) Expand all Loading... |
262 } | 266 } |
263 return ret; | 267 return ret; |
264 } | 268 } |
265 | 269 |
266 std::string Label::GetUserVisibleName(const Label& default_toolchain) const { | 270 std::string Label::GetUserVisibleName(const Label& default_toolchain) const { |
267 bool include_toolchain = | 271 bool include_toolchain = |
268 default_toolchain.dir() != toolchain_dir_ || | 272 default_toolchain.dir() != toolchain_dir_ || |
269 default_toolchain.name() != toolchain_name_; | 273 default_toolchain.name() != toolchain_name_; |
270 return GetUserVisibleName(include_toolchain); | 274 return GetUserVisibleName(include_toolchain); |
271 } | 275 } |
OLD | NEW |