summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/parsers.cc10
-rw-r--r--src/parsers_test.cc4
2 files changed, 11 insertions, 3 deletions
diff --git a/src/parsers.cc b/src/parsers.cc
index 4041bf6..cee22b7 100644
--- a/src/parsers.cc
+++ b/src/parsers.cc
@@ -343,8 +343,14 @@ bool ManifestParser::ParseLet(string* name, string* value, string* err) {
return false;
// Do @ -> builddir substitution.
- size_t ofs;
- while ((ofs = value->find('@')) != string::npos) {
+ // XXX hack: we don't want to eat @ in arguments, so only do the
+ // substitution after a space.
+ size_t ofs = 0;
+ while ((ofs = value->find('@', ofs)) != string::npos) {
+ if (ofs > 0 && (*value)[ofs - 1] != ' ') {
+ ++ofs;
+ continue;
+ }
value->replace(ofs, 1, builddir_);
ofs += builddir_.size();
}
diff --git a/src/parsers_test.cc b/src/parsers_test.cc
index 6bd8e4b..7590a7a 100644
--- a/src/parsers_test.cc
+++ b/src/parsers_test.cc
@@ -227,12 +227,14 @@ TEST_F(ParserTest, BuildDir) {
"rule cat\n"
" command = cat @otherfile $in > $out\n"
"build @bin: cat @a.o\n"
-"build @a.o: cat a.cc\n"));
+"build @a.o: cat a.cc\n"
+"multiple_ats = @foo bar@@baz\n"));
EXPECT_EQ("foo", state.bindings_.LookupVariable("default_test"));
ASSERT_TRUE(state.LookupNode("out/a.o"));
const Rule* rule = state.LookupRule("cat");
ASSERT_TRUE(rule);
EXPECT_EQ("cat out/otherfile $in > $out", rule->command_.unparsed());
+ EXPECT_EQ("out/foo bar@@baz", state.bindings_.LookupVariable("multiple_ats"));
}
TEST_F(ParserTest, BuildDirRoot) {