1d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// found in the LICENSE file. 4d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 5d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/label.h" 6d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 7d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/logging.h" 8d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/err.h" 9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/parse_tree.h" 10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/value.h" 11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochnamespace { 13d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// We print user visible label names with no trailing slash after the 15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// directory name. 16d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochstd::string DirWithNoTrailingSlash(const SourceDir& dir) { 17d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Be careful not to trim if the input is just "/" or "//". 18d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (dir.value().size() > 2) 19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return dir.value().substr(0, dir.value().size() - 1); 20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return dir.value(); 21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 23d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Given the separate-out input (everything before the colon) in the dep rule, 24d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// computes the final build rule. Sets err on failure. On success, 25d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// |*used_implicit| will be set to whether the implicit current directory was 26d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// used. The value is used only for generating error messages. 27d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool ComputeBuildLocationFromDep(const Value& input_value, 28d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const SourceDir& current_dir, 29d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const base::StringPiece& input, 30d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch SourceDir* result, 31d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 32d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // No rule, use the current locaton. 33d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (input.empty()) { 34d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *result = current_dir; 35d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return true; 36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 37d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 38d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Don't allow directories to start with a single slash. All labels must be 39d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // in the source root. 40d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (input[0] == '/' && (input.size() == 1 || input[1] != '/')) { 41d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(input_value, "Label can't start with a single slash", 42d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "Labels must be either relative (no slash at the beginning) or be " 43d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "absolute\ninside the source root (two slashes at the beginning)."); 44d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 45d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 46d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 47d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *result = current_dir.ResolveRelativeDir(input); 48d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return true; 49d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 50d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 51d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Given the separated-out target name (after the colon) computes the final 52d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// name, using the implicit name from the previously-generated 53d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// computed_location if necessary. The input_value is used only for generating 54d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// error messages. 55d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool ComputeTargetNameFromDep(const Value& input_value, 56d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const SourceDir& computed_location, 57d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const base::StringPiece& input, 58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::string* result, 59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 60d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!input.empty()) { 61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Easy case: input is specified, just use it. 62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch result->assign(input.data(), input.size()); 63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return true; 64d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 65d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 66d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& loc = computed_location.value(); 67d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 68d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Use implicit name. The path will be "//", "//base/", "//base/i18n/", etc. 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (loc.size() <= 2) { 70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(input_value, "This dependency name is empty"); 71d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 72d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 73d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t next_to_last_slash = loc.rfind('/', loc.size() - 2); 75d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch DCHECK(next_to_last_slash != std::string::npos); 76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch result->assign(&loc[next_to_last_slash + 1], 77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch loc.size() - next_to_last_slash - 2); 78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return true; 79d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 80d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// The original value is used only for error reporting, use the |input| as the 82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// input to this function (which may be a substring of the original value when 83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// we're parsing toolchains. 84d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// 85d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// If the output toolchain vars are NULL, then we'll report an error if we 86d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// find a toolchain specified (this is used when recursively parsing toolchain 87d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// labels which themselves can't have toolchain specs). 88d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// 89d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// We assume that the output variables are initialized to empty so we don't 90d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// write them unless we need them to contain something. 91d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// 92d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Returns true on success. On failure, the out* variables might be written to 93d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// but shouldn't be used. 94d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool Resolve(const SourceDir& current_dir, 95d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Label& current_toolchain, 96d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Value& original_value, 97d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const base::StringPiece& input, 98d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch SourceDir* out_dir, 99d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::string* out_name, 100d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch SourceDir* out_toolchain_dir, 101d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::string* out_toolchain_name, 102d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 103d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // To workaround the problem that StringPiece operator[] doesn't return a ref. 104d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const char* input_str = input.data(); 105d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 106d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t path_separator = input.find_first_of(":("); 107d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::StringPiece location_piece; 108d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::StringPiece name_piece; 109d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::StringPiece toolchain_piece; 110d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (path_separator == std::string::npos) { 111d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch location_piece = input; 112d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Leave name & toolchain piece null. 113d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 114d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch location_piece = base::StringPiece(&input_str[0], path_separator); 115d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 116d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t toolchain_separator = input.find('(', path_separator); 117d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (toolchain_separator == std::string::npos) { 118d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch name_piece = base::StringPiece(&input_str[path_separator + 1], 119d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch input.size() - path_separator - 1); 120d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Leave location piece null. 121d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else if (!out_toolchain_dir) { 122d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Toolchain specified but not allows in this context. 123d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(original_value, "Toolchain has a toolchain.", 124d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "Your toolchain definition (inside the parens) seems to itself " 125d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "have a\ntoolchain. Don't do this."); 126d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 127d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 128d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Name piece is everything between the two separators. Note that the 129d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // separators may be the same (e.g. "//foo(bar)" which means empty name. 130d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (toolchain_separator > path_separator) { 131d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch name_piece = base::StringPiece( 132d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch &input_str[path_separator + 1], 133d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch toolchain_separator - path_separator - 1); 134d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 135d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 136d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Toolchain name should end in a ) and this should be the end of the 137d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // string. 138d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (input[input.size() - 1] != ')') { 139d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(original_value, "Bad toolchain name.", 140d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "Toolchain name must end in a \")\" at the end of the label."); 141d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 142d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 143d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 144d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Subtract off the two parens to just get the toolchain name. 145d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch toolchain_piece = base::StringPiece( 146d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch &input_str[toolchain_separator + 1], 147d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch input.size() - toolchain_separator - 2); 148d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 149d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 150d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 151d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Everything before the separator is the filename. 152d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // We allow three cases: 153d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Absolute: "//foo:bar" -> /foo:bar 154d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Target in current file: ":foo" -> <currentdir>:foo 155d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Path with implicit name: "/foo" -> /foo:foo 156d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (location_piece.empty() && name_piece.empty()) { 157d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Can't use both implicit filename and name (":"). 158d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(original_value, "This doesn't specify a dependency."); 159d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 160d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 161d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 162d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!ComputeBuildLocationFromDep(original_value, current_dir, location_piece, 163d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out_dir, err)) 164d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 165d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 166d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!ComputeTargetNameFromDep(original_value, *out_dir, name_piece, 167d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out_name, err)) 168d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 169d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 170d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Last, do the toolchains. 171d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (out_toolchain_dir) { 172d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Handle empty toolchain strings. We don't allow normal labels to be 173d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // empty so we can't allow the recursive call of this function to do this 174d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // check. 175d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (toolchain_piece.empty()) { 176d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *out_toolchain_dir = current_toolchain.dir(); 177d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *out_toolchain_name = current_toolchain.name(); 178d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return true; 179d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 180d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Resolve(current_dir, current_toolchain, 181d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch original_value, toolchain_piece, 182d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out_toolchain_dir, out_toolchain_name, NULL, NULL, err); 183d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 184d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 185d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return true; 186d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 187d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 188d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} // namespace 189d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 190d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLabel::Label() { 191d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 192d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 193d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLabel::Label(const SourceDir& dir, 194d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const base::StringPiece& name, 195d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const SourceDir& toolchain_dir, 196d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const base::StringPiece& toolchain_name) 197d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch : dir_(dir), 198d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch toolchain_dir_(toolchain_dir) { 199d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch name_.assign(name.data(), name.size()); 200d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch toolchain_name_.assign(toolchain_name.data(), toolchain_name.size()); 201d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 202d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)Label::Label(const SourceDir& dir, const base::StringPiece& name) 20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : dir_(dir) { 20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) name_.assign(name.data(), name.size()); 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 208d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLabel::~Label() { 209d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 210d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 211d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// static 212d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLabel Label::Resolve(const SourceDir& current_dir, 213d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Label& current_toolchain, 214d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Value& input, 215d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 216d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Label ret; 217d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (input.type() != Value::STRING) { 218d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(input, "Dependency is not a string."); 219d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ret; 220d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 221d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& input_string = input.string_value(); 222d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (input_string.empty()) { 223d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(input, "Dependency string is empty."); 224d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ret; 225d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 226d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 227d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!::Resolve(current_dir, current_toolchain, input, input_string, 228d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch &ret.dir_, &ret.name_, 229d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch &ret.toolchain_dir_, &ret.toolchain_name_, 230d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch err)) 231d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Label(); 232d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ret; 233d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 234d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 235d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLabel Label::GetToolchainLabel() const { 23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return Label(toolchain_dir_, toolchain_name_); 237d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 238d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Label Label::GetWithNoToolchain() const { 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Label(dir_, name_); 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 243d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochstd::string Label::GetUserVisibleName(bool include_toolchain) const { 244d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::string ret; 245d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ret.reserve(dir_.value().size() + name_.size() + 1); 246d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 247d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (dir_.is_null()) 248d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ret; 249d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 250d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ret = DirWithNoTrailingSlash(dir_); 251d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ret.push_back(':'); 252d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ret.append(name_); 253d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 254d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (include_toolchain) { 255d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ret.push_back('('); 256d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!toolchain_dir_.is_null() && !toolchain_name_.empty()) { 257d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ret.append(DirWithNoTrailingSlash(toolchain_dir_)); 258d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ret.push_back(':'); 259d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ret.append(toolchain_name_); 260d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 261d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ret.push_back(')'); 262d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 263d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ret; 264d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 265d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 266d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochstd::string Label::GetUserVisibleName(const Label& default_toolchain) const { 267d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch bool include_toolchain = 268d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch default_toolchain.dir() != toolchain_dir_ || 269d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch default_toolchain.name() != toolchain_name_; 270d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return GetUserVisibleName(include_toolchain); 271d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 272