blob: 91d996d1607874124fb7ec48fd6aad00eb223842 [file] [log] [blame]
Shinichiro Hamaji776ca302015-06-06 03:52:48 +09001#include "exec.h"
2
3#include <stdio.h>
4#include <stdlib.h>
5
6#include <memory>
7#include <unordered_map>
8
9#include "dep.h"
10#include "eval.h"
11#include "log.h"
12#include "string_piece.h"
13#include "value.h"
14
15namespace {
16
17struct Runner {
18 Runner()
19 : echo(true), ignore_error(false) {
20 }
21 StringPiece output;
22 shared_ptr<string> cmd;
23 bool echo;
24 bool ignore_error;
25 //StringPiece shell;
26};
27
28} // namespace
29
30class Executor {
31 public:
32 explicit Executor(const Vars* vars)
33 : vars_(vars) {
34 }
35
36 void ExecNode(DepNode* n, DepNode* needed_by) {
37 if (done_[n->output])
38 return;
39
40 LOG("ExecNode: %s for %s",
41 n->output.as_string().c_str(),
42 needed_by ? needed_by->output.as_string().c_str() : "(null)");
43
44 for (DepNode* d : n->deps) {
45#if 0
46 if (d.is_order_only && exists(d->output)) {
47 }
48#endif
49 ExecNode(d, n);
50 }
51
52 vector<Runner*> runners;
53 CreateRunners(n, &runners);
54 for (Runner* runner : runners) {
55 if (runner->echo) {
56 printf("%s\n", runner->cmd->c_str());
57 fflush(stdout);
58 }
59 system(runner->cmd->c_str());
60 delete runner;
61 }
62 }
63
64 void CreateRunners(DepNode* n, vector<Runner*>* runners) {
65 unique_ptr<Evaluator> ev(new Evaluator(vars_));
66 for (Value* v : n->cmds) {
Shinichiro Hamaji133bf672015-06-17 06:14:20 +090067 shared_ptr<string> cmd = v->Eval(ev.get());
68 while (true) {
69 size_t index = cmd->find('\n');
70 if (index == string::npos)
71 break;
72
73 Runner* runner = new Runner;
74 runner->output = n->output;
75 runner->cmd = make_shared<string>(cmd->substr(0, index));
76 runners->push_back(runner);
77 cmd = make_shared<string>(cmd->substr(index + 1));
78 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090079 Runner* runner = new Runner;
80 runner->output = n->output;
Shinichiro Hamaji133bf672015-06-17 06:14:20 +090081 runner->cmd = cmd;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090082 runners->push_back(runner);
Shinichiro Hamaji133bf672015-06-17 06:14:20 +090083 continue;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090084 }
85 }
86
87 private:
88 const Vars* vars_;
89 unordered_map<StringPiece, bool> done_;
90
91};
92
93void Exec(const vector<DepNode*>& roots, const Vars* vars) {
94 unique_ptr<Executor> executor(new Executor(vars));
95 for (DepNode* root : roots) {
96 executor->ExecNode(root, NULL);
97 }
98}