summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2017-01-24 19:03:50 (GMT)
committerGitHub <noreply@github.com>2017-01-24 19:03:50 (GMT)
commit2993752dd617ada5218836dd6545fb06690e238b (patch)
tree574e0fcacc7f65345cd9a99c471a06c411e94db0 /src
parent9e71431e6f8323be8ced8997409cfe7a389c6583 (diff)
parent1cc730ddc27df52d757be1c2e7aa96193f8ca9df (diff)
downloadNinja-2993752dd617ada5218836dd6545fb06690e238b.zip
Ninja-2993752dd617ada5218836dd6545fb06690e238b.tar.gz
Ninja-2993752dd617ada5218836dd6545fb06690e238b.tar.bz2
Merge pull request #1181 from DanielWeber/issue-1161
Allow more path components
Diffstat (limited to 'src')
-rw-r--r--src/build.cc2
-rw-r--r--src/clparser.cc2
-rw-r--r--src/graph.cc8
-rw-r--r--src/graph.h9
-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/state.cc6
-rw-r--r--src/state.h7
-rw-r--r--src/util.cc18
-rw-r--r--src/util.h4
-rw-r--r--src/util_test.cc37
12 files changed, 57 insertions, 48 deletions
diff --git a/src/build.cc b/src/build.cc
index 64710dd..a0c7ec8 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 136ca04..b4c8619 100644
--- a/src/graph.cc
+++ b/src/graph.cc
@@ -348,10 +348,10 @@ bool Edge::use_console() const {
}
// static
-string Node::PathDecanonicalized(const string& path, unsigned int slash_bits) {
+string Node::PathDecanonicalized(const string& path, uint64_t slash_bits) {
string result = path;
#ifdef _WIN32
- unsigned int mask = 1;
+ uint64_t mask = 1;
for (char* c = &result[0]; (c = strchr(c, '/')) != NULL;) {
if (slash_bits & mask)
*c = '\\';
@@ -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)) {
*err = path + ": " + *err;
@@ -444,7 +444,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/graph.h b/src/graph.h
index add8d3d..ec24293 100644
--- a/src/graph.h
+++ b/src/graph.h
@@ -21,6 +21,7 @@ using namespace std;
#include "eval_env.h"
#include "timestamp.h"
+#include "util.h"
struct BuildLog;
struct DiskInterface;
@@ -33,7 +34,7 @@ struct State;
/// Information about a node in the dependency graph: the file, whether
/// it's dirty, mtime, etc.
struct Node {
- Node(const string& path, unsigned int slash_bits)
+ Node(const string& path, uint64_t slash_bits)
: path_(path),
slash_bits_(slash_bits),
mtime_(-1),
@@ -76,8 +77,8 @@ struct Node {
return PathDecanonicalized(path_, slash_bits_);
}
static string PathDecanonicalized(const string& path,
- unsigned int slash_bits);
- unsigned int slash_bits() const { return slash_bits_; }
+ uint64_t slash_bits);
+ uint64_t slash_bits() const { return slash_bits_; }
TimeStamp mtime() const { return mtime_; }
@@ -101,7 +102,7 @@ private:
/// Set bits starting from lowest for backslashes that were normalized to
/// forward slashes by CanonicalizePath. See |PathDecanonicalized|.
- unsigned int slash_bits_;
+ uint64_t slash_bits_;
/// Possible values of mtime_:
/// -1: file hasn't been examined
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 5ab73e9..63ec3a8 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/state.cc b/src/state.cc
index d539e7b..6079229 100644
--- a/src/state.cc
+++ b/src/state.cc
@@ -100,7 +100,7 @@ Edge* State::AddEdge(const Rule* rule) {
return edge;
}
-Node* State::GetNode(StringPiece path, unsigned int slash_bits) {
+Node* State::GetNode(StringPiece path, uint64_t slash_bits) {
Node* node = LookupNode(path);
if (node)
return node;
@@ -134,13 +134,13 @@ Node* State::SpellcheckNode(const string& path) {
return result;
}
-void State::AddIn(Edge* edge, StringPiece path, unsigned int slash_bits) {
+void State::AddIn(Edge* edge, StringPiece path, uint64_t slash_bits) {
Node* node = GetNode(path, slash_bits);
edge->inputs_.push_back(node);
node->AddOutEdge(edge);
}
-bool State::AddOut(Edge* edge, StringPiece path, unsigned int slash_bits) {
+bool State::AddOut(Edge* edge, StringPiece path, uint64_t slash_bits) {
Node* node = GetNode(path, slash_bits);
if (node->in_edge())
return false;
diff --git a/src/state.h b/src/state.h
index b530207..54e9dc5 100644
--- a/src/state.h
+++ b/src/state.h
@@ -23,6 +23,7 @@ using namespace std;
#include "eval_env.h"
#include "hash_map.h"
+#include "util.h"
struct Edge;
struct Node;
@@ -93,12 +94,12 @@ struct State {
Edge* AddEdge(const Rule* rule);
- Node* GetNode(StringPiece path, unsigned int slash_bits);
+ Node* GetNode(StringPiece path, uint64_t slash_bits);
Node* LookupNode(StringPiece path) const;
Node* SpellcheckNode(const string& path);
- void AddIn(Edge* edge, StringPiece path, unsigned int slash_bits);
- bool AddOut(Edge* edge, StringPiece path, unsigned int slash_bits);
+ void AddIn(Edge* edge, StringPiece path, uint64_t slash_bits);
+ bool AddOut(Edge* edge, StringPiece path, uint64_t slash_bits);
bool AddDefault(StringPiece path, string* error);
/// Reset state. Keeps all nodes and edges, but restores them to the
diff --git a/src/util.cc b/src/util.cc
index 1caa1ce..ce4b192 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..45d0727 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,38 @@ 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);
+ EXPECT_EQ(slash_bits, 0xffffffff);
- // 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 +333,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.