summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Weber <daniel.weber.dev@gmail.com>2016-08-22 22:26:38 (GMT)
committerDaniel Weber <daniel.weber.dev@gmail.com>2016-08-22 22:26:38 (GMT)
commitc4b09e1e7e1d531a818601be33e0ec8ee18c3cde (patch)
tree53765aa88182d29c3156fd2bea822e660e814127
parent94fc14314501a78b1742e910f7c920188b2753da (diff)
downloadNinja-c4b09e1e7e1d531a818601be33e0ec8ee18c3cde.zip
Ninja-c4b09e1e7e1d531a818601be33e0ec8ee18c3cde.tar.gz
Ninja-c4b09e1e7e1d531a818601be33e0ec8ee18c3cde.tar.bz2
Allow more path components
- 60 instead of 30 path components - 64 instead of 32 backslashes in a path (windows only) Issue: 1161
-rw-r--r--src/build.cc2
-rw-r--r--src/clparser.cc2
-rw-r--r--src/graph.cc4
-rw-r--r--src/includes_normalize-win32.cc2
-rw-r--r--src/manifest_parser.cc6
-rw-r--r--src/ninja.cc4
-rw-r--r--src/util.cc18
-rw-r--r--src/util.h4
-rw-r--r--src/util_test.cc38
9 files changed, 44 insertions, 36 deletions
diff --git a/src/build.cc b/src/build.cc
index b806fb5..5078251 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -918,7 +918,7 @@ bool Builder::ExtractDeps(CommandRunner::Result* result,
deps_nodes->reserve(deps.ins_.size());
for (vector<StringPiece>::iterator i = deps.ins_.begin();
i != deps.ins_.end(); ++i) {
- unsigned int slash_bits;
+ uint64_t slash_bits;
if (!CanonicalizePath(const_cast<char*>(i->str_), &i->len_, &slash_bits,
err))
return false;
diff --git a/src/clparser.cc b/src/clparser.cc
index f73a8c1..c17150b 100644
--- a/src/clparser.cc
+++ b/src/clparser.cc
@@ -90,7 +90,7 @@ bool CLParser::Parse(const string& output, const string& deps_prefix,
#else
// TODO: should this make the path relative to cwd?
normalized = include;
- unsigned int slash_bits;
+ uint64_t slash_bits;
if (!CanonicalizePath(&normalized, &slash_bits, err))
return false;
#endif
diff --git a/src/graph.cc b/src/graph.cc
index f1d9ca2..a5bac1c 100644
--- a/src/graph.cc
+++ b/src/graph.cc
@@ -420,7 +420,7 @@ bool ImplicitDepLoader::LoadDepFile(Edge* edge, const string& path,
return false;
}
- unsigned int unused;
+ uint64_t unused;
if (!CanonicalizePath(const_cast<char*>(depfile.out_.str_),
&depfile.out_.len_, &unused, err))
return false;
@@ -442,7 +442,7 @@ bool ImplicitDepLoader::LoadDepFile(Edge* edge, const string& path,
// Add all its in-edges.
for (vector<StringPiece>::iterator i = depfile.ins_.begin();
i != depfile.ins_.end(); ++i, ++implicit_dep) {
- unsigned int slash_bits;
+ uint64_t slash_bits;
if (!CanonicalizePath(const_cast<char*>(i->str_), &i->len_, &slash_bits,
err))
return false;
diff --git a/src/includes_normalize-win32.cc b/src/includes_normalize-win32.cc
index ca35012..e8a3e0f 100644
--- a/src/includes_normalize-win32.cc
+++ b/src/includes_normalize-win32.cc
@@ -103,7 +103,7 @@ bool IncludesNormalize::Normalize(const string& input, const char* relative_to,
return false;
}
strncpy(copy, input.c_str(), input.size() + 1);
- unsigned int slash_bits;
+ uint64_t slash_bits;
if (!CanonicalizePath(copy, &len, &slash_bits, err))
return false;
StringPiece partially_fixed(copy, len);
diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc
index d6dcf22..2164921 100644
--- a/src/manifest_parser.cc
+++ b/src/manifest_parser.cc
@@ -212,7 +212,7 @@ bool ManifestParser::ParseDefault(string* err) {
do {
string path = eval.Evaluate(env_);
string path_err;
- unsigned int slash_bits; // Unused because this only does lookup.
+ uint64_t slash_bits; // Unused because this only does lookup.
if (!CanonicalizePath(&path, &slash_bits, &path_err))
return lexer_.Error(path_err, err);
if (!state_->AddDefault(path, &path_err))
@@ -342,7 +342,7 @@ bool ManifestParser::ParseEdge(string* err) {
for (size_t i = 0, e = outs.size(); i != e; ++i) {
string path = outs[i].Evaluate(env);
string path_err;
- unsigned int slash_bits;
+ uint64_t slash_bits;
if (!CanonicalizePath(&path, &slash_bits, &path_err))
return lexer_.Error(path_err, err);
if (!state_->AddOut(edge, path, slash_bits)) {
@@ -375,7 +375,7 @@ bool ManifestParser::ParseEdge(string* err) {
for (vector<EvalString>::iterator i = ins.begin(); i != ins.end(); ++i) {
string path = i->Evaluate(env);
string path_err;
- unsigned int slash_bits;
+ uint64_t slash_bits;
if (!CanonicalizePath(&path, &slash_bits, &path_err))
return lexer_.Error(path_err, err);
state_->AddIn(edge, path, slash_bits);
diff --git a/src/ninja.cc b/src/ninja.cc
index 25eafe8..4fb04ad 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -233,7 +233,7 @@ int GuessParallelism() {
/// Returns true if the manifest was rebuilt.
bool NinjaMain::RebuildManifest(const char* input_file, string* err) {
string path = input_file;
- unsigned int slash_bits; // Unused because this path is only used for lookup.
+ uint64_t slash_bits; // Unused because this path is only used for lookup.
if (!CanonicalizePath(&path, &slash_bits, err))
return false;
Node* node = state_.LookupNode(path);
@@ -255,7 +255,7 @@ bool NinjaMain::RebuildManifest(const char* input_file, string* err) {
Node* NinjaMain::CollectTarget(const char* cpath, string* err) {
string path = cpath;
- unsigned int slash_bits;
+ uint64_t slash_bits;
if (!CanonicalizePath(&path, &slash_bits, err))
return NULL;
diff --git a/src/util.cc b/src/util.cc
index e31fd1f..fb57cec 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -90,7 +90,7 @@ void Error(const char* msg, ...) {
fprintf(stderr, "\n");
}
-bool CanonicalizePath(string* path, unsigned int* slash_bits, string* err) {
+bool CanonicalizePath(string* path, uint64_t* slash_bits, string* err) {
METRIC_RECORD("canonicalize str");
size_t len = path->size();
char* str = 0;
@@ -103,19 +103,19 @@ bool CanonicalizePath(string* path, unsigned int* slash_bits, string* err) {
}
#ifdef _WIN32
-static unsigned int ShiftOverBit(int offset, unsigned int bits) {
+static uint64_t ShiftOverBit(int offset, uint64_t bits) {
// e.g. for |offset| == 2:
// | ... 9 8 7 6 5 4 3 2 1 0 |
// \_________________/ \_/
// above below
// So we drop the bit at offset and move above "down" into its place.
- unsigned int above = bits & ~((1 << (offset + 1)) - 1);
- unsigned int below = bits & ((1 << offset) - 1);
+ uint64_t above = bits & ~((1 << (offset + 1)) - 1);
+ uint64_t below = bits & ((1 << offset) - 1);
return (above >> 1) | below;
}
#endif
-bool CanonicalizePath(char* path, size_t* len, unsigned int* slash_bits,
+bool CanonicalizePath(char* path, size_t* len, uint64_t* slash_bits,
string* err) {
// WARNING: this function is performance-critical; please benchmark
// any changes you make to it.
@@ -125,7 +125,7 @@ bool CanonicalizePath(char* path, size_t* len, unsigned int* slash_bits,
return false;
}
- const int kMaxPathComponents = 30;
+ const int kMaxPathComponents = 60;
char* components[kMaxPathComponents];
int component_count = 0;
@@ -135,8 +135,8 @@ bool CanonicalizePath(char* path, size_t* len, unsigned int* slash_bits,
const char* end = start + *len;
#ifdef _WIN32
- unsigned int bits = 0;
- unsigned int bits_mask = 1;
+ uint64_t bits = 0;
+ uint64_t bits_mask = 1;
int bits_offset = 0;
// Convert \ to /, setting a bit in |bits| for each \ encountered.
for (char* c = path; c < end; ++c) {
@@ -150,7 +150,7 @@ bool CanonicalizePath(char* path, size_t* len, unsigned int* slash_bits,
bits_offset++;
}
}
- if (bits_offset > 32) {
+ if (bits_offset > 64) {
*err = "too many path components";
return false;
}
diff --git a/src/util.h b/src/util.h
index cbdc1a6..846cd93 100644
--- a/src/util.h
+++ b/src/util.h
@@ -43,8 +43,8 @@ void Error(const char* msg, ...);
/// Canonicalize a path like "foo/../bar.h" into just "bar.h".
/// |slash_bits| has bits set starting from lowest for a backslash that was
/// normalized to a forward slash. (only used on Windows)
-bool CanonicalizePath(string* path, unsigned int* slash_bits, string* err);
-bool CanonicalizePath(char* path, size_t* len, unsigned int* slash_bits,
+bool CanonicalizePath(string* path, uint64_t* slash_bits, string* err);
+bool CanonicalizePath(char* path, size_t* len, uint64_t* slash_bits,
string* err);
/// Appends |input| to |*result|, escaping according to the whims of either
diff --git a/src/util_test.cc b/src/util_test.cc
index 33a4107..64c2bbf 100644
--- a/src/util_test.cc
+++ b/src/util_test.cc
@@ -19,7 +19,7 @@
namespace {
bool CanonicalizePath(string* path, string* err) {
- unsigned int unused;
+ uint64_t unused;
return ::CanonicalizePath(path, &unused, err);
}
@@ -177,7 +177,7 @@ TEST(CanonicalizePath, PathSamplesWindows) {
TEST(CanonicalizePath, SlashTracking) {
string path;
string err;
- unsigned int slash_bits;
+ uint64_t slash_bits;
path = "foo.h"; err = "";
EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
@@ -263,7 +263,7 @@ TEST(CanonicalizePath, SlashTracking) {
TEST(CanonicalizePath, CanonicalizeNotExceedingLen) {
// Make sure searching \/ doesn't go past supplied len.
char buf[] = "foo/bar\\baz.h\\"; // Last \ past end.
- unsigned int slash_bits;
+ uint64_t slash_bits;
string err;
size_t size = 13;
EXPECT_TRUE(::CanonicalizePath(buf, &size, &slash_bits, &err));
@@ -274,31 +274,39 @@ TEST(CanonicalizePath, CanonicalizeNotExceedingLen) {
TEST(CanonicalizePath, TooManyComponents) {
string path;
string err;
- unsigned int slash_bits;
+ uint64_t slash_bits;
- // 32 is OK.
- path = "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./x.h";
+ // 64 is OK.
+ path = "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./"
+ "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./x.h";
EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
+ EXPECT_EQ(slash_bits, 0x0);
// Backslashes version.
path =
- "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\."
- "\\a\\.\\a\\.\\a\\.\\a\\.\\x.h";
+ "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
+ "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
+ "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
+ "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\x.h";
+
EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
- EXPECT_EQ(slash_bits, 0xffff);
+ printf("%x\n",slash_bits);
+ EXPECT_EQ(slash_bits, 0xffffffffLL);
- // 33 is not.
+ // 65 is not.
err = "";
- path =
- "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/x.h";
+ path = "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./"
+ "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./x/y.h";
EXPECT_FALSE(CanonicalizePath(&path, &slash_bits, &err));
EXPECT_EQ(err, "too many path components");
// Backslashes version.
err = "";
path =
- "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\."
- "\\a\\.\\a\\.\\a\\.\\a\\.\\a\\x.h";
+ "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
+ "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
+ "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
+ "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\x\\y.h";
EXPECT_FALSE(CanonicalizePath(&path, &slash_bits, &err));
EXPECT_EQ(err, "too many path components");
}
@@ -326,7 +334,7 @@ TEST(CanonicalizePath, NotNullTerminated) {
string path;
string err;
size_t len;
- unsigned int unused;
+ uint64_t unused;
path = "foo/. bar/.";
len = strlen("foo/."); // Canonicalize only the part before the space.