[C++] Fix info, warning, and error for ninja
diff --git a/command.cc b/command.cc
index f696cd5..6b48f68 100644
--- a/command.cc
+++ b/command.cc
@@ -175,6 +175,7 @@
}
void CommandEvaluator::Eval(DepNode* n, vector<Command*>* commands) {
+ ev_->set_loc(n->loc);
ev_->set_current_scope(n->rule_vars);
current_dep_node_ = n;
for (Value* v : n->cmds) {
@@ -209,5 +210,22 @@
}
continue;
}
+
+ if (!ev_->delayed_output_commands().empty()) {
+ vector<Command*> output_commands;
+ for (const string& cmd : ev_->delayed_output_commands()) {
+ Command* c = new Command(n->output);
+ c->cmd = make_shared<string>(cmd);
+ c->echo = false;
+ c->ignore_error = false;
+ output_commands.push_back(c);
+ }
+ // Prepend |output_commands|.
+ commands->swap(output_commands);
+ copy(output_commands.begin(), output_commands.end(),
+ back_inserter(*commands));
+ ev_->clear_delayed_output_commands();
+ }
+
ev_->set_current_scope(NULL);
}
diff --git a/command.h b/command.h
index e93de34..ab63240 100644
--- a/command.h
+++ b/command.h
@@ -33,7 +33,6 @@
shared_ptr<string> cmd;
bool echo;
bool ignore_error;
- //StringPiece shell;
};
class CommandEvaluator {
diff --git a/eval.h b/eval.h
index 558df3c..dad8127 100644
--- a/eval.h
+++ b/eval.h
@@ -59,6 +59,7 @@
shared_ptr<string> EvalVar(Symbol name);
const Loc& loc() const { return loc_; }
+ void set_loc(const Loc& loc) { loc_ = loc; }
const vector<shared_ptr<Rule>>& rules() const { return rules_; }
const unordered_map<Symbol, Vars*>& rule_vars() const {
@@ -76,6 +77,16 @@
bool avoid_io() const { return avoid_io_; }
void set_avoid_io(bool a) { avoid_io_ = a; }
+ const vector<string>& delayed_output_commands() const {
+ return delayed_output_commands_;
+ }
+ void add_delayed_output_command(const string& c) {
+ delayed_output_commands_.push_back(c);
+ }
+ void clear_delayed_output_commands() {
+ delayed_output_commands_.clear();
+ }
+
private:
Var* EvalRHS(Symbol lhs, Value* rhs, StringPiece orig_rhs, AssignOp op,
bool is_override = false);
@@ -92,7 +103,11 @@
Loc loc_;
bool is_bootstrap_;
+
bool avoid_io_;
+ // Commands which should run at ninja-time (i.e., info, warning, and
+ // error).
+ vector<string> delayed_output_commands_;
};
#endif // EVAL_H_
diff --git a/func.cc b/func.cc
index e0f9e52..5f01ebe 100644
--- a/func.cc
+++ b/func.cc
@@ -534,30 +534,33 @@
*s += var->Flavor();
}
-void InfoFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
+void InfoFunc(const vector<Value*>& args, Evaluator* ev, string*) {
shared_ptr<string> a = args[0]->Eval(ev);
if (ev->avoid_io()) {
- *s += "KATI_TODO(info)";
+ ev->add_delayed_output_command(StringPrintf("echo '%s'", a->c_str()));
return;
}
printf("%s\n", a->c_str());
fflush(stdout);
}
-void WarningFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
+void WarningFunc(const vector<Value*>& args, Evaluator* ev, string*) {
shared_ptr<string> a = args[0]->Eval(ev);
if (ev->avoid_io()) {
- *s += "KATI_TODO(warning)";
+ ev->add_delayed_output_command(
+ StringPrintf("echo '%s:%d: %s' 2>&1", LOCF(ev->loc()), a->c_str()));
return;
}
printf("%s:%d: %s\n", LOCF(ev->loc()), a->c_str());
fflush(stdout);
}
-void ErrorFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
+void ErrorFunc(const vector<Value*>& args, Evaluator* ev, string*) {
shared_ptr<string> a = args[0]->Eval(ev);
if (ev->avoid_io()) {
- *s += "KATI_TODO(error)";
+ ev->add_delayed_output_command(
+ StringPrintf("echo '%s:%d: *** %s.' 2>&1 && false",
+ LOCF(ev->loc()), a->c_str()));
return;
}
ev->Error(StringPrintf("*** %s.", a->c_str()));
diff --git a/runtest.rb b/runtest.rb
index e2458ce..b0cfae8 100755
--- a/runtest.rb
+++ b/runtest.rb
@@ -88,8 +88,13 @@
end
end
-def normalize_ninja_log(log)
+def normalize_ninja_log(log, mk)
log.gsub!(/^\[\d+\/\d+\] .*\n/, '')
+ if mk =~ /err_error_in_recipe.mk/
+ # This test expects ninja fails. Strip ninja specific error logs.
+ log.gsub!(/^FAILED: .*\n/, '')
+ log.gsub!(/^ninja: .*\n/, '')
+ end
log
end
@@ -195,7 +200,7 @@
res = IO.popen(cmd, 'r:binary', &:read)
if via_ninja && File.exist?('build.ninja') && File.exists?('ninja.sh')
log = IO.popen('./ninja.sh -j1 -v 2>&1', 'r:binary', &:read)
- res += normalize_ninja_log(log)
+ res += normalize_ninja_log(log, mk)
end
res = normalize_kati_log(res)
output += "=== #{tc} ===\n" + res
diff --git a/testcase/err_error_in_recipe.mk b/testcase/err_error_in_recipe.mk
new file mode 100644
index 0000000..af1b46b
--- /dev/null
+++ b/testcase/err_error_in_recipe.mk
@@ -0,0 +1,2 @@
+test:
+ $(error foo)
diff --git a/testcase/info.mk b/testcase/info.mk
index b6b501d..829729a 100644
--- a/testcase/info.mk
+++ b/testcase/info.mk
@@ -1,4 +1,3 @@
-# TODO(ninja): Fix
-
test:
- echo $(info "%s:%s" foo bar)
+ echo $(info "%s:%s" foo bar)xxx
+ $(info baz)
diff --git a/testcase/strip.mk b/testcase/strip.mk
index fc283ef..44df672 100644
--- a/testcase/strip.mk
+++ b/testcase/strip.mk
@@ -1,5 +1,3 @@
-# TODO(ninja): Fix
-
XY:=x y
X:=$(subst y, ,$(XY))
Y:=$(subst x, ,$(XY))
diff --git a/testcase/warning.mk b/testcase/warning.mk
index 340c3c2..7e83503 100644
--- a/testcase/warning.mk
+++ b/testcase/warning.mk
@@ -1,4 +1,5 @@
$(warning foo)
test:
+ $(warning bar)
echo PASS