diff options
author | 2020-06-06 11:31:33 -0400 | |
---|---|---|
committer | 2020-06-07 01:31:33 +1000 | |
commit | 8b021e8bf3aa30abd9e9d2d88d2d00a935bc9a4a (patch) | |
tree | c90a08efb5bc4d8204e3b72eca08a9fec8162e80 | |
parent | fe2802711c29b37272c2e05a1c61ba04ffbf1435 (diff) |
Debugger: add `condump` command to export console buffer to a log file (#6781)
This is another debugger enhancement -- it allows you to export the
current contents of the debug console window to a file.
The filename parsing is based on the `trace` command, and as such,
supports both the "{game}" placeholder, and the ">>" prefix for
appending instead of overwriting.
-rw-r--r-- | src/emu/debug/debugcon.cpp | 37 | ||||
-rw-r--r-- | src/emu/debug/debugcon.h | 1 | ||||
-rw-r--r-- | src/emu/debug/textbuf.cpp | 63 | ||||
-rw-r--r-- | src/emu/debug/textbuf.h | 49 |
4 files changed, 149 insertions, 1 deletions
diff --git a/src/emu/debug/debugcon.cpp b/src/emu/debug/debugcon.cpp index 692c7945445..0b4ae76c95b 100644 --- a/src/emu/debug/debugcon.cpp +++ b/src/emu/debug/debugcon.cpp @@ -65,6 +65,7 @@ debugger_console::debugger_console(running_machine &machine) /* register our own custom-command help */ register_command("helpcustom", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_console::execute_help_custom, this, _1, _2)); + register_command("condump", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_console::execute_condump, this, _1, _2)); /* first CPU is visible by default */ for (device_t &device : device_iterator(m_machine.root_device())) @@ -139,6 +140,42 @@ void debugger_console::execute_help_custom(int ref, const std::vector<std::strin } } +/*------------------------------------------------------------ + execute_condump - execute the condump command +------------------------------------------------------------*/ + +void debugger_console::execute_condump(int ref, const std::vector<std::string>& params) +{ + std::string filename = params[0]; + const char* mode; + + /* replace macros */ + strreplace(filename, "{game}", m_machine.basename()); + + mode = "w"; + /* opening for append? */ + if ((filename[0] == '>') && (filename[1] == '>')) + { + mode = "a"; + filename = filename.substr(2); + } + + FILE* f = fopen(filename.c_str(), mode); + if (!f) + { + printf("Error opening file '%s'\n", filename.c_str()); + return; + } + + for (auto line_info : text_buffer_get_lines(m_console_textbuf)) + { + fwrite(line_info.text, sizeof(char), line_info.length, f); + fputc('\n', f); + } + + fclose(f); + printf("Wrote console contents to '%s'\n", filename.c_str()); +} //------------------------------------------------- // visible_symtable - return the locally-visible diff --git a/src/emu/debug/debugcon.h b/src/emu/debug/debugcon.h index 3979393f836..949b236774a 100644 --- a/src/emu/debug/debugcon.h +++ b/src/emu/debug/debugcon.h @@ -117,6 +117,7 @@ private: void exit(); void execute_help_custom(int ref, const std::vector<std::string> ¶ms); + void execute_condump(int ref, const std::vector<std::string>& params); void trim_parameter(char **paramptr, bool keep_quotes); CMDERR internal_execute_command(bool execute, int params, char **param); diff --git a/src/emu/debug/textbuf.cpp b/src/emu/debug/textbuf.cpp index fea5ed31c9c..dd30beec210 100644 --- a/src/emu/debug/textbuf.cpp +++ b/src/emu/debug/textbuf.cpp @@ -311,3 +311,66 @@ const char *text_buffer_get_seqnum_line(text_buffer *text, u32 seqnum) return nullptr; return &text->buffer[text->lineoffs[(text->linestart + index) % text->linesize]]; } + +text_buffer_lines text_buffer_get_lines(text_buffer* text) +{ + return text_buffer_lines(*text); +} + +/*--------------------------------------------------------------------- + text_buffer_lines::text_buffer_line_iterator::operator* + Gets the line that the iterator currently points to. +-----------------------------------------------------------------------*/ + +text_buffer_line text_buffer_lines::text_buffer_line_iterator::operator*() const +{ + const char* line = &m_buffer.buffer[m_buffer.lineoffs[m_lineptr]]; + + auto next_lineptr = m_lineptr + 1; + if (next_lineptr == m_buffer.linesize) + next_lineptr = 0; + + const char* nextline = &m_buffer.buffer[m_buffer.lineoffs[next_lineptr]]; + + /* -1 for the '\0' at the end of line */ + + ptrdiff_t difference = (nextline - line) - 1; + + if (difference < 0) + difference += m_buffer.bufsize; + + return text_buffer_line{ line, (size_t)difference }; +} + +/*--------------------------------------------------------------------- + text_buffer_lines::text_buffer_line_iterator::operator++ + Moves to the next line. +-----------------------------------------------------------------------*/ + +text_buffer_lines::text_buffer_line_iterator& text_buffer_lines::text_buffer_line_iterator::operator++() +{ + if (++m_lineptr == m_buffer.linesize) + m_lineptr = 0; + + return *this; +} + +/*------------------------------------------------------ + text_buffer_lines::begin() + Returns an iterator that points to the first line. +--------------------------------------------------------*/ + +text_buffer_lines::iterator text_buffer_lines::begin() const +{ + return text_buffer_line_iterator(m_buffer, m_buffer.linestart); +} + +/*----------------------------------------------------------- + text_buffer_lines::begin() + Returns an iterator that points just past the last line. +-------------------------------------------------------------*/ + +text_buffer_lines::iterator text_buffer_lines::end() const +{ + return text_buffer_line_iterator(m_buffer, m_buffer.lineend); +} diff --git a/src/emu/debug/textbuf.h b/src/emu/debug/textbuf.h index 9d42c3032ce..d678dd7779a 100644 --- a/src/emu/debug/textbuf.h +++ b/src/emu/debug/textbuf.h @@ -19,7 +19,52 @@ struct text_buffer; - +struct text_buffer_line +{ + const char *text; + size_t length; +}; + +/* helper class that makes it possible to iterate over the lines of a text_buffer */ +class text_buffer_lines +{ +private: + text_buffer& m_buffer; + +public: + text_buffer_lines(text_buffer& buffer) : m_buffer(buffer) { } + + class text_buffer_line_iterator + { + text_buffer& m_buffer; + s32 m_lineptr; + public: + text_buffer_line_iterator(text_buffer& buffer, s32 lineptr) : + m_buffer(buffer), + m_lineptr(lineptr) + { + } + + /* technically this isn't a valid forward iterator, because + * operator * doesn't return a reference + */ + text_buffer_line operator *() const; + text_buffer_line_iterator& operator ++(); + + bool operator != (const text_buffer_line_iterator& rhs) + { + return m_lineptr != rhs.m_lineptr; + } + /* according to C++ spec, only != is needed; == is present for completeness. */ + bool operator == (const text_buffer_line_iterator& rhs) { return !(operator !=(rhs)); } + }; + + typedef text_buffer_line_iterator iterator; + typedef text_buffer_line_iterator const iterator_const; + + iterator begin() const; + iterator end() const; +}; /*************************************************************************** FUNCTION PROTOTYPES @@ -52,5 +97,7 @@ u32 text_buffer_line_index_to_seqnum(text_buffer *text, u32 index); /* get a sequenced line from the text buffer */ const char *text_buffer_get_seqnum_line(text_buffer *text, u32 seqnum); +/* get an iterable container of the lines in the buffer */ +text_buffer_lines text_buffer_get_lines(text_buffer* text); #endif /* MAME_EMU_DEBUG_TEXTBUF_H */ |