summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build_test.cc3
-rw-r--r--src/graph.cc14
-rw-r--r--src/graph.h5
-rw-r--r--src/graph_test.cc21
4 files changed, 39 insertions, 4 deletions
diff --git a/src/build_test.cc b/src/build_test.cc
index a5b0972..5d6c4e9 100644
--- a/src/build_test.cc
+++ b/src/build_test.cc
@@ -755,12 +755,11 @@ TEST_F(BuildTest, MakeDirs) {
#ifdef _WIN32
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"build subdir\\dir2\\file: cat in1\n"));
- EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
#else
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"build subdir/dir2/file: cat in1\n"));
- EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
#endif
+ EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
EXPECT_EQ("", err);
EXPECT_TRUE(builder_.Build(&err));
diff --git a/src/graph.cc b/src/graph.cc
index aa9c0e8..5bc5c00 100644
--- a/src/graph.cc
+++ b/src/graph.cc
@@ -256,7 +256,7 @@ string EdgeEnv::MakePathList(vector<Node*>::iterator begin,
for (vector<Node*>::iterator i = begin; i != end; ++i) {
if (!result.empty())
result.push_back(sep);
- const string& path = (*i)->path();
+ const string& path = (*i)->PathDecanonicalized();
if (escape_in_out_ == kShellEscape) {
#if _WIN32
GetWin32EscapedString(path, &result);
@@ -328,6 +328,18 @@ bool Edge::use_console() const {
return pool() == &State::kConsolePool;
}
+string Node::PathDecanonicalized() const {
+ string result = path_;
+ unsigned int mask = 1;
+ for (char* c = &result[0]; (c = strpbrk(c, "/\\")) != NULL;) {
+ if (slash_bits_ & mask)
+ *c = '\\';
+ c++;
+ mask <<= 1;
+ }
+ return result;
+}
+
void Node::Dump(const char* prefix) const {
printf("%s <%s 0x%p> mtime: %d%s, (:%s), ",
prefix, path().c_str(), this,
diff --git a/src/graph.h b/src/graph.h
index 5c4112b..9aada38 100644
--- a/src/graph.h
+++ b/src/graph.h
@@ -72,6 +72,8 @@ struct Node {
}
const string& path() const { return path_; }
+ /// Get |path()| but use slash_bits to convert back to original slash styles.
+ string PathDecanonicalized() const;
unsigned int slash_bits() const { return slash_bits_; }
TimeStamp mtime() const { return mtime_; }
@@ -93,7 +95,8 @@ struct Node {
private:
string path_;
- /// XXX See CanonicalizePath.
+ /// Set bits starting from lowest for backslashes that were normalized to
+ /// forward slashes by CanonicalizePath. See |PathDecanonicalized|.
unsigned int slash_bits_;
/// Possible values of mtime_:
diff --git a/src/graph_test.cc b/src/graph_test.cc
index 14dc678..382d352 100644
--- a/src/graph_test.cc
+++ b/src/graph_test.cc
@@ -251,3 +251,24 @@ TEST_F(GraphTest, NestedPhonyPrintsDone) {
EXPECT_EQ(0, plan_.command_edge_count());
ASSERT_FALSE(plan_.more_to_do());
}
+
+#ifdef _WIN32
+TEST_F(GraphTest, Decanonicalize) {
+ ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
+"build out\\out1: cat src\\in1\n"
+"build out\\out2/out3\\out4: cat mid1\n"
+"build out3 out4\\foo: cat mid1\n"));
+
+ string err;
+ vector<Node*> root_nodes = state_.RootNodes(&err);
+ EXPECT_EQ(4u, root_nodes.size());
+ EXPECT_EQ(root_nodes[0]->path(), "out/out1");
+ EXPECT_EQ(root_nodes[1]->path(), "out/out2/out3/out4");
+ EXPECT_EQ(root_nodes[2]->path(), "out3");
+ EXPECT_EQ(root_nodes[3]->path(), "out4/foo");
+ EXPECT_EQ(root_nodes[0]->PathDecanonicalized(), "out\\out1");
+ EXPECT_EQ(root_nodes[1]->PathDecanonicalized(), "out\\out2/out3\\out4");
+ EXPECT_EQ(root_nodes[2]->PathDecanonicalized(), "out3");
+ EXPECT_EQ(root_nodes[3]->PathDecanonicalized(), "out4\\foo");
+}
+#endif