1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TOOLS_GN_SOURCE_DIR_H_
#define TOOLS_GN_SOURCE_DIR_H_
#include <algorithm>
#include <string>
#include "base/containers/hash_tables.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/strings/string_piece.h"
class Err;
class SourceFile;
class Value;
// Represents a directory within the source tree. Source dirs begin and end in
// slashes.
//
// If there is one slash at the beginning, it will mean a system-absolute file
// path. On Windows, absolute system paths will be of the form "/C:/foo/bar".
//
// Two slashes at the beginning indicate a path relative to the source root.
class SourceDir {
public:
enum SwapIn { SWAP_IN };
SourceDir();
explicit SourceDir(const base::StringPiece& p);
// Swaps the given string in without copies. The given string will be empty
// after this call.
SourceDir(SwapIn, std::string* s);
~SourceDir();
// Resolves a file or dir name relative to this source directory. Will return
// an empty SourceDir/File on error and set the give *err pointer (required).
// Empty input is always an error.
//
// If source_root is supplied, these functions will additionally handle the
// case where the input is a system-absolute but still inside the source
// tree. This is the case for some external tools.
SourceFile ResolveRelativeFile(
const Value& p,
Err* err,
const base::StringPiece& source_root = base::StringPiece()) const;
SourceDir ResolveRelativeDir(
const Value& p,
Err* err,
const base::StringPiece& source_root = base::StringPiece()) const;
// Like ResolveRelativeDir but takes a separate value (which gets blamed)
// and string to use (in cases where a substring has been extracted from the
// value, as with label resolution).
SourceDir ResolveRelativeDir(
const Value& blame_but_dont_use,
const base::StringPiece& p,
Err* err,
const base::StringPiece& source_root = base::StringPiece()) const;
// Resolves this source file relative to some given source root. Returns
// an empty file path on error.
base::FilePath Resolve(const base::FilePath& source_root) const;
bool is_null() const { return value_.empty(); }
const std::string& value() const { return value_; }
// Returns true if this path starts with a "//" which indicates a path
// from the source root.
bool is_source_absolute() const {
return value_.size() >= 2 && value_[0] == '/' && value_[1] == '/';
}
// Returns true if this path starts with a single slash which indicates a
// system-absolute path.
bool is_system_absolute() const {
return !is_source_absolute();
}
// Returns a source-absolute path starting with only one slash at the
// beginning (normally source-absolute paths start with two slashes to mark
// them as such). This is normally used when concatenating directories
// together.
//
// This function asserts that the directory is actually source-absolute. The
// return value points into our buffer.
base::StringPiece SourceAbsoluteWithOneSlash() const {
CHECK(is_source_absolute());
return base::StringPiece(&value_[1], value_.size() - 1);
}
void SwapValue(std::string* v);
bool operator==(const SourceDir& other) const {
return value_ == other.value_;
}
bool operator!=(const SourceDir& other) const {
return !operator==(other);
}
bool operator<(const SourceDir& other) const {
return value_ < other.value_;
}
void swap(SourceDir& other) {
value_.swap(other.value_);
}
private:
friend class SourceFile;
std::string value_;
// Copy & assign supported.
};
namespace BASE_HASH_NAMESPACE {
template<> struct hash<SourceDir> {
std::size_t operator()(const SourceDir& v) const {
hash<std::string> h;
return h(v.value());
}
};
} // namespace BASE_HASH_NAMESPACE
inline void swap(SourceDir& lhs, SourceDir& rhs) {
lhs.swap(rhs);
}
#endif // TOOLS_GN_SOURCE_DIR_H_
|