* Takes as argument a string, and returns a sequence of keys described * by the string. Most characters produce their own ASCII code. These * are the cases: * \\ produces the ASCII code of a single \ * \{123} produces 123 (decimal) * \{^A} produces 1 (Ctrl-A) * \{x40} produces 64 (hexadecimal code) * \{!more} or \{!m} disables -more- prompt until the end of the macro. */
| 396 | * \{!more} or \{!m} disables -more- prompt until the end of the macro. |
| 397 | */ |
| 398 | keyseq parse_keyseq(string s) |
| 399 | { |
| 400 | // TODO parse readable descriptions of special keys, e.g. \{F1} or something |
| 401 | int state = 0; |
| 402 | keyseq v; |
| 403 | |
| 404 | if (starts_with(s, "===")) |
| 405 | { |
| 406 | buf2keyseq(s.c_str(), v); |
| 407 | return v; |
| 408 | } |
| 409 | |
| 410 | bool more_reset = false; |
| 411 | for (int i = 0, size = s.length(); i < size; ++i) |
| 412 | { |
| 413 | char c = s[i]; |
| 414 | |
| 415 | switch (state) |
| 416 | { |
| 417 | case 0: // Normal state |
| 418 | if (c == '\\') |
| 419 | state = 1; |
| 420 | else |
| 421 | v.push_back(c); |
| 422 | break; |
| 423 | |
| 424 | case 1: // Last char is a '\' |
| 425 | if (c == '\\') |
| 426 | { |
| 427 | state = 0; |
| 428 | v.push_back(c); |
| 429 | } |
| 430 | else if (c == '{') |
| 431 | state = 2; |
| 432 | // XXX Error handling |
| 433 | break; |
| 434 | |
| 435 | case 2: // Inside \{} |
| 436 | { |
| 437 | const string::size_type clb = s.find('}', i); |
| 438 | if (clb == string::npos) |
| 439 | break; |
| 440 | |
| 441 | const string arg = s.substr(i, clb - i); |
| 442 | if (!more_reset && (arg == "!more" || arg == "!m")) |
| 443 | { |
| 444 | more_reset = true; |
| 445 | v.push_back(KEY_MACRO_MORE_PROTECT); |
| 446 | } |
| 447 | else |
| 448 | { |
| 449 | const int key = read_key_code(arg); |
| 450 | v.push_back(key); |
| 451 | } |
| 452 | |
| 453 | state = 0; |
| 454 | i = clb; |
| 455 | break; |
no test coverage detected