diff options
Diffstat (limited to 'src/emu/debug/debugcmd.cpp')
-rw-r--r-- | src/emu/debug/debugcmd.cpp | 188 |
1 files changed, 111 insertions, 77 deletions
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index 730565494a4..0b7efa44a93 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -469,10 +469,14 @@ void debugger_commands::execute_print(const std::vector<std::string_view> ¶m mini_printf - safe printf to a buffer -------------------------------------------------*/ -bool debugger_commands::mini_printf(std::ostream &stream, std::string_view format, int params, u64 *param) +bool debugger_commands::mini_printf(std::ostream &stream, const std::vector<std::string_view> ¶ms) { + std::string_view const format(params[0]); auto f = format.begin(); + int param = 1; + u64 number; + // parse the string looking for % signs while (f != format.end()) { @@ -495,21 +499,48 @@ bool debugger_commands::mini_printf(std::ostream &stream, std::string_view forma // formatting else if (c == '%') { + bool left_justify = false; + bool zero_fill = false; int width = 0; - int zerofill = 0; + int precision = 0; - // parse out the width - while (f != format.end() && *f >= '0' && *f <= '9') + // parse optional left justification flag + if (f != format.end() && *f == '-') { - c = *f++; - if (c == '0' && width == 0) - zerofill = 1; - width = width * 10 + (c - '0'); + left_justify = true; + f++; + } + + // parse optional zero fill flag + if (f != format.end() && *f == '0') + { + zero_fill = true; + f++; + } + + // parse optional width + while (f != format.end() && isdigit(*f)) + width = width * 10 + (*f++ - '0'); + if (f == format.end()) + break; + + // apply left justification + if (left_justify) + width = -width; + + if ((c = *f++) == '.') + { + // parse optional precision + while (f != format.end() && isdigit(*f)) + precision = precision * 10 + (*f++ - '0'); + + // get the format + if (f != format.end()) + c = *f++; + else + break; } - if (f == format.end()) break; - // get the format - c = *f++; switch (c) { case '%': @@ -517,70 +548,89 @@ bool debugger_commands::mini_printf(std::ostream &stream, std::string_view forma break; case 'X': + if (param < params.size() && m_console.validate_number_parameter(params[param++], number)) + util::stream_format(stream, zero_fill ? "%0*X" : "%*X", width, number); + else + { + m_console.printf("Not enough parameters for format!\n"); + return false; + } + break; case 'x': - if (params == 0) + if (param < params.size() && m_console.validate_number_parameter(params[param++], number)) + util::stream_format(stream, zero_fill ? "%0*x" : "%*x", width, number); + else { m_console.printf("Not enough parameters for format!\n"); return false; } - if (u32(*param >> 32) != 0) - util::stream_format(stream, zerofill ? "%0*X" : "%*X", (width <= 8) ? 1 : width - 8, u32(*param >> 32)); - else if (width > 8) - util::stream_format(stream, zerofill ? "%0*X" : "%*X", width - 8, 0); - util::stream_format(stream, zerofill ? "%0*X" : "%*X", (width < 8) ? width : 8, u32(*param)); - param++; - params--; break; case 'O': case 'o': - if (params == 0) + if (param < params.size() && m_console.validate_number_parameter(params[param++], number)) + util::stream_format(stream, zero_fill ? "%0*o" : "%*o", width, number); + else { m_console.printf("Not enough parameters for format!\n"); return false; } - if (u32(*param >> 60) != 0) - { - util::stream_format(stream, zerofill ? "%0*o" : "%*o", (width <= 20) ? 1 : width - 20, u32(*param >> 60)); - util::stream_format(stream, "%0*o", 10, u32(BIT(*param, 30, 30))); - } - else - { - if (width > 20) - util::stream_format(stream, zerofill ? "%0*o" : "%*o", width - 20, 0); - if (u32(BIT(*param, 30, 30)) != 0) - util::stream_format(stream, zerofill ? "%0*o" : "%*o", (width <= 10) ? 1 : width - 10, u32(BIT(*param, 30, 30))); - else if (width > 10) - util::stream_format(stream, zerofill ? "%0*o" : "%*o", width - 10, 0); - } - util::stream_format(stream, zerofill ? "%0*o" : "%*o", (width < 10) ? width : 10, u32(BIT(*param, 0, 30))); - param++; - params--; break; case 'D': case 'd': - if (params == 0) + if (param < params.size() && m_console.validate_number_parameter(params[param++], number)) + util::stream_format(stream, zero_fill ? "%0*d" : "%*d", width, number); + else { m_console.printf("Not enough parameters for format!\n"); return false; } - util::stream_format(stream, zerofill ? "%0*d" : "%*d", width, u32(*param)); - param++; - params--; break; + case 'C': case 'c': - if (params == 0) + if (param < params.size() && m_console.validate_number_parameter(params[param++], number)) + stream << char(number); + else { m_console.printf("Not enough parameters for format!\n"); return false; } - stream << char(*param); - param++; - params--; break; + case 's': + { + address_space *space; + if (param < params.size() && m_console.validate_target_address_parameter(params[param++], -1, space, number)) + { + address_space *tspace; + std::string s; + + for (u32 address = u32(number), taddress; space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, taddress = address, tspace); address++) + { + u8 const data = tspace->read_byte(taddress); + + if (!data) + break; + + s += data; + + if (precision == 1) + break; + else if (precision) + precision--; + } + + util::stream_format(stream, "%*s", width, s); + } + else + { + m_console.printf("Not enough parameters for format!\n"); + return false; + } + } + break; } } @@ -630,15 +680,9 @@ void debugger_commands::execute_index_command(std::vector<std::string_view> cons void debugger_commands::execute_printf(const std::vector<std::string_view> ¶ms) { - /* validate the other parameters */ - u64 values[MAX_COMMAND_PARAMS]; - for (int i = 1; i < params.size(); i++) - if (!m_console.validate_number_parameter(params[i], values[i])) - return; - /* then do a printf */ std::ostringstream buffer; - if (mini_printf(buffer, params[0], params.size() - 1, &values[1])) + if (mini_printf(buffer, params)) m_console.printf("%s\n", std::move(buffer).str()); } @@ -649,15 +693,9 @@ void debugger_commands::execute_printf(const std::vector<std::string_view> ¶ void debugger_commands::execute_logerror(const std::vector<std::string_view> ¶ms) { - /* validate the other parameters */ - u64 values[MAX_COMMAND_PARAMS]; - for (int i = 1; i < params.size(); i++) - if (!m_console.validate_number_parameter(params[i], values[i])) - return; - /* then do a printf */ std::ostringstream buffer; - if (mini_printf(buffer, params[0], params.size() - 1, &values[1])) + if (mini_printf(buffer, params)) m_machine.logerror("%s", std::move(buffer).str()); } @@ -668,15 +706,9 @@ void debugger_commands::execute_logerror(const std::vector<std::string_view> &pa void debugger_commands::execute_tracelog(const std::vector<std::string_view> ¶ms) { - /* validate the other parameters */ - u64 values[MAX_COMMAND_PARAMS]; - for (int i = 1; i < params.size(); i++) - if (!m_console.validate_number_parameter(params[i], values[i])) - return; - /* then do a printf */ std::ostringstream buffer; - if (mini_printf(buffer, params[0], params.size() - 1, &values[1])) + if (mini_printf(buffer, params)) m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str()); } @@ -688,12 +720,11 @@ void debugger_commands::execute_tracelog(const std::vector<std::string_view> &pa void debugger_commands::execute_tracesym(const std::vector<std::string_view> ¶ms) { // build a format string appropriate for the parameters and validate them - std::stringstream format; - u64 values[MAX_COMMAND_PARAMS]; + std::ostringstream format; for (int i = 0; i < params.size(); i++) { // find this symbol - symbol_entry *sym = m_console.visible_symtable().find(strmakelower(params[i]).c_str()); + symbol_entry *const sym = m_console.visible_symtable().find(strmakelower(params[i]).c_str()); if (!sym) { m_console.printf("Unknown symbol: %s\n", params[i]); @@ -704,15 +735,18 @@ void debugger_commands::execute_tracesym(const std::vector<std::string_view> &pa util::stream_format(format, "%s=%s ", params[i], sym->format().empty() ? "%16X" : sym->format()); - - // validate the parameter - if (!m_console.validate_number_parameter(params[i], values[i])) - return; } + // build parameters for printf + auto const format_str = std::move(format).str(); // need this to stay put as long as the string_view exists + std::vector<std::string_view> printf_params; + printf_params.reserve(params.size() + 1); + printf_params.emplace_back(format_str); + std::copy(params.begin(), params.end(), std::back_inserter(printf_params)); + // then do a printf std::ostringstream buffer; - if (mini_printf(buffer, format.str(), params.size(), values)) + if (mini_printf(buffer, printf_params)) m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str()); } @@ -3483,16 +3517,16 @@ void debugger_commands::execute_trace(const std::vector<std::string_view> ¶m using namespace std::literals; if (!util::streqlower(filename, "off"sv)) { - std::ios_base::openmode mode = std::ios_base::out; + std::ios_base::openmode mode; // opening for append? if ((filename[0] == '>') && (filename[1] == '>')) { - mode |= std::ios_base::ate; + mode = std::ios_base::in | std::ios_base::out | std::ios_base::ate; filename = filename.substr(2); } else - mode |= std::ios_base::trunc; + mode = std::ios_base::out | std::ios_base::trunc; f = std::make_unique<std::ofstream>(filename.c_str(), mode); if (f->fail()) |