29 bool InternalGetFullPathName(
const StringPiece& file_name,
char* buffer,
30 size_t buffer_length,
string *err) {
31 DWORD result_size = GetFullPathNameA(file_name.
AsString().c_str(),
32 buffer_length, buffer, NULL);
33 if (result_size == 0) {
34 *err =
"GetFullPathNameA(" + file_name.
AsString() +
"): " +
37 }
else if (result_size > buffer_length) {
38 *err =
"path too long";
45 return c ==
'/' || c ==
'\\';
64 if (a[1] !=
':' || b[1] !=
':') {
73 if (SameDriveFast(a, b)) {
77 char a_absolute[_MAX_PATH];
78 char b_absolute[_MAX_PATH];
79 if (!InternalGetFullPathName(a, a_absolute,
sizeof(a_absolute), err)) {
82 if (!InternalGetFullPathName(b, b_absolute,
sizeof(b_absolute), err)) {
85 char a_drive[_MAX_DIR];
86 char b_drive[_MAX_DIR];
87 _splitpath(a_absolute, a_drive, NULL, NULL, NULL);
88 _splitpath(b_absolute, b_drive, NULL, NULL, NULL);
89 return _stricmp(a_drive, b_drive) == 0;
104 for (
size_t i = 2; i < s.
size(); ++i) {
110 if (i + 1 < s.
size() && s[i+1] ==
'.' &&
116 if (i + 2 < s.
size() && s[i+1] ==
'.' && s[i+2] ==
'.' &&
131 Fatal(
"Initializing IncludesNormalize(): %s", err.c_str());
137 if (IsFullPathName(s)) {
139 for (
size_t i = 0; i < result.size(); ++i) {
140 if (result[i] ==
'\\') {
147 char result[_MAX_PATH];
148 if (!InternalGetFullPathName(s, result,
sizeof(result), err)) {
151 for (
char* c = result; *c; ++c)
158 StringPiece path,
const vector<StringPiece>& start_list,
string* err) {
159 string abs_path =
AbsPath(path, err);
164 for (i = 0; i < static_cast<int>(min(start_list.size(), path_list.size()));
171 vector<StringPiece> rel_list;
172 rel_list.reserve(start_list.size() - i + path_list.size() - i);
173 for (
int j = 0; j < static_cast<int>(start_list.size() - i); ++j)
174 rel_list.push_back(
"..");
175 for (
int j = i; j < static_cast<int>(path_list.size()); ++j)
176 rel_list.push_back(path_list[j]);
177 if (rel_list.size() == 0)
183 string* result,
string* err)
const {
184 char copy[_MAX_PATH + 1];
185 size_t len = input.size();
186 if (len > _MAX_PATH) {
187 *err =
"path too long";
190 strncpy(copy, input.c_str(), input.size() + 1);
195 string abs_input =
AbsPath(partially_fixed, err);
202 *result = partially_fixed.
AsString();
vector< StringPiece > SplitStringPiece(StringPiece input, char sep)
static bool IsPathSeparator(char c)
bool CanonicalizePath(string *path, uint64_t *slash_bits, string *err)
Canonicalize a path like "foo/../bar.h" into just "bar.h".
StringPiece represents a slice of a string whose memory is managed externally.
static string Relativize(StringPiece path, const vector< StringPiece > &start_list, string *err)
bool Normalize(const string &input, string *result, string *err) const
Normalize by fixing slashes style, fixing redundant .
vector< StringPiece > split_relative_to_
IncludesNormalize(const string &relative_to)
Normalize path relative to |relative_to|.
static string AbsPath(StringPiece s, string *err)
void Fatal(const char *msg,...)
Log a fatal message and exit.
string JoinStringPiece(const vector< StringPiece > &list, char sep)
char ToLowerASCII(char c)
unsigned long long uint64_t
bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b)
string AsString() const
Convert the slice into a full-fledged std::string, copying the data into a new string.