From 559389de082406f44ae752a2494e53000d31a7df Mon Sep 17 00:00:00 2001 From: Scott Graham Date: Sat, 8 Nov 2014 22:49:21 -0800 Subject: remove CanonicalizePath overloads, test for toplevel behaviour --- src/build.cc | 6 ++++-- src/build_test.cc | 29 +++++++++++++++++++++++++++++ src/canon_perftest.cc | 3 ++- src/graph.cc | 11 +++++++++-- src/includes_normalize-win32.cc | 3 ++- src/manifest_parser.cc | 3 ++- src/ninja.cc | 6 ++++-- src/util.cc | 10 ---------- src/util.h | 4 ---- src/util_test.cc | 14 ++++++++++++-- 10 files changed, 64 insertions(+), 25 deletions(-) diff --git a/src/build.cc b/src/build.cc index fb1cc74..a5f5fe8 100644 --- a/src/build.cc +++ b/src/build.cc @@ -850,9 +850,11 @@ bool Builder::ExtractDeps(CommandRunner::Result* result, deps_nodes->reserve(deps.ins_.size()); for (vector::iterator i = deps.ins_.begin(); i != deps.ins_.end(); ++i) { - if (!CanonicalizePath(const_cast(i->str_), &i->len_, err)) + unsigned int slash_bits; + if (!CanonicalizePath(const_cast(i->str_), &i->len_, err, + &slash_bits)) return false; - deps_nodes->push_back(state_->GetNode(*i)); + deps_nodes->push_back(state_->GetNode(*i, slash_bits)); } if (disk_interface_->RemoveFile(depfile) < 0) { diff --git a/src/build_test.cc b/src/build_test.cc index 5d6c4e9..f25dd5f 100644 --- a/src/build_test.cc +++ b/src/build_test.cc @@ -937,6 +937,35 @@ TEST_F(BuildTest, RebuildOrderOnlyDeps) { ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]); } +#ifdef _WIN32 +TEST_F(BuildTest, DepFileCanonicalize) { + string err; + int orig_edges = state_.edges_.size(); + ASSERT_NO_FATAL_FAILURE(AssertParse(&state_, +"rule cc\n command = cc $in\n depfile = $out.d\n" +"build gen/stuff/foo.o: cc foo.c\n")); + Edge* edge = state_.edges_.back(); + + fs_.Create("foo.c", ""); + GetNode("bar.h")->MarkDirty(); // Mark bar.h as missing. + // Note, different slashes from manifest. + fs_.Create("gen/stuff/foo.o.d", "gen\\stuff\\foo.o: blah.h bar.h\n"); + EXPECT_TRUE(builder_.AddTarget("gen/stuff/foo.o", &err)); + ASSERT_EQ("", err); + ASSERT_EQ(1u, fs_.files_read_.size()); + EXPECT_EQ("gen/stuff/foo.o.d", fs_.files_read_[0]); + + // Expect three new edges: one generating foo.o, and two more from + // loading the depfile. + ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size()); + // Expect our edge to now have three inputs: foo.c and two headers. + ASSERT_EQ(3u, edge->inputs_.size()); + + // Expect the command line we generate to only use the original input. + ASSERT_EQ("cc foo.c", edge->EvaluateCommand()); +} +#endif + TEST_F(BuildTest, Phony) { string err; ASSERT_NO_FATAL_FAILURE(AssertParse(&state_, diff --git a/src/canon_perftest.cc b/src/canon_perftest.cc index 59bd18f..8defa91 100644 --- a/src/canon_perftest.cc +++ b/src/canon_perftest.cc @@ -33,8 +33,9 @@ int main() { for (int j = 0; j < 5; ++j) { const int kNumRepetitions = 2000000; int64_t start = GetTimeMillis(); + unsigned int slash_bits; for (int i = 0; i < kNumRepetitions; ++i) { - CanonicalizePath(buf, &len, &err); + CanonicalizePath(buf, &len, &err, &slash_bits); } int delta = (int)(GetTimeMillis() - start); times.push_back(delta); diff --git a/src/graph.cc b/src/graph.cc index 5bc5c00..8666f50 100644 --- a/src/graph.cc +++ b/src/graph.cc @@ -391,6 +391,11 @@ bool ImplicitDepLoader::LoadDepFile(Edge* edge, const string& path, return false; } + unsigned int unused; + if (!CanonicalizePath(const_cast(depfile.out_.str_), + &depfile.out_.len_, err, &unused)) + return false; + // Check that this depfile matches the edge's output. Node* first_output = edge->outputs_[0]; StringPiece opath = StringPiece(first_output->path()); @@ -407,10 +412,12 @@ bool ImplicitDepLoader::LoadDepFile(Edge* edge, const string& path, // Add all its in-edges. for (vector::iterator i = depfile.ins_.begin(); i != depfile.ins_.end(); ++i, ++implicit_dep) { - if (!CanonicalizePath(const_cast(i->str_), &i->len_, err)) + unsigned int slash_bits; + if (!CanonicalizePath(const_cast(i->str_), &i->len_, err, + &slash_bits)) return false; - Node* node = state_->GetNode(*i); + Node* node = state_->GetNode(*i, slash_bits); *implicit_dep = node; node->AddOutEdge(edge); CreatePhonyInEdge(node); diff --git a/src/includes_normalize-win32.cc b/src/includes_normalize-win32.cc index 0d230f8..7ea2813 100644 --- a/src/includes_normalize-win32.cc +++ b/src/includes_normalize-win32.cc @@ -100,7 +100,8 @@ string IncludesNormalize::Normalize(const string& input, size_t len = input.size(); strncpy(copy, input.c_str(), input.size() + 1); string err; - if (!CanonicalizePath(copy, &len, &err)) + unsigned int slash_bits; + if (!CanonicalizePath(copy, &len, &err, &slash_bits)) Warning("couldn't canonicalize '%s': %s\n", input.c_str(), err.c_str()); StringPiece partially_fixed(copy, len); diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc index 81a191e..16214f1 100644 --- a/src/manifest_parser.cc +++ b/src/manifest_parser.cc @@ -209,7 +209,8 @@ bool ManifestParser::ParseDefault(string* err) { do { string path = eval.Evaluate(env_); string path_err; - if (!CanonicalizePath(&path, &path_err)) + unsigned int slash_bits; // Unused because this only does lookup. + if (!CanonicalizePath(&path, &path_err, &slash_bits)) return lexer_.Error(path_err, err); if (!state_->AddDefault(path, &path_err)) return lexer_.Error(path_err, err); diff --git a/src/ninja.cc b/src/ninja.cc index 4368fab..5831e26 100644 --- a/src/ninja.cc +++ b/src/ninja.cc @@ -228,7 +228,8 @@ struct RealFileReader : public ManifestParser::FileReader { /// Returns true if the manifest was rebuilt. bool NinjaMain::RebuildManifest(const char* input_file, string* err) { string path = input_file; - if (!CanonicalizePath(&path, err)) + unsigned int slash_bits; // Unused because this path is only used for lookup. + if (!CanonicalizePath(&path, err, &slash_bits)) return false; Node* node = state_.LookupNode(path); if (!node) @@ -250,7 +251,8 @@ bool NinjaMain::RebuildManifest(const char* input_file, string* err) { Node* NinjaMain::CollectTarget(const char* cpath, string* err) { string path = cpath; - if (!CanonicalizePath(&path, err)) + unsigned int slash_bits; // Unused because this path is only used for lookup. + if (!CanonicalizePath(&path, err, &slash_bits)) return NULL; // Special syntax: "foo.cc^" means "the first output of foo.cc". diff --git a/src/util.cc b/src/util.cc index 9cf736e..cccf59c 100644 --- a/src/util.cc +++ b/src/util.cc @@ -85,11 +85,6 @@ void Error(const char* msg, ...) { fprintf(stderr, "\n"); } -bool CanonicalizePath(string* path, string* err) { - unsigned int unused; - return CanonicalizePath(path, err, &unused); -} - bool CanonicalizePath(string* path, string* err, unsigned int* slash_bits) { METRIC_RECORD("canonicalize str"); size_t len = path->size(); @@ -102,11 +97,6 @@ bool CanonicalizePath(string* path, string* err, unsigned int* slash_bits) { return true; } -bool CanonicalizePath(char* path, size_t* len, string* err) { - unsigned int unused; - return CanonicalizePath(path, len, err, &unused); -} - unsigned int ShiftOverBit(int offset, unsigned int bits) { // e.g. for |offset| == 2: // | ... 9 8 7 6 5 4 3 2 1 0 | diff --git a/src/util.h b/src/util.h index 36f31f3..cb0de09 100644 --- a/src/util.h +++ b/src/util.h @@ -41,10 +41,6 @@ void Warning(const char* msg, ...); void Error(const char* msg, ...); /// Canonicalize a path like "foo/../bar.h" into just "bar.h". -bool CanonicalizePath(string* path, string* err); - -bool CanonicalizePath(char* path, size_t* len, string* err); - /// |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, string* err, unsigned int* slash_bits); diff --git a/src/util_test.cc b/src/util_test.cc index d047d9c..82db6d2 100644 --- a/src/util_test.cc +++ b/src/util_test.cc @@ -16,6 +16,15 @@ #include "test.h" +namespace { + +bool CanonicalizePath(string* path, string* err) { + unsigned int unused; + return ::CanonicalizePath(path, err, &unused); +} + +} // namespace + TEST(CanonicalizePath, PathSamples) { string path; string err; @@ -275,16 +284,17 @@ TEST(CanonicalizePath, NotNullTerminated) { string path; string err; size_t len; + unsigned int unused; path = "foo/. bar/."; len = strlen("foo/."); // Canonicalize only the part before the space. - EXPECT_TRUE(CanonicalizePath(&path[0], &len, &err)); + EXPECT_TRUE(CanonicalizePath(&path[0], &len, &err, &unused)); EXPECT_EQ(strlen("foo"), len); EXPECT_EQ("foo/. bar/.", string(path)); path = "foo/../file bar/."; len = strlen("foo/../file"); - EXPECT_TRUE(CanonicalizePath(&path[0], &len, &err)); + EXPECT_TRUE(CanonicalizePath(&path[0], &len, &err, &unused)); EXPECT_EQ(strlen("file"), len); EXPECT_EQ("file ./file bar/.", string(path)); } -- cgit v0.12