diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | ninja.cc | 5 | ||||
-rw-r--r-- | ninja.h | 80 | ||||
-rw-r--r-- | ninja_test.cc | 20 |
5 files changed, 114 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6484956 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +ninja +ninja_test diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..18f8918 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +CXXFLAGS := -Wall -g + +all: ninja ninja_test +ninja: ninja.cc | Makefile + +ninja_test: LDFLAGS = -lgtest -lgtest_main +ninja_test: ninja_test.cc | Makefile diff --git a/ninja.cc b/ninja.cc new file mode 100644 index 0000000..3e305c8 --- /dev/null +++ b/ninja.cc @@ -0,0 +1,5 @@ +#include "ninja.h" + +int main(int argc, char** argv) { + return 0; +} @@ -0,0 +1,80 @@ +#include <map> +#include <string> +#include <vector> + +using namespace std; + +struct Node; +struct FileStat { + FileStat(const string& path) : path_(path), node_(NULL) {} + string path_; + Node* node_; +}; + +struct Edge; +struct Node { + Node(FileStat* file) : file_(file), dirty_(false) {} + FileStat* file_; + bool dirty_; + vector<Edge*> edges_; +}; + +struct Rule { + Rule(const string& name, const string& command) : + name_(name), command_(command) {} + string name_; + string command_; +}; + +struct Edge { + Rule* rule_; + enum InOut { IN, OUT }; + vector<Node*> inputs_; + vector<Node*> outputs_; +}; + +struct StatCache { + map<string, FileStat*> paths_; +}; +struct State { + StatCache stat_cache_; + map<string, Rule*> rules_; + vector<Edge*> edges_; + + Rule* AddRule(const string& name, const string& command); + Edge* AddEdge(Rule* rule); + Edge* AddEdge(const string& rule_name); + Node* GetNode(const string& path); + void AddInOut(Edge* edge, Edge::InOut inout, const string& path); +}; + +Rule* State::AddRule(const string& name, const string& command) { + Rule* rule = new Rule(name, command); + rules_[name] = rule; + return rule; +} + +Edge* State::AddEdge(const string& rule_name) { + return AddEdge(rules_[rule_name]); +} + +Edge* State::AddEdge(Rule* rule) { + Edge* edge = new Edge(); + edge->rule_ = rule; + edges_.push_back(edge); + return edge; +} + +Node* State::GetNode(const string& path) { + FileStat* file = new FileStat(path); + stat_cache_.paths_[path] = file; + return new Node(file); +} + +void State::AddInOut(Edge* edge, Edge::InOut inout, const string& path) { + Node* node = GetNode(path); + if (inout == Edge::IN) + edge->inputs_.push_back(node); + else + edge->outputs_.push_back(node); +} diff --git a/ninja_test.cc b/ninja_test.cc new file mode 100644 index 0000000..145c53c --- /dev/null +++ b/ninja_test.cc @@ -0,0 +1,20 @@ +#include "ninja.h" + +#include <gtest/gtest.h> + +struct NinjaTest : public testing::Test { + NinjaTest() { + rule_cat_ = state_.AddRule("cat", "cat @in > $out"); + } + + Rule* rule_cat_; + State state_; +}; + +TEST_F(NinjaTest, Basic) { + Edge* edge = state_.AddEdge(rule_cat_); + state_.AddInOut(edge, Edge::IN, "in1"); + state_.AddInOut(edge, Edge::IN, "in2"); + state_.AddInOut(edge, Edge::OUT, "out"); +} + |