blob: e7f304be175c2ad8c77ad6a7dd1eaee9c58fd90e [file] [log] [blame]
Shinichiro Hamaji776ca302015-06-06 03:52:48 +09001#include "func.h"
2
3#include <stdio.h>
4
5#include <unordered_map>
6
Shinichiro Hamaji9619b362015-06-16 16:13:25 +09007#include "eval.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +09008#include "log.h"
9#include "strutil.h"
10
11namespace {
12
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +090013void PatsubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
14 shared_ptr<string> pat = args[0]->Eval(ev);
15 shared_ptr<string> repl = args[1]->Eval(ev);
16 shared_ptr<string> str = args[2]->Eval(ev);
Shinichiro Hamaji37591ce2015-06-16 19:36:05 +090017 WordWriter ww(s);
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +090018 for (StringPiece tok : WordScanner(*str)) {
Shinichiro Hamaji37591ce2015-06-16 19:36:05 +090019 ww.MaybeAddWhitespace();
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +090020 AppendSubstPattern(tok, *pat, *repl, s);
21 }
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +090022}
23
Shinichiro Hamaji37591ce2015-06-16 19:36:05 +090024void StripFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
25 shared_ptr<string> str = args[0]->Eval(ev);
26 WordWriter ww(s);
27 for (StringPiece tok : WordScanner(*str)) {
28 ww.Write(tok);
29 }
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +090030}
31
Shinichiro Hamaji37591ce2015-06-16 19:36:05 +090032void SubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
33 shared_ptr<string> pat = args[0]->Eval(ev);
34 shared_ptr<string> repl = args[1]->Eval(ev);
35 shared_ptr<string> str = args[2]->Eval(ev);
36 size_t index = 0;
37 while (index < str->size()) {
38 size_t found = str->find(*pat, index);
39 if (found == string::npos)
40 break;
41 AppendString(StringPiece(*str).substr(index, found - index), s);
42 AppendString(*repl, s);
43 index = found + pat->size();
44 }
45 AppendString(StringPiece(*str).substr(index), s);
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +090046}
47
Shinichiro Hamaji00cc6582015-06-17 18:12:46 +090048void FindstringFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
49 shared_ptr<string> find = args[0]->Eval(ev);
50 shared_ptr<string> in = args[1]->Eval(ev);
51 if (in->find(*find) != string::npos)
52 AppendString(*find, s);
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +090053}
54
Shinichiro Hamaji00cc6582015-06-17 18:12:46 +090055static void GetPats(const string& pat, vector<StringPiece>* pats) {
56 for (StringPiece tok : WordScanner(pat)) {
57 pats->push_back(tok);
58 }
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +090059}
60
Shinichiro Hamaji00cc6582015-06-17 18:12:46 +090061void FilterFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
62 shared_ptr<string> pat_buf = args[0]->Eval(ev);
63 shared_ptr<string> text = args[1]->Eval(ev);
64 vector<StringPiece> pats;
65 GetPats(*pat_buf, &pats);
66 WordWriter ww(s);
67 for (StringPiece tok : WordScanner(*text)) {
68 for (StringPiece pat : pats) {
69 if (MatchPattern(tok, pat)) {
70 ww.Write(tok);
71 break;
72 }
73 }
74 }
75}
76
77void FilterOutFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
78 shared_ptr<string> pat_buf = args[0]->Eval(ev);
79 shared_ptr<string> text = args[1]->Eval(ev);
80 vector<StringPiece> pats;
81 GetPats(*pat_buf, &pats);
82 WordWriter ww(s);
83 for (StringPiece tok : WordScanner(*text)) {
84 bool matched = false;
85 for (StringPiece pat : pats) {
86 if (MatchPattern(tok, pat)) {
87 matched = true;
88 break;
89 }
90 }
91 if (!matched)
92 ww.Write(tok);
93 }
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +090094}
95
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +090096void SortFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +090097 printf("TODO(sort)");
98}
99
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900100void WordFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900101 printf("TODO(word)");
102}
103
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900104void WordlistFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900105 printf("TODO(wordlist)");
106}
107
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900108void WordsFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900109 printf("TODO(words)");
110}
111
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900112void FirstwordFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900113 printf("TODO(firstword)");
114}
115
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900116void LastwordFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900117 printf("TODO(lastword)");
118}
119
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900120void JoinFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900121 printf("TODO(join)");
122}
123
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900124void WildcardFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900125 printf("TODO(wildcard)");
126}
127
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900128void DirFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900129 printf("TODO(dir)");
130}
131
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900132void NotdirFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900133 printf("TODO(notdir)");
134}
135
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900136void SuffixFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900137 printf("TODO(suffix)");
138}
139
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900140void BasenameFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900141 printf("TODO(basename)");
142}
143
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900144void AddsuffixFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900145 printf("TODO(addsuffix)");
146}
147
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900148void AddprefixFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900149 printf("TODO(addprefix)");
150}
151
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900152void RealpathFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900153 printf("TODO(realpath)");
154}
155
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900156void AbspathFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900157 printf("TODO(abspath)");
158}
159
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900160void IfFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900161 printf("TODO(if)");
162}
163
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900164void AndFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900165 printf("TODO(and)");
166}
167
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900168void OrFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900169 printf("TODO(or)");
170}
171
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900172void ValueFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900173 printf("TODO(value)");
174}
175
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900176void EvalFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900177 printf("TODO(eval)");
178}
179
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900180void ShellFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900181 printf("TODO(shell)");
182}
183
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900184void CallFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900185 printf("TODO(call)");
186}
187
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900188void ForeachFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900189 printf("TODO(foreach)");
190}
191
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900192void OriginFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900193 printf("TODO(origin)");
194}
195
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900196void FlavorFunc(const vector<Value*>&, Evaluator*, string*) {
Shinichiro Hamaji4f22f5c2015-06-16 16:28:25 +0900197 printf("TODO(flavor)");
198}
199
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900200void InfoFunc(const vector<Value*>& args, Evaluator* ev, string*) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900201 shared_ptr<string> a = args[0]->Eval(ev);
202 printf("%s\n", a->c_str());
203 fflush(stdout);
204}
205
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900206void WarningFunc(const vector<Value*>& args, Evaluator* ev, string*) {
Shinichiro Hamaji9619b362015-06-16 16:13:25 +0900207 shared_ptr<string> a = args[0]->Eval(ev);
Shinichiro Hamaji8ee8c372015-06-16 16:19:40 +0900208 printf("%s:%d: %s\n", LOCF(ev->loc()), a->c_str());
Shinichiro Hamaji9619b362015-06-16 16:13:25 +0900209 fflush(stdout);
210}
211
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900212void ErrorFunc(const vector<Value*>& args, Evaluator* ev, string*) {
Shinichiro Hamaji9619b362015-06-16 16:13:25 +0900213 shared_ptr<string> a = args[0]->Eval(ev);
214 ev->Error(StringPrintf("*** %s.", a->c_str()));
215}
216
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900217FuncInfo g_func_infos[] = {
Shinichiro Hamaji2e6cbfc2015-06-16 18:46:50 +0900218 { "patsubst", &PatsubstFunc, 3 },
219 { "strip", &StripFunc, 1 },
220 { "subst", &SubstFunc, 3 },
221 { "findstring", &FindstringFunc, 2 },
222 { "filter", &FilterFunc, 2 },
223 { "filter-out", &FilterOutFunc, 2 },
224 { "sort", &SortFunc, 1 },
225 { "word", &WordFunc, 2 },
226 { "wordlist", &WordlistFunc, 3 },
227 { "words", &WordsFunc, 1 },
228 { "firstword", &FirstwordFunc, 1 },
229 { "lastword", &LastwordFunc, 1 },
230 { "join", &JoinFunc, 2 },
231
232 { "wildcard", &WildcardFunc, 1 },
233 { "dir", &DirFunc, 1 },
234 { "notdir", &NotdirFunc, 1 },
235 { "suffix", &SuffixFunc, 1 },
236 { "basename", &BasenameFunc, 1 },
237 { "addsuffix", &AddsuffixFunc, 1 },
238 { "addprefix", &AddprefixFunc, 1 },
239 { "realpath", &RealpathFunc, 1 },
240 { "abspath", &AbspathFunc, 1 },
241 { "if", &IfFunc, 1 },
242 { "and", &AndFunc, 1 },
243 { "or", &OrFunc, 1 },
244 { "value", &ValueFunc, 1 },
245 { "eval", &EvalFunc, 1 },
246 { "shell", &ShellFunc, 1 },
247 { "call", &CallFunc, 1 },
248 { "foreach", &ForeachFunc, 1 },
249 { "origin", &OriginFunc, 1 },
250 { "flavor", &FlavorFunc, 1 },
251 { "info", &InfoFunc, 1 },
252 { "warning", &WarningFunc, 1 },
253 { "error", &ErrorFunc, 1 },
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900254};
255
256unordered_map<StringPiece, FuncInfo*>* g_func_info_map;
257
258} // namespace
259
260void InitFuncTable() {
261 g_func_info_map = new unordered_map<StringPiece, FuncInfo*>;
262 for (size_t i = 0; i < sizeof(g_func_infos) / sizeof(g_func_infos[0]); i++) {
263 FuncInfo* fi = &g_func_infos[i];
264 bool ok = g_func_info_map->insert(make_pair(Intern(fi->name), fi)).second;
265 CHECK(ok);
266 }
267}
268
269void QuitFuncTable() {
270 delete g_func_info_map;
271}
272
273FuncInfo* GetFuncInfo(StringPiece name) {
274 auto found = g_func_info_map->find(name);
275 if (found == g_func_info_map->end())
276 return NULL;
277 return found->second;
278}