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 | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 48 | void FindstringFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 49 | printf("TODO(findstring)"); |
| 50 | } |
| 51 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 52 | void FilterFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 53 | printf("TODO(filter)"); |
| 54 | } |
| 55 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 56 | void FilterOutFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 57 | printf("TODO(filter-out)"); |
| 58 | } |
| 59 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 60 | void SortFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 61 | printf("TODO(sort)"); |
| 62 | } |
| 63 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 64 | void WordFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 65 | printf("TODO(word)"); |
| 66 | } |
| 67 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 68 | void WordlistFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 69 | printf("TODO(wordlist)"); |
| 70 | } |
| 71 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 72 | void WordsFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 73 | printf("TODO(words)"); |
| 74 | } |
| 75 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 76 | void FirstwordFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 77 | printf("TODO(firstword)"); |
| 78 | } |
| 79 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 80 | void LastwordFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 81 | printf("TODO(lastword)"); |
| 82 | } |
| 83 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 84 | void JoinFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 85 | printf("TODO(join)"); |
| 86 | } |
| 87 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 88 | void WildcardFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 89 | printf("TODO(wildcard)"); |
| 90 | } |
| 91 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 92 | void DirFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 93 | printf("TODO(dir)"); |
| 94 | } |
| 95 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 96 | void NotdirFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 97 | printf("TODO(notdir)"); |
| 98 | } |
| 99 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 100 | void SuffixFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 101 | printf("TODO(suffix)"); |
| 102 | } |
| 103 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 104 | void BasenameFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 105 | printf("TODO(basename)"); |
| 106 | } |
| 107 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 108 | void AddsuffixFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 109 | printf("TODO(addsuffix)"); |
| 110 | } |
| 111 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 112 | void AddprefixFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 113 | printf("TODO(addprefix)"); |
| 114 | } |
| 115 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 116 | void RealpathFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 117 | printf("TODO(realpath)"); |
| 118 | } |
| 119 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 120 | void AbspathFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 121 | printf("TODO(abspath)"); |
| 122 | } |
| 123 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 124 | void IfFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 125 | printf("TODO(if)"); |
| 126 | } |
| 127 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 128 | void AndFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 129 | printf("TODO(and)"); |
| 130 | } |
| 131 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 132 | void OrFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 133 | printf("TODO(or)"); |
| 134 | } |
| 135 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 136 | void ValueFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 137 | printf("TODO(value)"); |
| 138 | } |
| 139 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 140 | void EvalFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 141 | printf("TODO(eval)"); |
| 142 | } |
| 143 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 144 | void ShellFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 145 | printf("TODO(shell)"); |
| 146 | } |
| 147 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 148 | void CallFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 149 | printf("TODO(call)"); |
| 150 | } |
| 151 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 152 | void ForeachFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 153 | printf("TODO(foreach)"); |
| 154 | } |
| 155 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 156 | void OriginFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 157 | printf("TODO(origin)"); |
| 158 | } |
| 159 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 160 | void FlavorFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 161 | printf("TODO(flavor)"); |
| 162 | } |
| 163 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 164 | void InfoFunc(const vector<Value*>& args, Evaluator* ev, string*) { |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 165 | shared_ptr<string> a = args[0]->Eval(ev); |
| 166 | printf("%s\n", a->c_str()); |
| 167 | fflush(stdout); |
| 168 | } |
| 169 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 170 | void WarningFunc(const vector<Value*>& args, Evaluator* ev, string*) { |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 171 | shared_ptr<string> a = args[0]->Eval(ev); |
Shinichiro Hamaji | 8ee8c37 | 2015-06-16 16:19:40 +0900 | [diff] [blame] | 172 | printf("%s:%d: %s\n", LOCF(ev->loc()), a->c_str()); |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 173 | fflush(stdout); |
| 174 | } |
| 175 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 176 | void ErrorFunc(const vector<Value*>& args, Evaluator* ev, string*) { |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 177 | shared_ptr<string> a = args[0]->Eval(ev); |
| 178 | ev->Error(StringPrintf("*** %s.", a->c_str())); |
| 179 | } |
| 180 | |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 181 | FuncInfo g_func_infos[] = { |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 182 | { "patsubst", &PatsubstFunc, 3 }, |
| 183 | { "strip", &StripFunc, 1 }, |
| 184 | { "subst", &SubstFunc, 3 }, |
| 185 | { "findstring", &FindstringFunc, 2 }, |
| 186 | { "filter", &FilterFunc, 2 }, |
| 187 | { "filter-out", &FilterOutFunc, 2 }, |
| 188 | { "sort", &SortFunc, 1 }, |
| 189 | { "word", &WordFunc, 2 }, |
| 190 | { "wordlist", &WordlistFunc, 3 }, |
| 191 | { "words", &WordsFunc, 1 }, |
| 192 | { "firstword", &FirstwordFunc, 1 }, |
| 193 | { "lastword", &LastwordFunc, 1 }, |
| 194 | { "join", &JoinFunc, 2 }, |
| 195 | |
| 196 | { "wildcard", &WildcardFunc, 1 }, |
| 197 | { "dir", &DirFunc, 1 }, |
| 198 | { "notdir", &NotdirFunc, 1 }, |
| 199 | { "suffix", &SuffixFunc, 1 }, |
| 200 | { "basename", &BasenameFunc, 1 }, |
| 201 | { "addsuffix", &AddsuffixFunc, 1 }, |
| 202 | { "addprefix", &AddprefixFunc, 1 }, |
| 203 | { "realpath", &RealpathFunc, 1 }, |
| 204 | { "abspath", &AbspathFunc, 1 }, |
| 205 | { "if", &IfFunc, 1 }, |
| 206 | { "and", &AndFunc, 1 }, |
| 207 | { "or", &OrFunc, 1 }, |
| 208 | { "value", &ValueFunc, 1 }, |
| 209 | { "eval", &EvalFunc, 1 }, |
| 210 | { "shell", &ShellFunc, 1 }, |
| 211 | { "call", &CallFunc, 1 }, |
| 212 | { "foreach", &ForeachFunc, 1 }, |
| 213 | { "origin", &OriginFunc, 1 }, |
| 214 | { "flavor", &FlavorFunc, 1 }, |
| 215 | { "info", &InfoFunc, 1 }, |
| 216 | { "warning", &WarningFunc, 1 }, |
| 217 | { "error", &ErrorFunc, 1 }, |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 218 | }; |
| 219 | |
| 220 | unordered_map<StringPiece, FuncInfo*>* g_func_info_map; |
| 221 | |
| 222 | } // namespace |
| 223 | |
| 224 | void InitFuncTable() { |
| 225 | g_func_info_map = new unordered_map<StringPiece, FuncInfo*>; |
| 226 | for (size_t i = 0; i < sizeof(g_func_infos) / sizeof(g_func_infos[0]); i++) { |
| 227 | FuncInfo* fi = &g_func_infos[i]; |
| 228 | bool ok = g_func_info_map->insert(make_pair(Intern(fi->name), fi)).second; |
| 229 | CHECK(ok); |
| 230 | } |
| 231 | } |
| 232 | |
| 233 | void QuitFuncTable() { |
| 234 | delete g_func_info_map; |
| 235 | } |
| 236 | |
| 237 | FuncInfo* GetFuncInfo(StringPiece name) { |
| 238 | auto found = g_func_info_map->find(name); |
| 239 | if (found == g_func_info_map->end()) |
| 240 | return NULL; |
| 241 | return found->second; |
| 242 | } |