31 bool InternalGetFullPathName(
const StringPiece& file_name,
char* buffer,
32 size_t buffer_length,
string *err) {
33 DWORD result_size = GetFullPathNameA(file_name.
AsString().c_str(),
34 buffer_length, buffer, NULL);
35 if (result_size == 0) {
36 *err =
"GetFullPathNameA(" + file_name.
AsString() +
"): " +
39 }
else if (result_size > buffer_length) {
40 *err =
"path too long";
47 return c ==
'/' || c ==
'\\';
66 if (a[1] !=
':' || b[1] !=
':') {
75 if (SameDriveFast(a, b)) {
79 char a_absolute[_MAX_PATH];
80 char b_absolute[_MAX_PATH];
81 if (!InternalGetFullPathName(a, a_absolute,
sizeof(a_absolute), err)) {
84 if (!InternalGetFullPathName(b, b_absolute,
sizeof(b_absolute), err)) {
87 char a_drive[_MAX_DIR];
88 char b_drive[_MAX_DIR];
89 _splitpath(a_absolute, a_drive, NULL, NULL, NULL);
90 _splitpath(b_absolute, b_drive, NULL, NULL, NULL);
91 return _stricmp(a_drive, b_drive) == 0;
106 for (
size_t i = 2; i < s.
size(); ++i) {
112 if (i + 1 < s.
size() && s[i+1] ==
'.' &&
118 if (i + 2 < s.
size() && s[i+1] ==
'.' && s[i+2] ==
'.' &&
131 relative_to_ = AbsPath(relative_to, &err);
133 Fatal(
"Initializing IncludesNormalize(): %s", err.c_str());
139 if (IsFullPathName(s)) {
141 for (
size_t i = 0; i < result.size(); ++i) {
142 if (result[i] ==
'\\') {
149 char result[_MAX_PATH];
150 if (!InternalGetFullPathName(s, result,
sizeof(result), err)) {
153 for (
char* c = result; *c; ++c)
160 StringPiece path,
const vector<StringPiece>& start_list,
string* err) {
161 string abs_path = AbsPath(path, err);
166 for (i = 0; i < static_cast<int>(min(start_list.size(), path_list.size()));
173 vector<StringPiece> rel_list;
174 rel_list.reserve(start_list.size() - i + path_list.size() - i);
175 for (
int j = 0; j < static_cast<int>(start_list.size() - i); ++j)
176 rel_list.push_back(
"..");
177 for (
int j = i; j < static_cast<int>(path_list.size()); ++j)
178 rel_list.push_back(path_list[j]);
179 if (rel_list.size() == 0)
185 string* result,
string* err)
const {
186 char copy[_MAX_PATH + 1];
187 size_t len = input.size();
188 if (len > _MAX_PATH) {
189 *err =
"path too long";
192 strncpy(copy, input.c_str(), input.size() + 1);
196 string abs_input = AbsPath(partially_fixed, err);
200 if (!SameDrive(abs_input, relative_to_, err)) {
203 *result = partially_fixed.
AsString();
206 *result = Relativize(abs_input, split_relative_to_, err);
vector< StringPiece > SplitStringPiece(StringPiece input, char sep)
string JoinStringPiece(const vector< StringPiece > &list, char sep)
bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b)
char ToLowerASCII(char c)
static std::string AbsPath(StringPiece s, std::string *err)
bool Normalize(const std::string &input, std::string *result, std::string *err) const
Normalize by fixing slashes style, fixing redundant .
static std::string Relativize(StringPiece path, const std::vector< StringPiece > &start_list, std::string *err)
IncludesNormalize(const std::string &relative_to)
Normalize path relative to |relative_to|.
StringPiece represents a slice of a string whose memory is managed externally.
std::string AsString() const
Convert the slice into a full-fledged std::string, copying the data into a new string.
static bool IsPathSeparator(char c)
void CanonicalizePath(string *path, uint64_t *slash_bits)
void Fatal(const char *msg,...)
Log a fatal message and exit.
unsigned long long uint64_t