summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Martin <martine@danga.com>2012-06-15 22:05:57 (GMT)
committerEvan Martin <martine@danga.com>2012-06-15 22:05:57 (GMT)
commit4c4e7f0782bcffb11eb4d41a0944a45a1abc31f0 (patch)
treefa1d2bacf1ebb1cda31e701d7baa0e8f24ce1a28
parentcb8204536efb831e649195bc25d9c89bd7f33793 (diff)
parent36aa519f52c7ff443cc7f2a43283a5d4c0807639 (diff)
downloadNinja-4c4e7f0782bcffb11eb4d41a0944a45a1abc31f0.zip
Ninja-4c4e7f0782bcffb11eb4d41a0944a45a1abc31f0.tar.gz
Ninja-4c4e7f0782bcffb11eb4d41a0944a45a1abc31f0.tar.bz2
Merge pull request #331 from sgraham/add-in_newline
Add $in_newline
-rw-r--r--doc/manual.asciidoc7
-rw-r--r--src/graph.cc16
-rw-r--r--src/parsers_test.cc17
3 files changed, 32 insertions, 8 deletions
diff --git a/doc/manual.asciidoc b/doc/manual.asciidoc
index 5de9638..e7983be 100644
--- a/doc/manual.asciidoc
+++ b/doc/manual.asciidoc
@@ -359,9 +359,12 @@ command to run. (In the context of a rule, the `command` variable is
special and defines the command to run. A full list of special
variables is provided in <<ref_rule,the reference>>.)
-Within the context of a rule, two additional special variables are
+Within the context of a rule, three additional special variables are
available: `$in` expands to the list of input files (`foo.c`) and
-`$out` to the output file (`foo.o`) for the command.
+`$out` to the output file (`foo.o`) for the command. For use with
+`$rspfile_content`, there is also `$in_newline`, which is the same as
+`$in`, except that multiple inputs are separated by `\n`, rather than
+spaces.
Build statements
diff --git a/src/graph.cc b/src/graph.cc
index f381d8a..5418ecf 100644
--- a/src/graph.cc
+++ b/src/graph.cc
@@ -183,20 +183,23 @@ struct EdgeEnv : public Env {
/// Given a span of Nodes, construct a list of paths suitable for a command
/// line. XXX here is where shell-escaping of e.g spaces should happen.
string MakePathList(vector<Node*>::iterator begin,
- vector<Node*>::iterator end);
+ vector<Node*>::iterator end,
+ char sep);
Edge* edge_;
};
string EdgeEnv::LookupVariable(const string& var) {
- if (var == "in") {
+ if (var == "in" || var == "in_newline") {
int explicit_deps_count = edge_->inputs_.size() - edge_->implicit_deps_ -
edge_->order_only_deps_;
return MakePathList(edge_->inputs_.begin(),
- edge_->inputs_.begin() + explicit_deps_count);
+ edge_->inputs_.begin() + explicit_deps_count,
+ var == "in" ? ' ' : '\n');
} else if (var == "out") {
return MakePathList(edge_->outputs_.begin(),
- edge_->outputs_.end());
+ edge_->outputs_.end(),
+ ' ');
} else if (edge_->env_) {
return edge_->env_->LookupVariable(var);
} else {
@@ -206,11 +209,12 @@ string EdgeEnv::LookupVariable(const string& var) {
}
string EdgeEnv::MakePathList(vector<Node*>::iterator begin,
- vector<Node*>::iterator end) {
+ vector<Node*>::iterator end,
+ char sep) {
string result;
for (vector<Node*>::iterator i = begin; i != end; ++i) {
if (!result.empty())
- result.push_back(' ');
+ result.push_back(sep);
const string& path = (*i)->path();
if (path.find(" ") != string::npos) {
result.append("\"");
diff --git a/src/parsers_test.cc b/src/parsers_test.cc
index c5151b8..fc83946 100644
--- a/src/parsers_test.cc
+++ b/src/parsers_test.cc
@@ -115,6 +115,23 @@ TEST_F(ParserTest, ResponseFiles) {
EXPECT_EQ("[$in]", rule->rspfile_content().Serialize());
}
+TEST_F(ParserTest, InNewline) {
+ ASSERT_NO_FATAL_FAILURE(AssertParse(
+"rule cat_rsp\n"
+" command = cat $in_newline > $out\n"
+"\n"
+"build out: cat_rsp in in2\n"
+" rspfile=out.rsp\n"));
+
+ ASSERT_EQ(2u, state.rules_.size());
+ const Rule* rule = state.rules_.begin()->second;
+ EXPECT_EQ("cat_rsp", rule->name());
+ EXPECT_EQ("[cat ][$in_newline][ > ][$out]", rule->command().Serialize());
+
+ Edge* edge = state.edges_[0];
+ EXPECT_EQ("cat in\nin2 > out", edge->EvaluateCommand());
+}
+
TEST_F(ParserTest, Variables) {
ASSERT_NO_FATAL_FAILURE(AssertParse(
"l = one-letter-test\n"