if (!parser_.Newline(err))
return false;
- string command;
+ if (state_->LookupRule(name) != NULL) {
+ *err = "duplicate rule '" + name + "'";
+ return false;
+ }
+
+ Rule* rule = new Rule(name); // XXX scoped_ptr
+
if (parser_.PeekToken() == Token::INDENT) {
parser_.ConsumeToken();
if (!ParseLet(&key, &val, err))
return false;
- if (key == "command")
- command = val;
+ if (key == "command") {
+ rule->ParseCommand(val);
+ }
}
parser_.ConsumeToken();
}
- if (command.empty())
+ if (rule->command_.unparsed().empty())
return parser_.Error("expected 'command =' line", err);
- state_->AddRule(name, command);
+ state_->AddRule(rule);
return true;
}
};
struct Rule {
- Rule(const string& name, const string& command) :
- name_(name) {
+ Rule(const string& name) : name_(name) { }
+
+ void ParseCommand(const string& command) {
assert(command_.Parse(command)); // XXX
}
string name_;
// EvalString::Env impl
virtual string Evaluate(const string& var);
- Rule* AddRule(const string& name, const string& command);
+ void AddRule(Rule* rule);
Rule* LookupRule(const string& rule_name);
Edge* AddEdge(Rule* rule);
Node* GetNode(const string& path);
return i->second;
}
-Rule* State::AddRule(const string& name, const string& command) {
- Rule* rule = new Rule(name, command);
- rules_[name] = rule;
- return rule;
+void State::AddRule(Rule* rule) {
+ assert(LookupRule(rule->name_) == NULL);
+ rules_[rule->name_] = rule;
}
Edge* State::AddEdge(Rule* rule) {
}
TEST(Parser, Errors) {
- State state;
-
{
ManifestParser parser(NULL);
string err;
}
{
+ State state;
ManifestParser parser(&state);
string err;
EXPECT_FALSE(parser.Parse("x = 3\ny 2", &err));
}
{
+ State state;
ManifestParser parser(&state);
string err;
EXPECT_FALSE(parser.Parse("build x: y z\n", &err));
}
{
+ State state;
ManifestParser parser(&state);
string err;
EXPECT_FALSE(parser.Parse("build x:: y z\n", &err));
}
{
+ State state;
ManifestParser parser(&state);
string err;
EXPECT_FALSE(parser.Parse("rule cat\n command = cat ok\n"
}
{
+ State state;
ManifestParser parser(&state);
string err;
EXPECT_FALSE(parser.Parse("rule cat\n"
}
{
+ State state;
ManifestParser parser(&state);
string err;
EXPECT_FALSE(parser.Parse("rule %foo\n",
TEST(State, Basic) {
State state;
- Rule* rule = state.AddRule("cat", "cat @in > $out");
+ Rule* rule = new Rule("cat");
+ rule->ParseCommand("cat @in > $out");
+ state.AddRule(rule);
Edge* edge = state.AddEdge(rule);
state.AddInOut(edge, Edge::IN, "in1");
state.AddInOut(edge, Edge::IN, "in2");