Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 1 | #include "func.h" |
| 2 | |
| 3 | #include <stdio.h> |
| 4 | |
| 5 | #include <unordered_map> |
| 6 | |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 7 | #include "eval.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 8 | #include "log.h" |
| 9 | #include "strutil.h" |
| 10 | |
| 11 | namespace { |
| 12 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 13 | void 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 Hamaji | 37591ce | 2015-06-16 19:36:05 +0900 | [diff] [blame] | 17 | WordWriter ww(s); |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 18 | for (StringPiece tok : WordScanner(*str)) { |
Shinichiro Hamaji | 37591ce | 2015-06-16 19:36:05 +0900 | [diff] [blame] | 19 | ww.MaybeAddWhitespace(); |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 20 | AppendSubstPattern(tok, *pat, *repl, s); |
| 21 | } |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 22 | } |
| 23 | |
Shinichiro Hamaji | 37591ce | 2015-06-16 19:36:05 +0900 | [diff] [blame] | 24 | void 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 Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 30 | } |
| 31 | |
Shinichiro Hamaji | 37591ce | 2015-06-16 19:36:05 +0900 | [diff] [blame] | 32 | void 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 Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 46 | } |
| 47 | |
Shinichiro Hamaji | 00cc658 | 2015-06-17 18:12:46 +0900 | [diff] [blame^] | 48 | void 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 Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 53 | } |
| 54 | |
Shinichiro Hamaji | 00cc658 | 2015-06-17 18:12:46 +0900 | [diff] [blame^] | 55 | static void GetPats(const string& pat, vector<StringPiece>* pats) { |
| 56 | for (StringPiece tok : WordScanner(pat)) { |
| 57 | pats->push_back(tok); |
| 58 | } |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 59 | } |
| 60 | |
Shinichiro Hamaji | 00cc658 | 2015-06-17 18:12:46 +0900 | [diff] [blame^] | 61 | void 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 | |
| 77 | void 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 Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 94 | } |
| 95 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 96 | void SortFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 97 | printf("TODO(sort)"); |
| 98 | } |
| 99 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 100 | void WordFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 101 | printf("TODO(word)"); |
| 102 | } |
| 103 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 104 | void WordlistFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 105 | printf("TODO(wordlist)"); |
| 106 | } |
| 107 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 108 | void WordsFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 109 | printf("TODO(words)"); |
| 110 | } |
| 111 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 112 | void FirstwordFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 113 | printf("TODO(firstword)"); |
| 114 | } |
| 115 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 116 | void LastwordFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 117 | printf("TODO(lastword)"); |
| 118 | } |
| 119 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 120 | void JoinFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 121 | printf("TODO(join)"); |
| 122 | } |
| 123 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 124 | void WildcardFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 125 | printf("TODO(wildcard)"); |
| 126 | } |
| 127 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 128 | void DirFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 129 | printf("TODO(dir)"); |
| 130 | } |
| 131 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 132 | void NotdirFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 133 | printf("TODO(notdir)"); |
| 134 | } |
| 135 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 136 | void SuffixFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 137 | printf("TODO(suffix)"); |
| 138 | } |
| 139 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 140 | void BasenameFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 141 | printf("TODO(basename)"); |
| 142 | } |
| 143 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 144 | void AddsuffixFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 145 | printf("TODO(addsuffix)"); |
| 146 | } |
| 147 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 148 | void AddprefixFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 149 | printf("TODO(addprefix)"); |
| 150 | } |
| 151 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 152 | void RealpathFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 153 | printf("TODO(realpath)"); |
| 154 | } |
| 155 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 156 | void AbspathFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 157 | printf("TODO(abspath)"); |
| 158 | } |
| 159 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 160 | void IfFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 161 | printf("TODO(if)"); |
| 162 | } |
| 163 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 164 | void AndFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 165 | printf("TODO(and)"); |
| 166 | } |
| 167 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 168 | void OrFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 169 | printf("TODO(or)"); |
| 170 | } |
| 171 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 172 | void ValueFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 173 | printf("TODO(value)"); |
| 174 | } |
| 175 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 176 | void EvalFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 177 | printf("TODO(eval)"); |
| 178 | } |
| 179 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 180 | void ShellFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 181 | printf("TODO(shell)"); |
| 182 | } |
| 183 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 184 | void CallFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 185 | printf("TODO(call)"); |
| 186 | } |
| 187 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 188 | void ForeachFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 189 | printf("TODO(foreach)"); |
| 190 | } |
| 191 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 192 | void OriginFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 193 | printf("TODO(origin)"); |
| 194 | } |
| 195 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 196 | void FlavorFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 197 | printf("TODO(flavor)"); |
| 198 | } |
| 199 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 200 | void InfoFunc(const vector<Value*>& args, Evaluator* ev, string*) { |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 201 | shared_ptr<string> a = args[0]->Eval(ev); |
| 202 | printf("%s\n", a->c_str()); |
| 203 | fflush(stdout); |
| 204 | } |
| 205 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 206 | void WarningFunc(const vector<Value*>& args, Evaluator* ev, string*) { |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 207 | shared_ptr<string> a = args[0]->Eval(ev); |
Shinichiro Hamaji | 8ee8c37 | 2015-06-16 16:19:40 +0900 | [diff] [blame] | 208 | printf("%s:%d: %s\n", LOCF(ev->loc()), a->c_str()); |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 209 | fflush(stdout); |
| 210 | } |
| 211 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 212 | void ErrorFunc(const vector<Value*>& args, Evaluator* ev, string*) { |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 213 | shared_ptr<string> a = args[0]->Eval(ev); |
| 214 | ev->Error(StringPrintf("*** %s.", a->c_str())); |
| 215 | } |
| 216 | |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 217 | FuncInfo g_func_infos[] = { |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 218 | { "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 Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 254 | }; |
| 255 | |
| 256 | unordered_map<StringPiece, FuncInfo*>* g_func_info_map; |
| 257 | |
| 258 | } // namespace |
| 259 | |
| 260 | void 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 | |
| 269 | void QuitFuncTable() { |
| 270 | delete g_func_info_map; |
| 271 | } |
| 272 | |
| 273 | FuncInfo* 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 | } |