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/filesystem_utils.h" 6d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <algorithm> 868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/logging.h" 11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/strings/string_util.h" 12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/strings/utf_string_conversions.h" 13d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "build/build_config.h" 14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/location.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "tools/gn/settings.h" 16d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/source_dir.h" 17d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 18d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochnamespace { 19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochenum DotDisposition { 21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // The given dot is just part of a filename and is not special. 22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch NOT_A_DIRECTORY, 23d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 24d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // The given dot is the current directory. 25d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch DIRECTORY_CUR, 26d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 27d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // The given dot is the first of a double dot that should take us up one. 28d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch DIRECTORY_UP 29d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}; 30d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 31d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// When we find a dot, this function is called with the character following 32d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// that dot to see what it is. The return value indicates what type this dot is 33d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// (see above). This code handles the case where the dot is at the end of the 34d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// input. 35d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// 36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// |*consumed_len| will contain the number of characters in the input that 37d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// express what we found. 38d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochDotDisposition ClassifyAfterDot(const std::string& path, 39d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t after_dot, 40d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t* consumed_len) { 41d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (after_dot == path.size()) { 42d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Single dot at the end. 43d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *consumed_len = 1; 44d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return DIRECTORY_CUR; 45d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsSlash(path[after_dot])) { 47d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Single dot followed by a slash. 48d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *consumed_len = 2; // Consume the slash 49d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return DIRECTORY_CUR; 50d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 51d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 52d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (path[after_dot] == '.') { 53d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Two dots. 54d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (after_dot + 1 == path.size()) { 55d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Double dot at the end. 56d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *consumed_len = 2; 57d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return DIRECTORY_UP; 58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsSlash(path[after_dot + 1])) { 60d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Double dot folowed by a slash. 61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *consumed_len = 3; 62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return DIRECTORY_UP; 63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 64d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 65d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 66d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // The dots are followed by something else, not a directory. 67d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *consumed_len = 1; 68d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return NOT_A_DIRECTORY; 69d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#if defined(OS_WIN) 72424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)inline char NormalizeWindowsPathChar(char c) { 73424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (c == '/') 74424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return '\\'; 75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return base::ToLowerASCII(c); 76424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 77424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 78424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Attempts to do a case and slash-insensitive comparison of two 8-bit Windows 79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// paths. 80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool AreAbsoluteWindowsPathsEqual(const base::StringPiece& a, 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const base::StringPiece& b) { 82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (a.size() != b.size()) 83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // For now, just do a case-insensitive ASCII comparison. We could convert to 86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // UTF-16 and use ICU if necessary. Or maybe base::strcasecmp is good enough? 87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (size_t i = 0; i < a.size(); i++) { 88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (NormalizeWindowsPathChar(a[i]) != NormalizeWindowsPathChar(b[i])) 89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool DoesBeginWindowsDriveLetter(const base::StringPiece& path) { 95424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (path.size() < 3) 96424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 98424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Check colon first, this will generally fail fastest. 99424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (path[1] != ':') 100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Check drive letter. 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!IsAsciiAlpha(path[0])) 104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!IsSlash(path[2])) 107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 110424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif 111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// A wrapper around FilePath.GetComponents that works the way we need. This is 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// not super efficient since it does some O(n) transformations on the path. If 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// this is called a lot, we might want to optimize. 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::vector<base::FilePath::StringType> GetPathComponents( 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::FilePath& path) { 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<base::FilePath::StringType> result; 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) path.GetComponents(&result); 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (result.empty()) 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return result; 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // GetComponents will preserve the "/" at the beginning, which confuses us. 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We don't expect to have relative paths in this function. 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Don't use IsSeparator since we always want to allow backslashes. 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (result[0] == FILE_PATH_LITERAL("/") || 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result[0] == FILE_PATH_LITERAL("\\")) 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result.erase(result.begin()); 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_WIN) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // On Windows, GetComponents will give us [ "C:", "/", "foo" ], and we 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // don't want the slash in there. This doesn't support input like "C:foo" 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // which means foo relative to the current directory of the C drive but 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // that's basically legacy DOS behavior we don't need to support. 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (result.size() >= 2 && result[1].size() == 1 && IsSlash(result[1][0])) 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result.erase(result.begin() + 1); 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return result; 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Provides the equivalent of == for filesystem strings, trying to do 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// approximately the right thing with case. 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool FilesystemStringsEqual(const base::FilePath::StringType& a, 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::FilePath::StringType& b) { 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_WIN) 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Assume case-insensitive filesystems on Windows. We use the CompareString 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // function to do a case-insensitive comparison based on the current locale 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // (we don't want GN to depend on ICU which is large and requires data 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // files). This isn't perfect, but getting this perfectly right is very 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // difficult and requires I/O, and this comparison should cover 99.9999% of 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // all cases. 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Note: The documentation for CompareString says it runs fastest on 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // null-terminated strings with -1 passed for the length, so we do that here. 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There should not be embedded nulls in filesystem strings. 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return ::CompareString(LOCALE_USER_DEFAULT, LINGUISTIC_IGNORECASE, 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) a.c_str(), -1, b.c_str(), -1) == CSTR_EQUAL; 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#else 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Assume case-sensitive filesystems on non-Windows. 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return a == b; 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace 166d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 167d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char* GetExtensionForOutputType(Target::OutputType type, 168d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Settings::TargetOS os) { 169d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch switch (os) { 1702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch case Settings::MAC: 1712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch switch (type) { 1722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch case Target::EXECUTABLE: 1732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return ""; 1742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch case Target::SHARED_LIBRARY: 1752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return "dylib"; 1762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch case Target::STATIC_LIBRARY: 1772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return "a"; 1782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch default: 1792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch NOTREACHED(); 1802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 1812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch break; 1822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 183d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case Settings::WIN: 184d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch switch (type) { 185d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case Target::EXECUTABLE: 186d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "exe"; 187d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case Target::SHARED_LIBRARY: 188d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "dll.lib"; // Extension of import library. 189d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case Target::STATIC_LIBRARY: 190d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "lib"; 1913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case Settings::LINUX: 1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (type) { 1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case Target::EXECUTABLE: 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return ""; 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case Target::SHARED_LIBRARY: 2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "so"; 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case Target::STATIC_LIBRARY: 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "a"; 204d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch default: 205d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch NOTREACHED(); 206d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 207d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch break; 208d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 209d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch default: 210d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch NOTREACHED(); 211d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 212d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ""; 213d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 214d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::string FilePathToUTF8(const base::FilePath::StringType& str) { 216d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#if defined(OS_WIN) 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::WideToUTF8(str); 218d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#else 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return str; 220d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#endif 221d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 222d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 223d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbase::FilePath UTF8ToFilePath(const base::StringPiece& sp) { 224d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#if defined(OS_WIN) 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::FilePath(base::UTF8ToWide(sp)); 226d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#else 227d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::FilePath(sp.as_string()); 228d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#endif 229d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 230d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 231d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochsize_t FindExtensionOffset(const std::string& path) { 232d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (int i = static_cast<int>(path.size()); i >= 0; i--) { 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsSlash(path[i])) 234d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch break; 235d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (path[i] == '.') 236d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return i + 1; 237d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 238d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return std::string::npos; 239d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 240d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 241d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbase::StringPiece FindExtension(const std::string* path) { 242d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t extension_offset = FindExtensionOffset(*path); 243d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (extension_offset == std::string::npos) 244d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(); 245d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(&path->data()[extension_offset], 246d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch path->size() - extension_offset); 247d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 248d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 249d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochsize_t FindFilenameOffset(const std::string& path) { 250d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (int i = static_cast<int>(path.size()) - 1; i >= 0; i--) { 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsSlash(path[i])) 252d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return i + 1; 253d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 254d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return 0; // No filename found means everything was the filename. 255d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 256d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 257d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbase::StringPiece FindFilename(const std::string* path) { 258d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t filename_offset = FindFilenameOffset(*path); 259d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (filename_offset == 0) 260d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(*path); // Everything is the file name. 261d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(&(*path).data()[filename_offset], 262d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch path->size() - filename_offset); 263d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 264d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 265d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbase::StringPiece FindFilenameNoExtension(const std::string* path) { 266d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (path->empty()) 267d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(); 268d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t filename_offset = FindFilenameOffset(*path); 269d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t extension_offset = FindExtensionOffset(*path); 270d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 271d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t name_len; 272d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (extension_offset == std::string::npos) 273d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch name_len = path->size() - filename_offset; 274d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch else 275d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch name_len = extension_offset - filename_offset - 1; 276d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 277d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(&(*path).data()[filename_offset], name_len); 278d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 279d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 280d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid RemoveFilename(std::string* path) { 281d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch path->resize(FindFilenameOffset(*path)); 282d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 283d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 284d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool EndsWithSlash(const std::string& s) { 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return !s.empty() && IsSlash(s[s.size() - 1]); 286d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 287d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 288d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbase::StringPiece FindDir(const std::string* path) { 289d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t filename_offset = FindFilenameOffset(*path); 290d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (filename_offset == 0u) 291d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(); 292d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(path->data(), filename_offset); 293d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 294d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 2955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubase::StringPiece FindLastDirComponent(const SourceDir& dir) { 2965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& dir_string = dir.value(); 2975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (dir_string.empty()) 2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return base::StringPiece(); 3005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int cur = static_cast<int>(dir_string.size()) - 1; 3015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(dir_string[cur] == '/'); 3025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int end = cur; 3035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu cur--; // Skip before the last slash. 3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (; cur >= 0; cur--) { 3065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (dir_string[cur] == '/') 3075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return base::StringPiece(&dir_string[cur + 1], end - cur - 1); 3085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 3095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return base::StringPiece(&dir_string[0], end); 3105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 312d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool EnsureStringIsInOutputDir(const SourceDir& dir, 313d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& str, 31403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const ParseNode* origin, 315d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 316d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // This check will be wrong for all proper prefixes "e.g. "/output" will 317d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // match "/out" but we don't really care since this is just a sanity check. 318d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& dir_str = dir.value(); 319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (str.compare(0, dir_str.length(), dir_str) == 0) 320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; // Output directory is hardcoded. 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) *err = Err(origin, "File is not inside output directory.", 323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "The given file should be in the output directory. Normally you would " 324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "specify\n\"$target_out_dir/foo\" or " 325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "\"$target_gen_dir/foo\". I interpreted this as\n\"" 326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch + str + "\"."); 327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 328d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 329d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool IsPathAbsolute(const base::StringPiece& path) { 3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (path.empty()) 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!IsSlash(path[0])) { 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_WIN) 3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Check for Windows system paths like "C:\foo". 337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (path.size() > 2 && path[1] == ':' && IsSlash(path[2])) 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; // Doesn't begin with a slash, is relative. 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Double forward slash at the beginning means source-relative (we don't 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // allow backslashes for denoting this). 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (path.size() > 1 && path[1] == '/') 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MakeAbsolutePathRelativeIfPossible(const base::StringPiece& source_root, 3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::StringPiece& path, 3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* dest) { 3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(IsPathAbsolute(source_root)); 3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(IsPathAbsolute(path)); 3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dest->clear(); 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (source_root.size() > path.size()) 3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; // The source root is longer: the path can never be inside. 3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_WIN) 363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Source root should be canonical on Windows. Note that the initial slash 364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // must be forward slash, but that the other ones can be either forward or 365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // backward. 3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(source_root.size() > 2 && source_root[0] != '/' && 367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) source_root[1] == ':' && IsSlash(source_root[2])); 368424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 369424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t after_common_index = std::string::npos; 370424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (DoesBeginWindowsDriveLetter(path)) { 371424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Handle "C:\foo" 372424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (AreAbsoluteWindowsPathsEqual(source_root, 373424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) path.substr(0, source_root.size()))) 374424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) after_common_index = source_root.size(); 375424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else 376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 377424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else if (path[0] == '/' && source_root.size() <= path.size() - 1 && 378424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DoesBeginWindowsDriveLetter(path.substr(1))) { 379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Handle "/C:/foo" 380424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (AreAbsoluteWindowsPathsEqual(source_root, 381424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) path.substr(1, source_root.size()))) 382424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) after_common_index = source_root.size() + 1; 383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else 384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 385424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 388424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 389424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If we get here, there's a match and after_common_index identifies the 390424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // part after it. 391424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 392424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // The base may or may not have a trailing slash, so skip all slashes from 393424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // the path after our prefix match. 394424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t first_after_slash = after_common_index; 395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (first_after_slash < path.size() && IsSlash(path[first_after_slash])) 396424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) first_after_slash++; 397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dest->assign("//"); // Result is source root relative. 399424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dest->append(&path.data()[first_after_slash], 400424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) path.size() - first_after_slash); 401424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 402424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#else 404424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // On non-Windows this is easy. Since we know both are absolute, just do a 4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // prefix check. 4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (path.substr(0, source_root.size()) == source_root) { 4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The base may or may not have a trailing slash, so skip all slashes from 4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the path after our prefix match. 4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t first_after_slash = source_root.size(); 411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (first_after_slash < path.size() && IsSlash(path[first_after_slash])) 4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) first_after_slash++; 4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 414424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dest->assign("//"); // Result is source root relative. 4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dest->append(&path.data()[first_after_slash], 4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) path.size() - first_after_slash); 4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 420424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif 4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 423d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochstd::string InvertDir(const SourceDir& path) { 424d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string value = path.value(); 425d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (value.empty()) 426d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return std::string(); 427d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 428d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch DCHECK(value[0] == '/'); 429d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t begin_index = 1; 430d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 431d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // If the input begins with two slashes, skip over both (this is a 432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // source-relative dir). These must be forward slashes only. 433d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (value.size() > 1 && value[1] == '/') 434d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch begin_index = 2; 435d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 436d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::string ret; 437d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = begin_index; i < value.size(); i++) { 438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsSlash(value[i])) 439d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ret.append("../"); 440d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 441d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ret; 442d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 443d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 444d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid NormalizePath(std::string* path) { 445d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch char* pathbuf = path->empty() ? NULL : &(*path)[0]; 446d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 447d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // top_index is the first character we can modify in the path. Anything 448d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // before this indicates where the path is relative to. 449d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t top_index = 0; 450d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch bool is_relative = true; 451d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!path->empty() && pathbuf[0] == '/') { 452d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch is_relative = false; 453d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 454d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (path->size() > 1 && pathbuf[1] == '/') { 455d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Two leading slashes, this is a path into the source dir. 456d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch top_index = 2; 457d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 458d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // One leading slash, this is a system-absolute path. 459d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch top_index = 1; 460d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 461d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 462d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 463d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t dest_i = top_index; 464d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t src_i = top_index; src_i < path->size(); /* nothing */) { 465d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (pathbuf[src_i] == '.') { 466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (src_i == 0 || IsSlash(pathbuf[src_i - 1])) { 467d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Slash followed by a dot, see if it's something special. 468d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t consumed_len; 469d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch switch (ClassifyAfterDot(*path, src_i + 1, &consumed_len)) { 470d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case NOT_A_DIRECTORY: 471d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Copy the dot to the output, it means nothing special. 472d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch pathbuf[dest_i++] = pathbuf[src_i++]; 473d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch break; 474d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case DIRECTORY_CUR: 475d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Current directory, just skip the input. 476d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch src_i += consumed_len; 477d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch break; 478d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case DIRECTORY_UP: 479d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Back up over previous directory component. If we're already 480d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // at the top, preserve the "..". 481d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (dest_i > top_index) { 482d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // The previous char was a slash, remove it. 483d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch dest_i--; 484d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 485d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 486d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (dest_i == top_index) { 487d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (is_relative) { 488d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // We're already at the beginning of a relative input, copy the 489d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // ".." and continue. We need the trailing slash if there was 490d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // one before (otherwise we're at the end of the input). 491d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch pathbuf[dest_i++] = '.'; 492d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch pathbuf[dest_i++] = '.'; 493d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (consumed_len == 3) 494d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch pathbuf[dest_i++] = '/'; 495d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 496d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // This also makes a new "root" that we can't delete by going 497d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // up more levels. Otherwise "../.." would collapse to 498d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // nothing. 499d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch top_index = dest_i; 500d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 501d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Otherwise we're at the beginning of an absolute path. Don't 502d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // allow ".." to go up another level and just eat it. 503d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 504d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Just find the previous slash or the beginning of input. 505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (dest_i > 0 && !IsSlash(pathbuf[dest_i - 1])) 506d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch dest_i--; 507d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 508d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch src_i += consumed_len; 509d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 510d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 511d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Dot not preceeded by a slash, copy it literally. 512d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch pathbuf[dest_i++] = pathbuf[src_i++]; 513d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (IsSlash(pathbuf[src_i])) { 515a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (src_i > 0 && IsSlash(pathbuf[src_i - 1])) { 516d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Two slashes in a row, skip over it. 517d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch src_i++; 518d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Just one slash, copy it, normalizing to foward slash. 520a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pathbuf[dest_i] = '/'; 521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dest_i++; 522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) src_i++; 523d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 524d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 525d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Input nothing special, just copy it. 526d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch pathbuf[dest_i++] = pathbuf[src_i++]; 527d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 528d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 529d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch path->resize(dest_i); 530d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 531d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 532d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid ConvertPathToSystem(std::string* path) { 533d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#if defined(OS_WIN) 534d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < path->size(); i++) { 535d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if ((*path)[i] == '/') 536d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch (*path)[i] = '\\'; 537d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 538d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#endif 539d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 540d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 54168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::string RebaseSourceAbsolutePath(const std::string& input, 54268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const SourceDir& dest_dir) { 54368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CHECK(input.size() >= 2 && input[0] == '/' && input[1] == '/') 54468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << "Input to rebase isn't source-absolute: " << input; 54568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CHECK(dest_dir.is_source_absolute()) 54668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << "Dir to rebase to isn't source-absolute: " << dest_dir.value(); 54768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 54868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& dest = dest_dir.value(); 54968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 55068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Skip the common prefixes of the source and dest as long as they end in 55168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // a [back]slash. 55268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_t common_prefix_len = 2; // The beginning two "//" are always the same. 55368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_t max_common_length = std::min(input.size(), dest.size()); 55468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = common_prefix_len; i < max_common_length; i++) { 555a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsSlash(input[i]) && IsSlash(dest[i])) 55668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) common_prefix_len = i + 1; 55768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) else if (input[i] != dest[i]) 55868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 55968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 56068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 56168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Invert the dest dir starting from the end of the common prefix. 56268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string ret; 56368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = common_prefix_len; i < dest.size(); i++) { 564a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsSlash(dest[i])) 56568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ret.append("../"); 56668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 56768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 56868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Append any remaining unique input. 56968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ret.append(&input[common_prefix_len], input.size() - common_prefix_len); 57068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 57168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If the result is still empty, the paths are the same. 57268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (ret.empty()) 57368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ret.push_back('.'); 57468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 57568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return ret; 57668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string DirectoryWithNoLastSlash(const SourceDir& dir) { 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string ret; 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (dir.value().empty()) { 582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Just keep input the same. 583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (dir.value() == "/") { 584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ret.assign("/."); 585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (dir.value() == "//") { 586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ret.assign("//."); 587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ret.assign(dir.value()); 589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ret.resize(ret.size() - 1); 590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ret; 592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 594a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SourceDir SourceDirForPath(const base::FilePath& source_root, 595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::FilePath& path) { 596a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<base::FilePath::StringType> source_comp = 597a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetPathComponents(source_root); 598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<base::FilePath::StringType> path_comp = 599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetPathComponents(path); 600a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // See if path is inside the source root by looking for each of source root's 602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // components at the beginning of path. 603a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool is_inside_source; 604a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (path_comp.size() < source_comp.size()) { 605a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Too small to fit. 606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_inside_source = false; 607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 608a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_inside_source = true; 609a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t i = 0; i < source_comp.size(); i++) { 610a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!FilesystemStringsEqual(source_comp[i], path_comp[i])) { 611a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_inside_source = false; 612a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 613a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string result_str; 618a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t initial_path_comp_to_use; 619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (is_inside_source) { 620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Construct a source-relative path beginning in // and skip all of the 621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // shared directories. 622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result_str = "//"; 623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) initial_path_comp_to_use = source_comp.size(); 624a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Not inside source code, construct a system-absolute path. 626a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result_str = "/"; 627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) initial_path_comp_to_use = 0; 628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 630a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t i = initial_path_comp_to_use; i < path_comp.size(); i++) { 631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result_str.append(FilePathToUTF8(path_comp[i])); 632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result_str.push_back('/'); 633a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 634a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return SourceDir(result_str); 635a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 636a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 637a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SourceDir SourceDirForCurrentDirectory(const base::FilePath& source_root) { 638a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::FilePath cd; 639a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::GetCurrentDirectory(&cd); 640a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return SourceDirForPath(source_root, cd); 641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 642a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string GetOutputSubdirName(const Label& toolchain_label, bool is_default) { 644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The default toolchain has no subdir. 645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (is_default) 646cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return std::string(); 647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 648cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // For now just assume the toolchain name is always a valid dir name. We may 649cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // want to clean up the in the future. 650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return toolchain_label.name() + "/"; 651cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetToolchainOutputDir(const Settings* settings) { 65403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return settings->toolchain_output_subdir().AsSourceDir( 65503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) settings->build_settings()); 656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 658cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)SourceDir GetToolchainOutputDir(const BuildSettings* build_settings, 659cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const Label& toolchain_label, bool is_default) { 660cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string result = build_settings->build_dir().value(); 661cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) result.append(GetOutputSubdirName(toolchain_label, is_default)); 662cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return SourceDir(SourceDir::SWAP_IN, &result); 663cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 664cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetToolchainGenDir(const Settings* settings) { 66603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return GetToolchainGenDirAsOutputFile(settings).AsSourceDir( 66703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) settings->build_settings()); 66803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 67003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)OutputFile GetToolchainGenDirAsOutputFile(const Settings* settings) { 67103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) OutputFile result(settings->toolchain_output_subdir()); 67203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) result.value().append("gen/"); 67303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return result; 674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 675f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)SourceDir GetToolchainGenDir(const BuildSettings* build_settings, 677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const Label& toolchain_label, bool is_default) { 678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string result = GetToolchainOutputDir( 679cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) build_settings, toolchain_label, is_default).value(); 680cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) result.append("gen/"); 681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return SourceDir(SourceDir::SWAP_IN, &result); 682cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 683cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetOutputDirForSourceDir(const Settings* settings, 685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const SourceDir& source_dir) { 68603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return GetOutputDirForSourceDirAsOutputFile(settings, source_dir).AsSourceDir( 68703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) settings->build_settings()); 68803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 69003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)OutputFile GetOutputDirForSourceDirAsOutputFile(const Settings* settings, 69103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const SourceDir& source_dir) { 69203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) OutputFile result = settings->toolchain_output_subdir(); 69303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) result.value().append("obj/"); 694f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 6956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (source_dir.is_source_absolute()) { 6966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // The source dir is source-absolute, so we trim off the two leading 6976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // slashes to append to the toolchain object directory. 69803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) result.value().append(&source_dir.value()[2], 69903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) source_dir.value().size() - 2); 7006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 70103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return result; 702f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetGenDirForSourceDir(const Settings* settings, 705f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const SourceDir& source_dir) { 70603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return GetGenDirForSourceDirAsOutputFile(settings, source_dir).AsSourceDir( 70703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) settings->build_settings()); 70803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 71003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)OutputFile GetGenDirForSourceDirAsOutputFile(const Settings* settings, 71103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const SourceDir& source_dir) { 71203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) OutputFile result = GetToolchainGenDirAsOutputFile(settings); 713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (source_dir.is_source_absolute()) { 7156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // The source dir should be source-absolute, so we trim off the two leading 7166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // slashes to append to the toolchain object directory. 7176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK(source_dir.is_source_absolute()); 71803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) result.value().append(&source_dir.value()[2], 71903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) source_dir.value().size() - 2); 7206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 72103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return result; 722f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetTargetOutputDir(const Target* target) { 72503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return GetOutputDirForSourceDirAsOutputFile( 72603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target->settings(), target->label().dir()).AsSourceDir( 72703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target->settings()->build_settings()); 72803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 72903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 73003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)OutputFile GetTargetOutputDirAsOutputFile(const Target* target) { 73103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return GetOutputDirForSourceDirAsOutputFile( 73203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target->settings(), target->label().dir()); 733f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 734f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetTargetGenDir(const Target* target) { 73603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return GetTargetGenDirAsOutputFile(target).AsSourceDir( 73703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target->settings()->build_settings()); 73803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 73903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 74003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)OutputFile GetTargetGenDirAsOutputFile(const Target* target) { 74103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return GetGenDirForSourceDirAsOutputFile( 74203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target->settings(), target->label().dir()); 743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 744f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 745f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetCurrentOutputDir(const Scope* scope) { 74603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return GetOutputDirForSourceDirAsOutputFile( 74703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scope->settings(), scope->GetSourceDir()).AsSourceDir( 74803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scope->settings()->build_settings()); 749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 750f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetCurrentGenDir(const Scope* scope) { 752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return GetGenDirForSourceDir(scope->settings(), scope->GetSourceDir()); 753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 754