Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 1 | #include "func.h" |
| 2 | |
Shinichiro Hamaji | d527145 | 2015-06-17 18:50:03 +0900 | [diff] [blame^] | 3 | #include <limits.h> |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 4 | #include <stdio.h> |
Shinichiro Hamaji | d527145 | 2015-06-17 18:50:03 +0900 | [diff] [blame^] | 5 | #include <stdlib.h> |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 6 | |
Shinichiro Hamaji | d87e59e | 2015-06-17 18:18:34 +0900 | [diff] [blame] | 7 | #include <algorithm> |
Shinichiro Hamaji | d527145 | 2015-06-17 18:50:03 +0900 | [diff] [blame^] | 8 | #include <iterator> |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 9 | #include <unordered_map> |
| 10 | |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 11 | #include "eval.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 12 | #include "log.h" |
| 13 | #include "strutil.h" |
| 14 | |
| 15 | namespace { |
| 16 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 17 | void PatsubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) { |
| 18 | shared_ptr<string> pat = args[0]->Eval(ev); |
| 19 | shared_ptr<string> repl = args[1]->Eval(ev); |
| 20 | shared_ptr<string> str = args[2]->Eval(ev); |
Shinichiro Hamaji | 37591ce | 2015-06-16 19:36:05 +0900 | [diff] [blame] | 21 | WordWriter ww(s); |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 22 | for (StringPiece tok : WordScanner(*str)) { |
Shinichiro Hamaji | 37591ce | 2015-06-16 19:36:05 +0900 | [diff] [blame] | 23 | ww.MaybeAddWhitespace(); |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 24 | AppendSubstPattern(tok, *pat, *repl, s); |
| 25 | } |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 26 | } |
| 27 | |
Shinichiro Hamaji | 37591ce | 2015-06-16 19:36:05 +0900 | [diff] [blame] | 28 | void StripFunc(const vector<Value*>& args, Evaluator* ev, string* s) { |
| 29 | shared_ptr<string> str = args[0]->Eval(ev); |
| 30 | WordWriter ww(s); |
| 31 | for (StringPiece tok : WordScanner(*str)) { |
| 32 | ww.Write(tok); |
| 33 | } |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 34 | } |
| 35 | |
Shinichiro Hamaji | 37591ce | 2015-06-16 19:36:05 +0900 | [diff] [blame] | 36 | void SubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) { |
| 37 | shared_ptr<string> pat = args[0]->Eval(ev); |
| 38 | shared_ptr<string> repl = args[1]->Eval(ev); |
| 39 | shared_ptr<string> str = args[2]->Eval(ev); |
| 40 | size_t index = 0; |
| 41 | while (index < str->size()) { |
| 42 | size_t found = str->find(*pat, index); |
| 43 | if (found == string::npos) |
| 44 | break; |
| 45 | AppendString(StringPiece(*str).substr(index, found - index), s); |
| 46 | AppendString(*repl, s); |
| 47 | index = found + pat->size(); |
| 48 | } |
| 49 | AppendString(StringPiece(*str).substr(index), s); |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 50 | } |
| 51 | |
Shinichiro Hamaji | 00cc658 | 2015-06-17 18:12:46 +0900 | [diff] [blame] | 52 | void FindstringFunc(const vector<Value*>& args, Evaluator* ev, string* s) { |
| 53 | shared_ptr<string> find = args[0]->Eval(ev); |
| 54 | shared_ptr<string> in = args[1]->Eval(ev); |
| 55 | if (in->find(*find) != string::npos) |
| 56 | AppendString(*find, s); |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 57 | } |
| 58 | |
Shinichiro Hamaji | 00cc658 | 2015-06-17 18:12:46 +0900 | [diff] [blame] | 59 | void FilterFunc(const vector<Value*>& args, Evaluator* ev, string* s) { |
| 60 | shared_ptr<string> pat_buf = args[0]->Eval(ev); |
| 61 | shared_ptr<string> text = args[1]->Eval(ev); |
| 62 | vector<StringPiece> pats; |
Shinichiro Hamaji | d87e59e | 2015-06-17 18:18:34 +0900 | [diff] [blame] | 63 | WordScanner(*pat_buf).Split(&pats); |
Shinichiro Hamaji | 00cc658 | 2015-06-17 18:12:46 +0900 | [diff] [blame] | 64 | WordWriter ww(s); |
| 65 | for (StringPiece tok : WordScanner(*text)) { |
| 66 | for (StringPiece pat : pats) { |
| 67 | if (MatchPattern(tok, pat)) { |
| 68 | ww.Write(tok); |
| 69 | break; |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | void FilterOutFunc(const vector<Value*>& args, Evaluator* ev, string* s) { |
| 76 | shared_ptr<string> pat_buf = args[0]->Eval(ev); |
| 77 | shared_ptr<string> text = args[1]->Eval(ev); |
| 78 | vector<StringPiece> pats; |
Shinichiro Hamaji | d87e59e | 2015-06-17 18:18:34 +0900 | [diff] [blame] | 79 | WordScanner(*pat_buf).Split(&pats); |
Shinichiro Hamaji | 00cc658 | 2015-06-17 18:12:46 +0900 | [diff] [blame] | 80 | WordWriter ww(s); |
| 81 | for (StringPiece tok : WordScanner(*text)) { |
| 82 | bool matched = false; |
| 83 | for (StringPiece pat : pats) { |
| 84 | if (MatchPattern(tok, pat)) { |
| 85 | matched = true; |
| 86 | break; |
| 87 | } |
| 88 | } |
| 89 | if (!matched) |
| 90 | ww.Write(tok); |
| 91 | } |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 92 | } |
| 93 | |
Shinichiro Hamaji | d87e59e | 2015-06-17 18:18:34 +0900 | [diff] [blame] | 94 | void SortFunc(const vector<Value*>& args, Evaluator* ev, string* s) { |
| 95 | shared_ptr<string> list = args[0]->Eval(ev); |
| 96 | vector<StringPiece> toks; |
| 97 | WordScanner(*list).Split(&toks); |
| 98 | sort(toks.begin(), toks.end()); |
| 99 | WordWriter ww(s); |
| 100 | StringPiece prev; |
| 101 | for (StringPiece tok : toks) { |
| 102 | if (prev != tok) { |
| 103 | ww.Write(tok); |
| 104 | prev = tok; |
| 105 | } |
| 106 | } |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 107 | } |
| 108 | |
Shinichiro Hamaji | d527145 | 2015-06-17 18:50:03 +0900 | [diff] [blame^] | 109 | static int GetNumericValueForFunc(const string& buf) { |
| 110 | StringPiece s = TrimLeftSpace(buf); |
| 111 | char* end; |
| 112 | long n = strtol(s.data(), &end, 10); |
| 113 | if (n < 0 || n == LONG_MAX || s.data() + s.size() != end) { |
| 114 | return -1; |
| 115 | } |
| 116 | return n; |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 117 | } |
| 118 | |
Shinichiro Hamaji | d527145 | 2015-06-17 18:50:03 +0900 | [diff] [blame^] | 119 | void WordFunc(const vector<Value*>& args, Evaluator* ev, string* s) { |
| 120 | shared_ptr<string> n_str = args[0]->Eval(ev); |
| 121 | int n = GetNumericValueForFunc(*n_str); |
| 122 | if (n < 0) { |
| 123 | ev->Error(StringPrintf( |
| 124 | "*** non-numeric first argument to `word' function: '%s'.", |
| 125 | n_str->c_str())); |
| 126 | } |
| 127 | if (n == 0) { |
| 128 | ev->Error("*** first argument to `word' function must be greater than 0."); |
| 129 | } |
| 130 | |
| 131 | shared_ptr<string> text = args[1]->Eval(ev); |
| 132 | for (StringPiece tok : WordScanner(*text)) { |
| 133 | n--; |
| 134 | if (n == 0) { |
| 135 | AppendString(tok, s); |
| 136 | break; |
| 137 | } |
| 138 | } |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 139 | } |
| 140 | |
Shinichiro Hamaji | d527145 | 2015-06-17 18:50:03 +0900 | [diff] [blame^] | 141 | void WordlistFunc(const vector<Value*>& args, Evaluator* ev, string* s) { |
| 142 | shared_ptr<string> s_str = args[0]->Eval(ev); |
| 143 | int si = GetNumericValueForFunc(*s_str); |
| 144 | if (si < 0) { |
| 145 | ev->Error(StringPrintf( |
| 146 | "*** non-numeric first argument to `wordlist' function: '%s'.", |
| 147 | s_str->c_str())); |
| 148 | } |
| 149 | if (si == 0) { |
| 150 | ev->Error(StringPrintf( |
| 151 | "*** invalid first argument to `wordlist' function: %s`", |
| 152 | s_str->c_str())); |
| 153 | } |
| 154 | |
| 155 | shared_ptr<string> e_str = args[1]->Eval(ev); |
| 156 | int ei = GetNumericValueForFunc(*e_str); |
| 157 | if (ei < 0) { |
| 158 | ev->Error(StringPrintf( |
| 159 | "*** non-numeric second argument to `wordlist' function: '%s'.", |
| 160 | e_str->c_str())); |
| 161 | } |
| 162 | |
| 163 | shared_ptr<string> text = args[2]->Eval(ev); |
| 164 | int i = 0; |
| 165 | WordWriter ww(s); |
| 166 | for (StringPiece tok : WordScanner(*text)) { |
| 167 | i++; |
| 168 | if (si <= i && i <= ei) { |
| 169 | ww.Write(tok); |
| 170 | } |
| 171 | } |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 172 | } |
| 173 | |
Shinichiro Hamaji | d527145 | 2015-06-17 18:50:03 +0900 | [diff] [blame^] | 174 | void WordsFunc(const vector<Value*>& args, Evaluator* ev, string* s) { |
| 175 | shared_ptr<string> text = args[0]->Eval(ev); |
| 176 | WordScanner ws(*text); |
| 177 | int n = 0; |
| 178 | for (auto iter = ws.begin(); iter != ws.end(); ++iter) |
| 179 | n++; |
| 180 | char buf[32]; |
| 181 | sprintf(buf, "%d", n); |
| 182 | *s += buf; |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 183 | } |
| 184 | |
Shinichiro Hamaji | d527145 | 2015-06-17 18:50:03 +0900 | [diff] [blame^] | 185 | void FirstwordFunc(const vector<Value*>& args, Evaluator* ev, string* s) { |
| 186 | shared_ptr<string> text = args[0]->Eval(ev); |
| 187 | for (StringPiece tok : WordScanner(*text)) { |
| 188 | AppendString(tok, s); |
| 189 | return; |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | void LastwordFunc(const vector<Value*>& args, Evaluator* ev, string* s) { |
| 194 | shared_ptr<string> text = args[0]->Eval(ev); |
| 195 | StringPiece last; |
| 196 | for (StringPiece tok : WordScanner(*text)) { |
| 197 | last = tok; |
| 198 | } |
| 199 | AppendString(last, s); |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 200 | } |
| 201 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 202 | void JoinFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 203 | printf("TODO(join)"); |
| 204 | } |
| 205 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 206 | void WildcardFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 207 | printf("TODO(wildcard)"); |
| 208 | } |
| 209 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 210 | void DirFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 211 | printf("TODO(dir)"); |
| 212 | } |
| 213 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 214 | void NotdirFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 215 | printf("TODO(notdir)"); |
| 216 | } |
| 217 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 218 | void SuffixFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 219 | printf("TODO(suffix)"); |
| 220 | } |
| 221 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 222 | void BasenameFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 223 | printf("TODO(basename)"); |
| 224 | } |
| 225 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 226 | void AddsuffixFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 227 | printf("TODO(addsuffix)"); |
| 228 | } |
| 229 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 230 | void AddprefixFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 231 | printf("TODO(addprefix)"); |
| 232 | } |
| 233 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 234 | void RealpathFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 235 | printf("TODO(realpath)"); |
| 236 | } |
| 237 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 238 | void AbspathFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 239 | printf("TODO(abspath)"); |
| 240 | } |
| 241 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 242 | void IfFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 243 | printf("TODO(if)"); |
| 244 | } |
| 245 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 246 | void AndFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 247 | printf("TODO(and)"); |
| 248 | } |
| 249 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 250 | void OrFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 251 | printf("TODO(or)"); |
| 252 | } |
| 253 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 254 | void ValueFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 255 | printf("TODO(value)"); |
| 256 | } |
| 257 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 258 | void EvalFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 259 | printf("TODO(eval)"); |
| 260 | } |
| 261 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 262 | void ShellFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 263 | printf("TODO(shell)"); |
| 264 | } |
| 265 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 266 | void CallFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 267 | printf("TODO(call)"); |
| 268 | } |
| 269 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 270 | void ForeachFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 271 | printf("TODO(foreach)"); |
| 272 | } |
| 273 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 274 | void OriginFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 275 | printf("TODO(origin)"); |
| 276 | } |
| 277 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 278 | void FlavorFunc(const vector<Value*>&, Evaluator*, string*) { |
Shinichiro Hamaji | 4f22f5c | 2015-06-16 16:28:25 +0900 | [diff] [blame] | 279 | printf("TODO(flavor)"); |
| 280 | } |
| 281 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 282 | void InfoFunc(const vector<Value*>& args, Evaluator* ev, string*) { |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 283 | shared_ptr<string> a = args[0]->Eval(ev); |
| 284 | printf("%s\n", a->c_str()); |
| 285 | fflush(stdout); |
| 286 | } |
| 287 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 288 | void WarningFunc(const vector<Value*>& args, Evaluator* ev, string*) { |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 289 | shared_ptr<string> a = args[0]->Eval(ev); |
Shinichiro Hamaji | 8ee8c37 | 2015-06-16 16:19:40 +0900 | [diff] [blame] | 290 | printf("%s:%d: %s\n", LOCF(ev->loc()), a->c_str()); |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 291 | fflush(stdout); |
| 292 | } |
| 293 | |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 294 | void ErrorFunc(const vector<Value*>& args, Evaluator* ev, string*) { |
Shinichiro Hamaji | 9619b36 | 2015-06-16 16:13:25 +0900 | [diff] [blame] | 295 | shared_ptr<string> a = args[0]->Eval(ev); |
| 296 | ev->Error(StringPrintf("*** %s.", a->c_str())); |
| 297 | } |
| 298 | |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 299 | FuncInfo g_func_infos[] = { |
Shinichiro Hamaji | 2e6cbfc | 2015-06-16 18:46:50 +0900 | [diff] [blame] | 300 | { "patsubst", &PatsubstFunc, 3 }, |
| 301 | { "strip", &StripFunc, 1 }, |
| 302 | { "subst", &SubstFunc, 3 }, |
| 303 | { "findstring", &FindstringFunc, 2 }, |
| 304 | { "filter", &FilterFunc, 2 }, |
| 305 | { "filter-out", &FilterOutFunc, 2 }, |
| 306 | { "sort", &SortFunc, 1 }, |
| 307 | { "word", &WordFunc, 2 }, |
| 308 | { "wordlist", &WordlistFunc, 3 }, |
| 309 | { "words", &WordsFunc, 1 }, |
| 310 | { "firstword", &FirstwordFunc, 1 }, |
| 311 | { "lastword", &LastwordFunc, 1 }, |
| 312 | { "join", &JoinFunc, 2 }, |
| 313 | |
| 314 | { "wildcard", &WildcardFunc, 1 }, |
| 315 | { "dir", &DirFunc, 1 }, |
| 316 | { "notdir", &NotdirFunc, 1 }, |
| 317 | { "suffix", &SuffixFunc, 1 }, |
| 318 | { "basename", &BasenameFunc, 1 }, |
| 319 | { "addsuffix", &AddsuffixFunc, 1 }, |
| 320 | { "addprefix", &AddprefixFunc, 1 }, |
| 321 | { "realpath", &RealpathFunc, 1 }, |
| 322 | { "abspath", &AbspathFunc, 1 }, |
| 323 | { "if", &IfFunc, 1 }, |
| 324 | { "and", &AndFunc, 1 }, |
| 325 | { "or", &OrFunc, 1 }, |
| 326 | { "value", &ValueFunc, 1 }, |
| 327 | { "eval", &EvalFunc, 1 }, |
| 328 | { "shell", &ShellFunc, 1 }, |
| 329 | { "call", &CallFunc, 1 }, |
| 330 | { "foreach", &ForeachFunc, 1 }, |
| 331 | { "origin", &OriginFunc, 1 }, |
| 332 | { "flavor", &FlavorFunc, 1 }, |
| 333 | { "info", &InfoFunc, 1 }, |
| 334 | { "warning", &WarningFunc, 1 }, |
| 335 | { "error", &ErrorFunc, 1 }, |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 336 | }; |
| 337 | |
| 338 | unordered_map<StringPiece, FuncInfo*>* g_func_info_map; |
| 339 | |
| 340 | } // namespace |
| 341 | |
| 342 | void InitFuncTable() { |
| 343 | g_func_info_map = new unordered_map<StringPiece, FuncInfo*>; |
| 344 | for (size_t i = 0; i < sizeof(g_func_infos) / sizeof(g_func_infos[0]); i++) { |
| 345 | FuncInfo* fi = &g_func_infos[i]; |
| 346 | bool ok = g_func_info_map->insert(make_pair(Intern(fi->name), fi)).second; |
| 347 | CHECK(ok); |
| 348 | } |
| 349 | } |
| 350 | |
| 351 | void QuitFuncTable() { |
| 352 | delete g_func_info_map; |
| 353 | } |
| 354 | |
| 355 | FuncInfo* GetFuncInfo(StringPiece name) { |
| 356 | auto found = g_func_info_map->find(name); |
| 357 | if (found == g_func_info_map->end()) |
| 358 | return NULL; |
| 359 | return found->second; |
| 360 | } |