Not a method of the game_options class since keybindings aren't stored in that class.
| 3584 | // Not a method of the game_options class since keybindings aren't |
| 3585 | // stored in that class. |
| 3586 | static void _bindkey(string field) |
| 3587 | { |
| 3588 | const size_t start_bracket = field.find_first_of('['); |
| 3589 | const size_t end_bracket = field.find_last_of(']'); |
| 3590 | |
| 3591 | if (start_bracket == string::npos |
| 3592 | || end_bracket == string::npos |
| 3593 | || start_bracket > end_bracket) |
| 3594 | { |
| 3595 | mprf(MSGCH_ERROR, "Bad bindkey bracketing in '%s'", |
| 3596 | field.c_str()); |
| 3597 | return; |
| 3598 | } |
| 3599 | |
| 3600 | const string key_str = field.substr(start_bracket + 1, |
| 3601 | end_bracket - start_bracket - 1); |
| 3602 | const char *s = key_str.c_str(); |
| 3603 | |
| 3604 | char32_t wc; |
| 3605 | vector<char32_t> wchars; |
| 3606 | while (int l = utf8towc(&wc, s)) |
| 3607 | { |
| 3608 | s += l; |
| 3609 | wchars.push_back(wc); |
| 3610 | } |
| 3611 | |
| 3612 | |
| 3613 | int key; |
| 3614 | |
| 3615 | if (wchars.size() == 0) |
| 3616 | { |
| 3617 | mprf(MSGCH_ERROR, "No key in bindkey directive '%s'", |
| 3618 | field.c_str()); |
| 3619 | return; |
| 3620 | } |
| 3621 | else if (wchars.size() == 1) |
| 3622 | key = wchars[0]; |
| 3623 | else if (wchars[0] == '\\') |
| 3624 | { |
| 3625 | // does this need to validate non-widechars? |
| 3626 | keyseq ks = parse_keyseq(key_str); |
| 3627 | if (ks.size() != 1) |
| 3628 | { |
| 3629 | mprf(MSGCH_ERROR, "Invalid keyseq '%s' in bindkey directive '%s'", |
| 3630 | key_str.c_str(), field.c_str()); |
| 3631 | } |
| 3632 | key = ks[0]; |
| 3633 | } |
| 3634 | else // if (wchars.size() > 1) |
| 3635 | { |
| 3636 | // XX probably would be safe to directly check for numbers? |
| 3637 | // don't use the wide char version for this part |
| 3638 | // Try to read a human-readable keycode. `^` sequences handled here. |
| 3639 | key = read_key_code(key_str); |
| 3640 | if (key == CK_NO_KEY) |
| 3641 | { |
| 3642 | mprf(MSGCH_ERROR, "Invalid key '%s' in bindkey directive '%s'", |
| 3643 | key_str.c_str(), field.c_str()); |
no test coverage detected