filesystem_utils.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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) 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/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) 102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Check drive letter 103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!((path[0] >= 'A' && path[0] <= 'Z') || 104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) path[0] >= 'a' && path[0] <= 'z')) 105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!IsSlash(path[2])) 108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 110424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif 112424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// A wrapper around FilePath.GetComponents that works the way we need. This is 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// not super efficient since it does some O(n) transformations on the path. If 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// this is called a lot, we might want to optimize. 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::vector<base::FilePath::StringType> GetPathComponents( 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::FilePath& path) { 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<base::FilePath::StringType> result; 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) path.GetComponents(&result); 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (result.empty()) 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return result; 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // GetComponents will preserve the "/" at the beginning, which confuses us. 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We don't expect to have relative paths in this function. 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Don't use IsSeparator since we always want to allow backslashes. 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (result[0] == FILE_PATH_LITERAL("/") || 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result[0] == FILE_PATH_LITERAL("\\")) 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result.erase(result.begin()); 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_WIN) 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // On Windows, GetComponents will give us [ "C:", "/", "foo" ], and we 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // don't want the slash in there. This doesn't support input like "C:foo" 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // which means foo relative to the current directory of the C drive but 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // that's basically legacy DOS behavior we don't need to support. 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (result.size() >= 2 && result[1].size() == 1 && IsSlash(result[1][0])) 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result.erase(result.begin() + 1); 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return result; 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Provides the equivalent of == for filesystem strings, trying to do 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// approximately the right thing with case. 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool FilesystemStringsEqual(const base::FilePath::StringType& a, 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::FilePath::StringType& b) { 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_WIN) 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Assume case-insensitive filesystems on Windows. We use the CompareString 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // function to do a case-insensitive comparison based on the current locale 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // (we don't want GN to depend on ICU which is large and requires data 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // files). This isn't perfect, but getting this perfectly right is very 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // difficult and requires I/O, and this comparison should cover 99.9999% of 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // all cases. 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Note: The documentation for CompareString says it runs fastest on 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // null-terminated strings with -1 passed for the length, so we do that here. 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There should not be embedded nulls in filesystem strings. 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return ::CompareString(LOCALE_USER_DEFAULT, LINGUISTIC_IGNORECASE, 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) a.c_str(), -1, b.c_str(), -1) == CSTR_EQUAL; 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#else 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Assume case-sensitive filesystems on non-Windows. 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return a == b; 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace 167d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochSourceFileType GetSourceFileType(const SourceFile& file) { 169d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::StringPiece extension = FindExtension(&file.value()); 170d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (extension == "cc" || extension == "cpp" || extension == "cxx") 171d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return SOURCE_CC; 172d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (extension == "h") 173d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return SOURCE_H; 174d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (extension == "c") 175d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return SOURCE_C; 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (extension == "m") 177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return SOURCE_M; 178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (extension == "mm") 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return SOURCE_MM; 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (extension == "rc") 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return SOURCE_RC; 1820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (extension == "S" || extension == "s") 183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return SOURCE_S; 1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 185d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return SOURCE_UNKNOWN; 186d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 187d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 188d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char* GetExtensionForOutputType(Target::OutputType type, 189d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Settings::TargetOS os) { 190d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch switch (os) { 1912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch case Settings::MAC: 1922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch switch (type) { 1932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch case Target::EXECUTABLE: 1942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return ""; 1952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch case Target::SHARED_LIBRARY: 1962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return "dylib"; 1972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch case Target::STATIC_LIBRARY: 1982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return "a"; 1992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch default: 2002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch NOTREACHED(); 2012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 2022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch break; 2032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 204d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case Settings::WIN: 205d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch switch (type) { 206d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case Target::EXECUTABLE: 207d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "exe"; 208d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case Target::SHARED_LIBRARY: 209d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "dll.lib"; // Extension of import library. 210d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case Target::STATIC_LIBRARY: 211d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "lib"; 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case Settings::LINUX: 2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (type) { 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case Target::EXECUTABLE: 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return ""; 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case Target::SHARED_LIBRARY: 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "so"; 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case Target::STATIC_LIBRARY: 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "a"; 225d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch default: 226d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch NOTREACHED(); 227d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 228d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch break; 229d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 230d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch default: 231d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch NOTREACHED(); 232d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 233d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ""; 234d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 235d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::string FilePathToUTF8(const base::FilePath::StringType& str) { 237d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#if defined(OS_WIN) 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::WideToUTF8(str); 239d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#else 24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return str; 241d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#endif 242d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 243d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 244d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbase::FilePath UTF8ToFilePath(const base::StringPiece& sp) { 245d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#if defined(OS_WIN) 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::FilePath(base::UTF8ToWide(sp)); 247d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#else 248d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::FilePath(sp.as_string()); 249d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#endif 250d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 251d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 252d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochsize_t FindExtensionOffset(const std::string& path) { 253d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (int i = static_cast<int>(path.size()); i >= 0; i--) { 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsSlash(path[i])) 255d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch break; 256d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (path[i] == '.') 257d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return i + 1; 258d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 259d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return std::string::npos; 260d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 261d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 262d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbase::StringPiece FindExtension(const std::string* path) { 263d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t extension_offset = FindExtensionOffset(*path); 264d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (extension_offset == std::string::npos) 265d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(); 266d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(&path->data()[extension_offset], 267d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch path->size() - extension_offset); 268d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 269d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 270d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochsize_t FindFilenameOffset(const std::string& path) { 271d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (int i = static_cast<int>(path.size()) - 1; i >= 0; i--) { 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsSlash(path[i])) 273d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return i + 1; 274d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 275d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return 0; // No filename found means everything was the filename. 276d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 277d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 278d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbase::StringPiece FindFilename(const std::string* path) { 279d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t filename_offset = FindFilenameOffset(*path); 280d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (filename_offset == 0) 281d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(*path); // Everything is the file name. 282d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(&(*path).data()[filename_offset], 283d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch path->size() - filename_offset); 284d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 285d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 286d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbase::StringPiece FindFilenameNoExtension(const std::string* path) { 287d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (path->empty()) 288d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(); 289d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t filename_offset = FindFilenameOffset(*path); 290d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t extension_offset = FindExtensionOffset(*path); 291d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 292d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t name_len; 293d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (extension_offset == std::string::npos) 294d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch name_len = path->size() - filename_offset; 295d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch else 296d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch name_len = extension_offset - filename_offset - 1; 297d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 298d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(&(*path).data()[filename_offset], name_len); 299d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 300d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 301d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid RemoveFilename(std::string* path) { 302d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch path->resize(FindFilenameOffset(*path)); 303d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 304d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 305d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool EndsWithSlash(const std::string& s) { 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return !s.empty() && IsSlash(s[s.size() - 1]); 307d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 308d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 309d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbase::StringPiece FindDir(const std::string* path) { 310d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t filename_offset = FindFilenameOffset(*path); 311d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (filename_offset == 0u) 312d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(); 313d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base::StringPiece(path->data(), filename_offset); 314d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 315d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 316d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool EnsureStringIsInOutputDir(const SourceDir& dir, 317d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& str, 318d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Value& originating, 319d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 320d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // The last char of the dir will be a slash. We don't care if the input ends 321d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // in a slash or not, so just compare up until there. 322d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // 323d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // This check will be wrong for all proper prefixes "e.g. "/output" will 324d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // match "/out" but we don't really care since this is just a sanity check. 325d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& dir_str = dir.value(); 326d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (str.compare(0, dir_str.length() - 1, dir_str, 0, dir_str.length() - 1) 327d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch != 0) { 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *err = Err(originating, "File is not inside output directory.", 329d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "The given file should be in the output directory. Normally you would " 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "specify\n\"$target_out_dir/foo\" or " 331d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "\"$target_gen_dir/foo\". I interpreted this as\n\"" 332d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch + str + "\"."); 333d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 334d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 335d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return true; 336d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 337d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool IsPathAbsolute(const base::StringPiece& path) { 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (path.empty()) 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!IsSlash(path[0])) { 3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_WIN) 3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Check for Windows system paths like "C:\foo". 345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (path.size() > 2 && path[1] == ':' && IsSlash(path[2])) 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; // Doesn't begin with a slash, is relative. 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Double forward slash at the beginning means source-relative (we don't 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // allow backslashes for denoting this). 3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (path.size() > 1 && path[1] == '/') 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MakeAbsolutePathRelativeIfPossible(const base::StringPiece& source_root, 3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::StringPiece& path, 3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* dest) { 3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(IsPathAbsolute(source_root)); 3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(IsPathAbsolute(path)); 3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dest->clear(); 3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (source_root.size() > path.size()) 3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; // The source root is longer: the path can never be inside. 3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_WIN) 371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Source root should be canonical on Windows. Note that the initial slash 372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // must be forward slash, but that the other ones can be either forward or 373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // backward. 3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(source_root.size() > 2 && source_root[0] != '/' && 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) source_root[1] == ':' && IsSlash(source_root[2])); 376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 377424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t after_common_index = std::string::npos; 378424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (DoesBeginWindowsDriveLetter(path)) { 379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Handle "C:\foo" 380424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (AreAbsoluteWindowsPathsEqual(source_root, 381424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) path.substr(0, source_root.size()))) 382424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) after_common_index = source_root.size(); 383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else 384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 385424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else if (path[0] == '/' && source_root.size() <= path.size() - 1 && 386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DoesBeginWindowsDriveLetter(path.substr(1))) { 387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Handle "/C:/foo" 388424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (AreAbsoluteWindowsPathsEqual(source_root, 389424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) path.substr(1, source_root.size()))) 390424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) after_common_index = source_root.size() + 1; 391424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else 392424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 393424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 394424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 395424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 396424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If we get here, there's a match and after_common_index identifies the 398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // part after it. 399424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 400424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // The base may or may not have a trailing slash, so skip all slashes from 401424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // the path after our prefix match. 402424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t first_after_slash = after_common_index; 403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (first_after_slash < path.size() && IsSlash(path[first_after_slash])) 404424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) first_after_slash++; 405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 406424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dest->assign("//"); // Result is source root relative. 407424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dest->append(&path.data()[first_after_slash], 408424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) path.size() - first_after_slash); 409424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 410424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#else 412424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // On non-Windows this is easy. Since we know both are absolute, just do a 4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // prefix check. 4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (path.substr(0, source_root.size()) == source_root) { 4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The base may or may not have a trailing slash, so skip all slashes from 4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the path after our prefix match. 4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t first_after_slash = source_root.size(); 419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (first_after_slash < path.size() && IsSlash(path[first_after_slash])) 4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) first_after_slash++; 4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 422424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dest->assign("//"); // Result is source root relative. 4233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dest->append(&path.data()[first_after_slash], 4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) path.size() - first_after_slash); 4253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 428424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif 4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 431d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochstd::string InvertDir(const SourceDir& path) { 432d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string value = path.value(); 433d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (value.empty()) 434d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return std::string(); 435d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 436d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch DCHECK(value[0] == '/'); 437d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t begin_index = 1; 438d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 439d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // If the input begins with two slashes, skip over both (this is a 440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // source-relative dir). These must be forward slashes only. 441d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (value.size() > 1 && value[1] == '/') 442d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch begin_index = 2; 443d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 444d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::string ret; 445d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = begin_index; i < value.size(); i++) { 446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsSlash(value[i])) 447d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ret.append("../"); 448d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 449d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ret; 450d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 451d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 452d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid NormalizePath(std::string* path) { 453d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch char* pathbuf = path->empty() ? NULL : &(*path)[0]; 454d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 455d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // top_index is the first character we can modify in the path. Anything 456d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // before this indicates where the path is relative to. 457d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t top_index = 0; 458d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch bool is_relative = true; 459d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!path->empty() && pathbuf[0] == '/') { 460d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch is_relative = false; 461d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 462d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (path->size() > 1 && pathbuf[1] == '/') { 463d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Two leading slashes, this is a path into the source dir. 464d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch top_index = 2; 465d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 466d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // One leading slash, this is a system-absolute path. 467d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch top_index = 1; 468d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 469d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 470d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 471d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t dest_i = top_index; 472d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t src_i = top_index; src_i < path->size(); /* nothing */) { 473d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (pathbuf[src_i] == '.') { 474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (src_i == 0 || IsSlash(pathbuf[src_i - 1])) { 475d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Slash followed by a dot, see if it's something special. 476d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t consumed_len; 477d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch switch (ClassifyAfterDot(*path, src_i + 1, &consumed_len)) { 478d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case NOT_A_DIRECTORY: 479d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Copy the dot to the output, it means nothing special. 480d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch pathbuf[dest_i++] = pathbuf[src_i++]; 481d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch break; 482d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case DIRECTORY_CUR: 483d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Current directory, just skip the input. 484d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch src_i += consumed_len; 485d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch break; 486d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case DIRECTORY_UP: 487d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Back up over previous directory component. If we're already 488d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // at the top, preserve the "..". 489d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (dest_i > top_index) { 490d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // The previous char was a slash, remove it. 491d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch dest_i--; 492d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 493d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 494d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (dest_i == top_index) { 495d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (is_relative) { 496d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // We're already at the beginning of a relative input, copy the 497d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // ".." and continue. We need the trailing slash if there was 498d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // one before (otherwise we're at the end of the input). 499d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch pathbuf[dest_i++] = '.'; 500d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch pathbuf[dest_i++] = '.'; 501d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (consumed_len == 3) 502d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch pathbuf[dest_i++] = '/'; 503d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 504d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // This also makes a new "root" that we can't delete by going 505d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // up more levels. Otherwise "../.." would collapse to 506d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // nothing. 507d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch top_index = dest_i; 508d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 509d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Otherwise we're at the beginning of an absolute path. Don't 510d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // allow ".." to go up another level and just eat it. 511d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 512d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Just find the previous slash or the beginning of input. 513a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (dest_i > 0 && !IsSlash(pathbuf[dest_i - 1])) 514d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch dest_i--; 515d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 516d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch src_i += consumed_len; 517d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 518d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 519d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Dot not preceeded by a slash, copy it literally. 520d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch pathbuf[dest_i++] = pathbuf[src_i++]; 521d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (IsSlash(pathbuf[src_i])) { 523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (src_i > 0 && IsSlash(pathbuf[src_i - 1])) { 524d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Two slashes in a row, skip over it. 525d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch src_i++; 526d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 527a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Just one slash, copy it, normalizing to foward slash. 528a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pathbuf[dest_i] = '/'; 529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dest_i++; 530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) src_i++; 531d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 532d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 533d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Input nothing special, just copy it. 534d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch pathbuf[dest_i++] = pathbuf[src_i++]; 535d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 536d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 537d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch path->resize(dest_i); 538d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 539d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 540d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid ConvertPathToSystem(std::string* path) { 541d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#if defined(OS_WIN) 542d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < path->size(); i++) { 543d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if ((*path)[i] == '/') 544d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch (*path)[i] = '\\'; 545d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 546d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#endif 547d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 548d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 54968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::string RebaseSourceAbsolutePath(const std::string& input, 55068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const SourceDir& dest_dir) { 55168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CHECK(input.size() >= 2 && input[0] == '/' && input[1] == '/') 55268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << "Input to rebase isn't source-absolute: " << input; 55368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CHECK(dest_dir.is_source_absolute()) 55468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << "Dir to rebase to isn't source-absolute: " << dest_dir.value(); 55568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 55668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& dest = dest_dir.value(); 55768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 55868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Skip the common prefixes of the source and dest as long as they end in 55968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // a [back]slash. 56068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_t common_prefix_len = 2; // The beginning two "//" are always the same. 56168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_t max_common_length = std::min(input.size(), dest.size()); 56268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = common_prefix_len; i < max_common_length; i++) { 563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsSlash(input[i]) && IsSlash(dest[i])) 56468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) common_prefix_len = i + 1; 56568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) else if (input[i] != dest[i]) 56668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 56768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 56868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 56968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Invert the dest dir starting from the end of the common prefix. 57068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string ret; 57168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = common_prefix_len; i < dest.size(); i++) { 572a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsSlash(dest[i])) 57368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ret.append("../"); 57468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 57568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 57668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Append any remaining unique input. 57768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ret.append(&input[common_prefix_len], input.size() - common_prefix_len); 57868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 57968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If the result is still empty, the paths are the same. 58068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (ret.empty()) 58168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ret.push_back('.'); 58268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 58368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return ret; 58468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string DirectoryWithNoLastSlash(const SourceDir& dir) { 587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string ret; 588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (dir.value().empty()) { 590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Just keep input the same. 591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (dir.value() == "/") { 592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ret.assign("/."); 593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (dir.value() == "//") { 594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ret.assign("//."); 595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ret.assign(dir.value()); 597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ret.resize(ret.size() - 1); 598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ret; 600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SourceDir SourceDirForPath(const base::FilePath& source_root, 603a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::FilePath& path) { 604a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<base::FilePath::StringType> source_comp = 605a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetPathComponents(source_root); 606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<base::FilePath::StringType> path_comp = 607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetPathComponents(path); 608a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 609a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // See if path is inside the source root by looking for each of source root's 610a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // components at the beginning of path. 611a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool is_inside_source; 612a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (path_comp.size() < source_comp.size()) { 613a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Too small to fit. 614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_inside_source = false; 615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_inside_source = true; 617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t i = 0; i < source_comp.size(); i++) { 618a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!FilesystemStringsEqual(source_comp[i], path_comp[i])) { 619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_inside_source = false; 620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 624a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string result_str; 626a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t initial_path_comp_to_use; 627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (is_inside_source) { 628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Construct a source-relative path beginning in // and skip all of the 629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // shared directories. 630a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result_str = "//"; 631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) initial_path_comp_to_use = source_comp.size(); 632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 633a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Not inside source code, construct a system-absolute path. 634a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result_str = "/"; 635a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) initial_path_comp_to_use = 0; 636a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 637a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 638a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t i = initial_path_comp_to_use; i < path_comp.size(); i++) { 639a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result_str.append(FilePathToUTF8(path_comp[i])); 640a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result_str.push_back('/'); 641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 642a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return SourceDir(result_str); 643a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 644a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SourceDir SourceDirForCurrentDirectory(const base::FilePath& source_root) { 646a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::FilePath cd; 647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::GetCurrentDirectory(&cd); 648a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return SourceDirForPath(source_root, cd); 649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 650a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetToolchainOutputDir(const Settings* settings) { 652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const OutputFile& toolchain_subdir = settings->toolchain_output_subdir(); 653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string result = settings->build_settings()->build_dir().value(); 655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!toolchain_subdir.value().empty()) 656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) result.append(toolchain_subdir.value()); 657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SourceDir(SourceDir::SWAP_IN, &result); 659f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetToolchainGenDir(const Settings* settings) { 662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const OutputFile& toolchain_subdir = settings->toolchain_output_subdir(); 663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string result = settings->build_settings()->build_dir().value(); 665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!toolchain_subdir.value().empty()) 666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) result.append(toolchain_subdir.value()); 667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) result.append("gen/"); 669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SourceDir(SourceDir::SWAP_IN, &result); 670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetOutputDirForSourceDir(const Settings* settings, 673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const SourceDir& source_dir) { 674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SourceDir toolchain = GetToolchainOutputDir(settings); 675f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string ret; 677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) toolchain.SwapValue(&ret); 678f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ret.append("obj/"); 679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 680f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The source dir should be source-absolute, so we trim off the two leading 681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // slashes to append to the toolchain object directory. 682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(source_dir.is_source_absolute()); 683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ret.append(&source_dir.value()[2], source_dir.value().size() - 2); 684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SourceDir(SourceDir::SWAP_IN, &ret); 686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 688f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetGenDirForSourceDir(const Settings* settings, 689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const SourceDir& source_dir) { 690f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SourceDir toolchain = GetToolchainGenDir(settings); 691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 692f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string ret; 693f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) toolchain.SwapValue(&ret); 694f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 695f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The source dir should be source-absolute, so we trim off the two leading 696f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // slashes to append to the toolchain object directory. 697f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(source_dir.is_source_absolute()); 698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ret.append(&source_dir.value()[2], source_dir.value().size() - 2); 699f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SourceDir(SourceDir::SWAP_IN, &ret); 701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 702f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetTargetOutputDir(const Target* target) { 704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return GetOutputDirForSourceDir(target->settings(), target->label().dir()); 705f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 706f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 707f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetTargetGenDir(const Target* target) { 708f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return GetGenDirForSourceDir(target->settings(), target->label().dir()); 709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetCurrentOutputDir(const Scope* scope) { 712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return GetOutputDirForSourceDir(scope->settings(), scope->GetSourceDir()); 713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 714f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SourceDir GetCurrentGenDir(const Scope* scope) { 716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return GetGenDirForSourceDir(scope->settings(), scope->GetSourceDir()); 717f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 718