aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-06-18 11:12:58 +0900
committerShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-06-18 11:25:45 +0900
commit6e6de8d721166b90b017a88c44a9cca0afadf921 (patch)
tree48ec06ff1f6729b2e48343d20428dc1f51e29b52
parent8f68bd3becce2fa8f442468691c2555d5a2f37e0 (diff)
downloadandroid_build_kati-6e6de8d721166b90b017a88c44a9cca0afadf921.tar.gz
android_build_kati-6e6de8d721166b90b017a88c44a9cca0afadf921.tar.bz2
android_build_kati-6e6de8d721166b90b017a88c44a9cca0afadf921.zip
[C++] Implement include directive
-rw-r--r--eval.cc44
-rw-r--r--eval.h3
-rw-r--r--file.cc2
-rw-r--r--file.h2
-rw-r--r--file_cache.cc10
-rw-r--r--file_cache.h3
-rw-r--r--main.cc1
7 files changed, 61 insertions, 4 deletions
diff --git a/eval.cc b/eval.cc
index ff30049..6c7110e 100644
--- a/eval.cc
+++ b/eval.cc
@@ -1,7 +1,10 @@
#include "eval.h"
+#include <glob.h>
+
#include "ast.h"
#include "file.h"
+#include "file_cache.h"
#include "rule.h"
#include "strutil.h"
#include "value.h"
@@ -106,6 +109,9 @@ void Evaluator::EvalCommand(const CommandAST* ast) {
}
void Evaluator::EvalIf(const IfAST* ast) {
+ loc_ = ast->loc();
+ last_rule_ = NULL;
+
bool is_true;
switch (ast->op) {
case CondOp::IFDEF:
@@ -139,11 +145,47 @@ void Evaluator::EvalIf(const IfAST* ast) {
}
}
+void Evaluator::DoInclude(const char* fname, bool should_exist) {
+ Makefile* mk = MakefileCacheManager::Get()->ReadMakefile(fname);
+ if (!mk->Exists()) {
+ if (should_exist) {
+ Error(StringPrintf(
+ "Cannot read %s\n"
+ "NOTE: kati does not support generating missing makefiles", fname));
+ }
+ return;
+ }
+
+ for (AST* ast : mk->asts()) {
+ LOG("%s", ast->DebugString().c_str());
+ ast->Eval(this);
+ }
+}
+
void Evaluator::EvalInclude(const IncludeAST* ast) {
- ERROR("TODO");
+ loc_ = ast->loc();
+ last_rule_ = NULL;
+
+ shared_ptr<string> pats = ast->expr->Eval(this);
+ for (StringPiece pat : WordScanner(*pats)) {
+ ScopedTerminator st(pat);
+ if (pat.find_first_of("?*[") != string::npos) {
+ glob_t gl;
+ glob(pat.data(), GLOB_NOSORT, NULL, &gl);
+ for (size_t i = 0; i < gl.gl_pathc; i++) {
+ DoInclude(gl.gl_pathv[i], ast->should_exist);
+ }
+ globfree(&gl);
+ } else {
+ DoInclude(pat.data(), ast->should_exist);
+ }
+ }
}
void Evaluator::EvalExport(const ExportAST* ast) {
+ loc_ = ast->loc();
+ last_rule_ = NULL;
+
ERROR("TODO");
}
diff --git a/eval.h b/eval.h
index 3c84c3f..6a27c62 100644
--- a/eval.h
+++ b/eval.h
@@ -41,6 +41,7 @@ class Evaluator {
void EvalInclude(const IncludeAST* ast);
void EvalExport(const ExportAST* ast);
+
Var* LookupVar(StringPiece name);
// For target specific variables.
Var* LookupVarInCurrentScope(StringPiece name);
@@ -60,6 +61,8 @@ class Evaluator {
void Error(const string& msg);
private:
+ void DoInclude(const char* fname, bool should_exist);
+
const Vars* in_vars_;
Vars* vars_;
unordered_map<StringPiece, Vars*> rule_vars_;
diff --git a/file.cc b/file.cc
index 9f3c147..c8bc985 100644
--- a/file.cc
+++ b/file.cc
@@ -10,7 +10,7 @@
#include "parser.h"
Makefile::Makefile(const string& filename)
- : len_(0), mtime_(0), filename_(filename) {
+ : buf_(NULL), len_(0), mtime_(0), filename_(filename) {
int fd = open(filename.c_str(), O_RDONLY);
if (fd < 0) {
return;
diff --git a/file.h b/file.h
index a053073..671bf64 100644
--- a/file.h
+++ b/file.h
@@ -25,6 +25,8 @@ class Makefile {
const vector<AST*>& asts() const { return asts_; }
vector<AST*>* mutable_asts() { return &asts_; }
+ bool Exists() const { return buf_; }
+
private:
char* buf_;
size_t len_;
diff --git a/file_cache.cc b/file_cache.cc
index eb64328..7abd10b 100644
--- a/file_cache.cc
+++ b/file_cache.cc
@@ -4,12 +4,22 @@
#include "file.h"
+static MakefileCacheManager* g_instance;
+
MakefileCacheManager::MakefileCacheManager() {}
MakefileCacheManager::~MakefileCacheManager() {}
+MakefileCacheManager* MakefileCacheManager::Get() {
+ return g_instance;
+}
+
class MakefileCacheManagerImpl : public MakefileCacheManager {
public:
+ MakefileCacheManagerImpl() {
+ g_instance = this;
+ }
+
virtual ~MakefileCacheManagerImpl() {
for (auto p : cache_) {
delete p.second;
diff --git a/file_cache.h b/file_cache.h
index 7b3b3ff..a33e863 100644
--- a/file_cache.h
+++ b/file_cache.h
@@ -13,9 +13,10 @@ class MakefileCacheManager {
virtual Makefile* ReadMakefile(const string& filename) = 0;
+ static MakefileCacheManager* Get();
+
protected:
MakefileCacheManager();
-
};
MakefileCacheManager* NewMakefileCacheManager();
diff --git a/main.cc b/main.cc
index a504154..3b1fb9d 100644
--- a/main.cc
+++ b/main.cc
@@ -66,7 +66,6 @@ static int Run(const vector<StringPiece>& targets) {
Evaluator* ev = new Evaluator(vars);
for (AST* ast : mk->asts()) {
LOG("%s", ast->DebugString().c_str());
-
ast->Eval(ev);
}