summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/graph.h8
-rw-r--r--src/manifest_parser.cc10
-rw-r--r--src/manifest_parser_test.cc48
-rw-r--r--src/state.cc14
-rw-r--r--src/state.h5
-rw-r--r--src/state_test.cc6
6 files changed, 76 insertions, 15 deletions
diff --git a/src/graph.h b/src/graph.h
index 66e31b5..5c4112b 100644
--- a/src/graph.h
+++ b/src/graph.h
@@ -33,8 +33,9 @@ struct State;
/// Information about a node in the dependency graph: the file, whether
/// it's dirty, mtime, etc.
struct Node {
- explicit Node(const string& path)
+ Node(const string& path, unsigned int slash_bits)
: path_(path),
+ slash_bits_(slash_bits),
mtime_(-1),
dirty_(false),
in_edge_(NULL),
@@ -71,6 +72,7 @@ struct Node {
}
const string& path() const { return path_; }
+ unsigned int slash_bits() const { return slash_bits_; }
TimeStamp mtime() const { return mtime_; }
bool dirty() const { return dirty_; }
@@ -90,6 +92,10 @@ struct Node {
private:
string path_;
+
+ /// XXX See CanonicalizePath.
+ unsigned int slash_bits_;
+
/// Possible values of mtime_:
/// -1: file hasn't been examined
/// 0: we looked, and file doesn't exist
diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc
index 55d191f..81a191e 100644
--- a/src/manifest_parser.cc
+++ b/src/manifest_parser.cc
@@ -323,16 +323,18 @@ bool ManifestParser::ParseEdge(string* err) {
for (vector<EvalString>::iterator i = ins.begin(); i != ins.end(); ++i) {
string path = i->Evaluate(env);
string path_err;
- if (!CanonicalizePath(&path, &path_err))
+ unsigned int slash_bits;
+ if (!CanonicalizePath(&path, &path_err, &slash_bits))
return lexer_.Error(path_err, err);
- state_->AddIn(edge, path);
+ state_->AddIn(edge, path, slash_bits);
}
for (vector<EvalString>::iterator i = outs.begin(); i != outs.end(); ++i) {
string path = i->Evaluate(env);
string path_err;
- if (!CanonicalizePath(&path, &path_err))
+ unsigned int slash_bits;
+ if (!CanonicalizePath(&path, &path_err, &slash_bits))
return lexer_.Error(path_err, err);
- state_->AddOut(edge, path);
+ state_->AddOut(edge, path, slash_bits);
}
edge->implicit_deps_ = implicit;
edge->order_only_deps_ = order_only;
diff --git a/src/manifest_parser_test.cc b/src/manifest_parser_test.cc
index aa3e9e4..1998a77 100644
--- a/src/manifest_parser_test.cc
+++ b/src/manifest_parser_test.cc
@@ -269,6 +269,26 @@ TEST_F(ParserTest, CanonicalizeFile) {
EXPECT_FALSE(state.LookupNode("in//2"));
}
+#ifdef _WIN32
+TEST_F(ParserTest, CanonicalizeFileBackslashes) {
+ ASSERT_NO_FATAL_FAILURE(AssertParse(
+"rule cat\n"
+" command = cat $in > $out\n"
+"build out: cat in\\1 in\\\\2\n"
+"build in\\1: cat\n"
+"build in\\2: cat\n"));
+
+ Node* node = state.LookupNode("in/1");;
+ EXPECT_TRUE(node);
+ EXPECT_EQ(1, node->slash_bits());
+ node = state.LookupNode("in/2");
+ EXPECT_TRUE(node);
+ EXPECT_EQ(1, node->slash_bits());
+ EXPECT_FALSE(state.LookupNode("in//1"));
+ EXPECT_FALSE(state.LookupNode("in//2"));
+}
+#endif
+
TEST_F(ParserTest, PathVariables) {
ASSERT_NO_FATAL_FAILURE(AssertParse(
"rule cat\n"
@@ -292,6 +312,34 @@ TEST_F(ParserTest, CanonicalizePaths) {
EXPECT_TRUE(state.LookupNode("bar/foo.cc"));
}
+#ifdef _WIN32
+TEST_F(ParserTest, CanonicalizePathsBackslashes) {
+ ASSERT_NO_FATAL_FAILURE(AssertParse(
+"rule cat\n"
+" command = cat $in > $out\n"
+"build ./out.o: cat ./bar/baz/../foo.cc\n"
+"build .\\out2.o: cat .\\bar/baz\\..\\foo.cc\n"
+"build .\\out3.o: cat .\\bar/baz\\..\\foo3.cc\n"
+));
+
+ EXPECT_FALSE(state.LookupNode("./out.o"));
+ EXPECT_FALSE(state.LookupNode(".\\out2.o"));
+ EXPECT_FALSE(state.LookupNode(".\\out3.o"));
+ EXPECT_TRUE(state.LookupNode("out.o"));
+ EXPECT_TRUE(state.LookupNode("out2.o"));
+ EXPECT_TRUE(state.LookupNode("out3.o"));
+ EXPECT_FALSE(state.LookupNode("./bar/baz/../foo.cc"));
+ EXPECT_FALSE(state.LookupNode(".\\bar/baz\\..\\foo.cc"));
+ EXPECT_FALSE(state.LookupNode(".\\bar/baz\\..\\foo3.cc"));
+ Node* node = state.LookupNode("bar/foo.cc");
+ EXPECT_TRUE(node);
+ EXPECT_EQ(0, node->slash_bits());
+ node = state.LookupNode("bar/foo3.cc");
+ EXPECT_TRUE(node);
+ EXPECT_EQ(1, node->slash_bits()); // First seen determines slashes.
+}
+#endif
+
TEST_F(ParserTest, ReservedWords) {
ASSERT_NO_FATAL_FAILURE(AssertParse(
"rule build\n"
diff --git a/src/state.cc b/src/state.cc
index 7258272..b6c29ff 100644
--- a/src/state.cc
+++ b/src/state.cc
@@ -112,10 +112,14 @@ Edge* State::AddEdge(const Rule* rule) {
}
Node* State::GetNode(StringPiece path) {
+ return GetNode(path, 0);
+}
+
+Node* State::GetNode(StringPiece path, unsigned int slash_bits) {
Node* node = LookupNode(path);
if (node)
return node;
- node = new Node(path.AsString());
+ node = new Node(path.AsString(), slash_bits);
paths_[node->path()] = node;
return node;
}
@@ -145,14 +149,14 @@ Node* State::SpellcheckNode(const string& path) {
return result;
}
-void State::AddIn(Edge* edge, StringPiece path) {
- Node* node = GetNode(path);
+void State::AddIn(Edge* edge, StringPiece path, unsigned int slash_bits) {
+ Node* node = GetNode(path, slash_bits);
edge->inputs_.push_back(node);
node->AddOutEdge(edge);
}
-void State::AddOut(Edge* edge, StringPiece path) {
- Node* node = GetNode(path);
+void State::AddOut(Edge* edge, StringPiece path, unsigned int slash_bits) {
+ Node* node = GetNode(path, slash_bits);
edge->outputs_.push_back(node);
if (node->in_edge()) {
Warning("multiple rules generate %s. "
diff --git a/src/state.h b/src/state.h
index c382dc0..9da6d1b 100644
--- a/src/state.h
+++ b/src/state.h
@@ -96,11 +96,12 @@ struct State {
Edge* AddEdge(const Rule* rule);
Node* GetNode(StringPiece path);
+ Node* GetNode(StringPiece path, unsigned int slash_bits);
Node* LookupNode(StringPiece path) const;
Node* SpellcheckNode(const string& path);
- void AddIn(Edge* edge, StringPiece path);
- void AddOut(Edge* edge, StringPiece path);
+ void AddIn(Edge* edge, StringPiece path, unsigned int slash_bits);
+ void AddOut(Edge* edge, StringPiece path, unsigned int slash_bits);
bool AddDefault(StringPiece path, string* error);
/// Reset state. Keeps all nodes and edges, but restores them to the
diff --git a/src/state_test.cc b/src/state_test.cc
index a4fafa1..85c6513 100644
--- a/src/state_test.cc
+++ b/src/state_test.cc
@@ -32,9 +32,9 @@ TEST(State, Basic) {
state.AddRule(rule);
Edge* edge = state.AddEdge(rule);
- state.AddIn(edge, "in1");
- state.AddIn(edge, "in2");
- state.AddOut(edge, "out");
+ state.AddIn(edge, "in1", 0);
+ state.AddIn(edge, "in2", 0);
+ state.AddOut(edge, "out", 0);
EXPECT_EQ("cat in1 in2 > out", edge->EvaluateCommand());