Unified · Split
| @@ -770,7 +770,7 @@ namespace · 769 unmodified lines | |||
| 770 | } | 770 | } |
| 771 | 771 | ||
| 772 | // [TODO] Didn't find the cmd, try ignoring case? | 772 | // [TODO] Didn't find the cmd, try ignoring case? |
| 773 | return nullptr; | 773 | throw debug_cmd_error_t{ "Unknown command. '?' for help." }; |
| 774 | } | 774 | } |
| 775 | 775 | ||
| 776 | void print_help() | 776 | void print_help() |
| @@ -797,31 +797,6 @@ namespace · 20 unmodified lines | |||
| 797 | debug_print_info(ss.str()); | 797 | debug_print_info(ss.str()); |
| 798 | } | 798 | } |
| 799 | 799 | ||
| 800 | // split the string using the supplied delimiter | ||
| 801 | std::vector<std::string> split(const std::string &str, const char delim = ' ') | ||
| 802 | { | ||
| 803 | auto split_string = std::vector<std::string>{}; | ||
| 804 | |||
| 805 | auto curr = str.begin(); | ||
| 806 | auto end = str.cend(); | ||
| 807 | while (curr != end) | ||
| 808 | { | ||
| 809 | auto curr_begin = curr; | ||
| 810 | while (curr != end && *curr != delim) | ||
| 811 | ++curr; | ||
| 812 | |||
| 813 | if (curr_begin != curr) | ||
| 814 | split_string.push_back(std::move(std::string{ curr_begin, curr })); | ||
| 815 | |||
| 816 | if (curr == end) | ||
| 817 | break; | ||
| 818 | |||
| 819 | ++curr; | ||
| 820 | } | ||
| 821 | |||
| 822 | return split_string; | ||
| 823 | } | ||
| 824 | |||
| 825 | void prompt(debugger &debugger, const vm_registers_t &r) | 800 | void prompt(debugger &debugger, const vm_registers_t &r) |
| 826 | { | 801 | { |
| 827 | debugger.controller->suspend_all_threads(); | 802 | debugger.controller->suspend_all_threads(); |
| @@ -845,22 +820,13 @@ namespace · 17 unmodified lines | |||
| 845 | << console_modifiers::reset_all; | 820 | << console_modifiers::reset_all; |
| 846 | 821 | ||
| 847 | std::getline(std::cin, cmd); | 822 | std::getline(std::cin, cmd); |
| 848 | if (cmd.empty()) | 823 | const auto cmd_tokens = util::split(cmd); |
| 849 | continue; | ||
| 850 | |||
| 851 | const auto cmd_tokens = split(cmd); | ||
| 852 | if (cmd_tokens.empty()) | 824 | if (cmd_tokens.empty()) |
| 853 | continue; | 825 | continue; |
| 854 | 826 | ||
| 855 | auto cmd_exec = find_cmd(cmd_tokens[0]); | ||
| 856 | if (cmd_exec == nullptr) | ||
| 857 | { | ||
| 858 | debug_print_error("Unknown command. '?' for help."); | ||
| 859 | continue; | ||
| 860 | } | ||
| 861 | |||
| 862 | try | 827 | try |
| 863 | { | 828 | { |
| 829 | auto cmd_exec = find_cmd(cmd_tokens[0]); | ||
| 864 | cmd_exec(cmd_tokens, cxt); | 830 | cmd_exec(cmd_tokens, cxt); |
| 865 | if (cxt.exit_break) | 831 | if (cxt.exit_break) |
| 866 | break; | 832 | break; |
| @@ -9,28 +9,62 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #include <cstdint> | 10 | #include <cstdint> |
| 11 | #include <type_traits> | 11 | #include <type_traits> |
| 12 | #include <string> | ||
| 13 | #include <cstring> | ||
| 14 | #include <vector> | ||
| 12 | 15 | ||
| 13 | namespace disvm | 16 | namespace disvm |
| 14 | { | 17 | { |
| 15 | namespace util | 18 | namespace util |
| 16 | { | 19 | { |
| 17 | template<typename Flags> | 20 | template<typename Flags> |
| 18 | inline bool has_flag(const Flags flags, const Flags flag) | 21 | bool has_flag(const Flags flags, const Flags flag) |
| 19 | { | 22 | { |
| 20 | return (static_cast<std::underlying_type_t<Flags>>(flags) & static_cast<std::underlying_type_t<Flags>>(flag)) != 0; | 23 | return (static_cast<std::underlying_type_t<Flags>>(flags) & static_cast<std::underlying_type_t<Flags>>(flag)) != 0; |
| 21 | } | 24 | } |
| 22 | 25 | ||
| 23 | template <typename T1, typename T2> | 26 | template <typename T1, typename T2> |
| 24 | inline bool are_equal(const T1 &l, const T2 &r) | 27 | bool are_equal(const T1 &l, const T2 &r) |
| 25 | { | 28 | { |
| 26 | return (l == r); | 29 | return (l == r); |
| 27 | } | 30 | } |
| 28 | 31 | ||
| 29 | template <typename T1, typename T2, typename... Others> | 32 | template <typename T1, typename T2, typename... Others> |
| 30 | inline bool are_equal(const T1 &l, const T2 &r, const Others &... args) | 33 | bool are_equal(const T1 &l, const T2 &r, const Others &... args) |
| 31 | { | 34 | { |
| 32 | return (l == r) && are_equal(r, args...); | 35 | return (l == r) && are_equal(r, args...); |
| 33 | } | 36 | } |
| 37 | |||
| 38 | // split the string using the delimiters contained in the supplied string | ||
| 39 | inline std::vector<std::string> split(const std::string &str, const char *delims) | ||
| 40 | { | ||
| 41 | auto split_string = std::vector<std::string>{}; | ||
| 42 | |||
| 43 | auto curr = str.begin(); | ||
| 44 | auto end = str.cend(); | ||
| 45 | while (curr != end) | ||
| 46 | { | ||
| 47 | auto curr_begin = curr; | ||
| 48 | |||
| 49 | while (curr != end && (nullptr == std::strchr(delims, *curr))) | ||
| 50 | ++curr; | ||
| 51 | |||
| 52 | if (curr_begin != curr) | ||
| 53 | split_string.push_back(std::move(std::string{ curr_begin, curr })); | ||
| 54 | |||
| 55 | if (curr == end) | ||
| 56 | break; | ||
| 57 | |||
| 58 | ++curr; | ||
| 59 | } | ||
| 60 | |||
| 61 | return split_string; | ||
| 62 | } | ||
| 63 | |||
| 64 | inline std::vector<std::string> split(const std::string &str) | ||
| 65 | { | ||
| 66 | return split(str, " "); | ||
| 67 | } | ||
| 34 | } | 68 | } |
| 35 | } | 69 | } |
| 36 | 70 | ||