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#ifndef TOOLS_GN_SOURCE_FILE_H_
6d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#define TOOLS_GN_SOURCE_FILE_H_
7d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <algorithm>
9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include <string>
10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/containers/hash_tables.h"
12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/files/file_path.h"
13d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/logging.h"
14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/strings/string_piece.h"
15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
16d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochclass SourceDir;
17d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
18d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Represents a file within the source tree. Always begins in a slash, never
19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// ends in one.
20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochclass SourceFile {
21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch public:
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  enum SwapIn { SWAP_IN };
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
24d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  SourceFile();
25d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
26d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Takes a known absolute source file. Always begins in a slash.
27d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  explicit SourceFile(const base::StringPiece& p);
28d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Constructs from the given string by swapping in the contents of the given
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // value. The value will be the empty string after this call.
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SourceFile(SwapIn, std::string* value);
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
33d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  ~SourceFile();
34d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
35d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  bool is_null() const { return value_.empty(); }
36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const std::string& value() const { return value_; }
37d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns everything after the last slash.
39d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  std::string GetName() const;
40d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  SourceDir GetDir() const;
41d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
42d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Resolves this source file relative to some given source root. Returns
43d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // an empty file path on error.
44d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  base::FilePath Resolve(const base::FilePath& source_root) const;
45d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
46d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Returns true if this file starts with a "//" which indicates a path
47d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // from the source root.
48d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  bool is_source_absolute() const {
49d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return value_.size() >= 2 && value_[0] == '/' && value_[1] == '/';
50d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
51d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
52d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Returns true if this file starts with a single slash which indicates a
53d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // system-absolute path.
54d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  bool is_system_absolute() const {
55d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return !is_source_absolute();
56d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
57d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Returns a source-absolute path starting with only one slash at the
59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // beginning (normally source-absolute paths start with two slashes to mark
60d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // them as such). This is normally used when concatenating names together.
61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  //
62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // This function asserts that the file is actually source-absolute. The
63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // return value points into our buffer.
64d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  base::StringPiece SourceAbsoluteWithOneSlash() const {
65d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    CHECK(is_source_absolute());
66d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return base::StringPiece(&value_[1], value_.size() - 1);
67d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
68d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
69d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  bool operator==(const SourceFile& other) const {
70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return value_ == other.value_;
71d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
72d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  bool operator!=(const SourceFile& other) const {
73d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return !operator==(other);
74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
75d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  bool operator<(const SourceFile& other) const {
76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return value_ < other.value_;
77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void swap(SourceFile& other) {
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    value_.swap(other.value_);
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch private:
84d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  friend class SourceDir;
85d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
86d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  std::string value_;
87d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
88d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Copy & assign supported.
89d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch};
90d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
91d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochnamespace BASE_HASH_NAMESPACE {
92d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
93d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#if defined(COMPILER_GCC)
94d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochtemplate<> struct hash<SourceFile> {
95d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  std::size_t operator()(const SourceFile& v) const {
96d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    hash<std::string> h;
97d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return h(v.value());
98d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
99d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch};
100d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#elif defined(COMPILER_MSVC)
101d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochinline size_t hash_value(const SourceFile& v) {
102d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return hash_value(v.value());
103d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
104d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#endif  // COMPILER...
105d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
106d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}  // namespace BASE_HASH_NAMESPACE
107d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)inline void swap(SourceFile& lhs, SourceFile& rhs) {
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  lhs.swap(rhs);
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
112d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#endif  // TOOLS_GN_SOURCE_FILE_H_
113