summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/debug/textbuf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/debug/textbuf.cpp')
-rw-r--r--src/emu/debug/textbuf.cpp332
1 files changed, 182 insertions, 150 deletions
diff --git a/src/emu/debug/textbuf.cpp b/src/emu/debug/textbuf.cpp
index 279ce8dead6..c70f8660185 100644
--- a/src/emu/debug/textbuf.cpp
+++ b/src/emu/debug/textbuf.cpp
@@ -2,15 +2,16 @@
// copyright-holders:Aaron Giles
/***************************************************************************
- textbuf.c
+ textbuf.cpp
Debugger text buffering engine.
***************************************************************************/
-#include "corealloc.h"
#include "textbuf.h"
+#include <new>
+
/***************************************************************************
@@ -27,47 +28,46 @@
struct text_buffer
{
- char * buffer;
- s32 * lineoffs;
- s32 bufsize;
- s32 bufstart;
- s32 bufend;
- s32 linesize;
- s32 linestart;
- s32 lineend;
- u32 linestartseq;
- s32 maxwidth;
-};
-
-
-
-/***************************************************************************
- INLINE FUNCTIONS
-***************************************************************************/
-
-/*-------------------------------------------------
- buffer_used - return the number of bytes
- currently held in the buffer
--------------------------------------------------*/
-
-static inline s32 buffer_used(text_buffer *text)
-{
- s32 used = text->bufend - text->bufstart;
- if (used < 0)
- used += text->bufsize;
- return used;
-}
+ text_buffer(u32 bytes, u32 lines) noexcept
+ : buffer(new (std::nothrow) char [bytes])
+ , lineoffs(new (std::nothrow) s32 [lines])
+ , bufsize(buffer ? bytes : 0)
+ , linesize(lineoffs ? lines : 0)
+ {
+ }
+ std::unique_ptr<char []> const buffer;
+ std::unique_ptr<s32 []> const lineoffs;
+ s32 const bufsize;
+ s32 bufstart = 0;
+ s32 bufend = 0;
+ s32 const linesize;
+ s32 linestart = 0;
+ s32 lineend = 0;
+ u32 linestartseq = 0;
+ s32 maxwidth = 0;
+
+ /*-------------------------------------------------
+ buffer_used - return the number of bytes
+ currently held in the buffer
+ -------------------------------------------------*/
+
+ s32 buffer_used() const noexcept
+ {
+ s32 const used(bufend - bufstart);
+ return (used < 0) ? (used + bufsize) : used;
+ }
-/*-------------------------------------------------
- buffer_space - return the number of bytes
- available in the buffer
--------------------------------------------------*/
+ /*-------------------------------------------------
+ buffer_space - return the number of bytes
+ available in the buffer
+ -------------------------------------------------*/
-static inline s32 buffer_space(text_buffer *text)
-{
- return text->bufsize - buffer_used(text);
-}
+ s32 buffer_space() const noexcept
+ {
+ return bufsize - buffer_used();
+ }
+};
@@ -81,36 +81,19 @@ static inline s32 buffer_space(text_buffer *text)
text_buffer_alloc - allocate a new text buffer
-------------------------------------------------*/
-text_buffer *text_buffer_alloc(u32 bytes, u32 lines)
+text_buffer_ptr text_buffer_alloc(u32 bytes, u32 lines)
{
- text_buffer *text;
+ // allocate memory for the text buffer object
+ text_buffer_ptr text(new (std::nothrow) text_buffer(bytes, lines));
- /* allocate memory for the text buffer object */
- text = global_alloc_nothrow(text_buffer);
if (!text)
return nullptr;
- /* allocate memory for the buffer itself */
- text->buffer = global_alloc_array_nothrow(char, bytes);
- if (!text->buffer)
- {
- global_free(text);
- return nullptr;
- }
-
- /* allocate memory for the lines array */
- text->lineoffs = global_alloc_array_nothrow(s32, lines);
- if (!text->lineoffs)
- {
- global_free_array(text->buffer);
- global_free(text);
+ if (!text->buffer || !text->lineoffs)
return nullptr;
- }
- /* initialize the buffer description */
- text->bufsize = bytes;
- text->linesize = lines;
- text_buffer_clear(text);
+ // initialize the buffer description
+ text_buffer_clear(*text);
return text;
}
@@ -121,13 +104,9 @@ text_buffer *text_buffer_alloc(u32 bytes, u32 lines)
text buffer
-------------------------------------------------*/
-void text_buffer_free(text_buffer *text)
+void text_buffer_deleter::operator()(text_buffer *text) const
{
- if (text->lineoffs)
- global_free_array(text->lineoffs);
- if (text->buffer)
- global_free_array(text->buffer);
- global_free(text);
+ delete text;
}
@@ -135,21 +114,21 @@ void text_buffer_free(text_buffer *text)
text_buffer_clear - clear a text buffer
-------------------------------------------------*/
-void text_buffer_clear(text_buffer *text)
+void text_buffer_clear(text_buffer &text)
{
- /* reset all the buffer pointers and other bits */
- text->bufstart = 0;
- text->bufend = 0;
+ // reset all the buffer pointers and other bits
+ text.bufstart = 0;
+ text.bufend = 0;
- text->linestart = 0;
- text->lineend = 0;
- text->linestartseq = 0;
+ text.linestart = 0;
+ text.lineend = 0;
+ text.linestartseq = 0;
- text->maxwidth = 0;
+ text.maxwidth = 0;
- /* create the initial line */
- text->lineoffs[0] = 0;
- text->buffer[text->lineoffs[0]] = 0;
+ // create the initial line
+ text.lineoffs[0] = 0;
+ text.buffer[text.lineoffs[0]] = 0;
}
@@ -160,109 +139,107 @@ void text_buffer_clear(text_buffer *text)
***************************************************************************/
-/*-------------------------------------------------
- text_buffer_print - print data to the text
- buffer
--------------------------------------------------*/
+//-------------------------------------------------
+// text_buffer_print - print data to the text
+// buffer
+//-------------------------------------------------
-void text_buffer_print(text_buffer *text, const char *data)
+void text_buffer_print(text_buffer &text, std::string_view data)
{
- text_buffer_print_wrap(text, data, 10000);
+ text_buffer_print_wrap(text, data, MAX_LINE_LENGTH);
}
-/*-------------------------------------------------
- text_buffer_print_wrap - print data to the
- text buffer with word wrapping to a given
- column
--------------------------------------------------*/
+//-------------------------------------------------
+// text_buffer_print_wrap - print data to the
+// text buffer with word wrapping to a given
+// column
+//-------------------------------------------------
-void text_buffer_print_wrap(text_buffer *text, const char *data, int wrapcol)
+void text_buffer_print_wrap(text_buffer &text, std::string_view data, int wrapcol)
{
- s32 stopcol = (wrapcol < MAX_LINE_LENGTH) ? wrapcol : MAX_LINE_LENGTH;
- s32 needed_space;
+ s32 const stopcol = (wrapcol < MAX_LINE_LENGTH) ? wrapcol : MAX_LINE_LENGTH;
- /* we need to ensure there is enough space for this string plus enough for the max line length */
- needed_space = s32(strlen(data)) + MAX_LINE_LENGTH;
+ // we need to ensure there is enough space for this string plus enough for the max line length
+ s32 const needed_space = s32(data.length()) + MAX_LINE_LENGTH;
- /* make space in the buffer if we need to */
- while (buffer_space(text) < needed_space && text->linestart != text->lineend)
+ // make space in the buffer if we need to
+ while (text.buffer_space() < needed_space && text.linestart != text.lineend)
{
- text->linestartseq++;
- if (++text->linestart >= text->linesize)
- text->linestart = 0;
- text->bufstart = text->lineoffs[text->linestart];
+ text.linestartseq++;
+ if (++text.linestart >= text.linesize)
+ text.linestart = 0;
+ text.bufstart = text.lineoffs[text.linestart];
}
- /* now add the data */
- for ( ; *data; data++)
+ // now add the data
+ for (int ch : data)
{
- int ch = *data;
int linelen;
- /* a CR resets our position */
+ // a CR resets our position
if (ch == '\r')
- text->bufend = text->lineoffs[text->lineend];
+ text.bufend = text.lineoffs[text.lineend];
- /* non-CR data is just characters */
+ // non-CR data is just characters
else if (ch != '\n')
- text->buffer[text->bufend++] = ch;
+ text.buffer[text.bufend++] = ch;
- /* an explicit newline or line-too-long condition inserts a newline */
- linelen = text->bufend - text->lineoffs[text->lineend];
+ // an explicit newline or line-too-long condition inserts a newline */
+ linelen = text.bufend - text.lineoffs[text.lineend];
if (ch == '\n' || linelen >= stopcol)
{
int overflow = 0;
- /* if we're wrapping, back off until we hit a space */
+ // if we're wrapping, back off until we hit a space
if (linelen >= wrapcol)
{
- /* scan backwards, removing characters along the way */
+ // scan backwards, removing characters along the way
overflow = 1;
- while (overflow < linelen && text->buffer[text->bufend - overflow] != ' ')
+ while (overflow < linelen && text.buffer[text.bufend - overflow] != ' ')
overflow++;
- /* if we found a space, take it; otherwise, reset and pretend we didn't try */
+ // if we found a space, take it; otherwise, reset and pretend we didn't try
if (overflow < linelen)
linelen -= overflow;
else
overflow = 0;
}
- /* did we beat the max width */
- if (linelen > text->maxwidth)
- text->maxwidth = linelen;
+ // did we beat the max width
+ if (linelen > text.maxwidth)
+ text.maxwidth = linelen;
- /* append a terminator */
+ // append a terminator
if (overflow == 0)
- text->buffer[text->bufend++] = 0;
+ text.buffer[text.bufend++] = 0;
else
- text->buffer[text->bufend - overflow] = 0;
+ text.buffer[text.bufend - overflow] = 0;
- /* determine what the next line will be */
- if (++text->lineend >= text->linesize)
- text->lineend = 0;
+ // determine what the next line will be
+ if (++text.lineend >= text.linesize)
+ text.lineend = 0;
- /* if we're out of lines, consume the next one */
- if (text->lineend == text->linestart)
+ // if we're out of lines, consume the next one
+ if (text.lineend == text.linestart)
{
- text->linestartseq++;
- if (++text->linestart >= text->linesize)
- text->linestart = 0;
- text->bufstart = text->lineoffs[text->linestart];
+ text.linestartseq++;
+ if (++text.linestart >= text.linesize)
+ text.linestart = 0;
+ text.bufstart = text.lineoffs[text.linestart];
}
- /* if we don't have enough room in the buffer for a max line, wrap to the start */
- if (text->bufend + MAX_LINE_LENGTH + 1 >= text->bufsize)
- text->bufend = 0;
+ // if we don't have enough room in the buffer for a max line, wrap to the start
+ if (text.bufend + MAX_LINE_LENGTH + 1 >= text.bufsize)
+ text.bufend = 0;
- /* create a new empty line */
- text->lineoffs[text->lineend] = text->bufend - (overflow ? (overflow - 1) : 0);
+ // create a new empty line
+ text.lineoffs[text.lineend] = text.bufend - (overflow ? (overflow - 1) : 0);
}
}
- /* nullptr terminate what we have on this line */
- text->buffer[text->bufend] = 0;
+ // null terminate what we have on this line
+ text.buffer[text.bufend] = 0;
}
@@ -278,9 +255,9 @@ void text_buffer_print_wrap(text_buffer *text, const char *data, int wrapcol)
width of all lines seen so far
-------------------------------------------------*/
-u32 text_buffer_max_width(text_buffer *text)
+u32 text_buffer_max_width(text_buffer const &text)
{
- return text->maxwidth;
+ return text.maxwidth;
}
@@ -289,12 +266,10 @@ u32 text_buffer_max_width(text_buffer *text)
lines in the text buffer
-------------------------------------------------*/
-u32 text_buffer_num_lines(text_buffer *text)
+u32 text_buffer_num_lines(text_buffer const &text)
{
- s32 lines = text->lineend + 1 - text->linestart;
- if (lines <= 0)
- lines += text->linesize;
- return lines;
+ s32 const lines = text.lineend + 1 - text.linestart;
+ return (lines <= 0) ? (lines + text.linesize) : lines;
}
@@ -303,9 +278,9 @@ u32 text_buffer_num_lines(text_buffer *text)
line index into a sequence number
-------------------------------------------------*/
-u32 text_buffer_line_index_to_seqnum(text_buffer *text, u32 index)
+u32 text_buffer_line_index_to_seqnum(text_buffer const &text, u32 index)
{
- return text->linestartseq + index;
+ return text.linestartseq + index;
}
@@ -314,11 +289,68 @@ u32 text_buffer_line_index_to_seqnum(text_buffer *text, u32 index)
an indexed line in the buffer
-------------------------------------------------*/
-const char *text_buffer_get_seqnum_line(text_buffer *text, u32 seqnum)
+const char *text_buffer_get_seqnum_line(text_buffer const &text, u32 seqnum)
{
- u32 numlines = text_buffer_num_lines(text);
- u32 index = seqnum - text->linestartseq;
+ u32 const numlines = text_buffer_num_lines(text);
+ u32 const index = seqnum - text.linestartseq;
if (index >= numlines)
return nullptr;
- return &text->buffer[text->lineoffs[(text->linestart + index) % text->linesize]];
+ return &text.buffer[text.lineoffs[(text.linestart + index) % text.linesize]];
+}
+
+/*---------------------------------------------------------------------
+ text_buffer_lines::text_buffer_line_iterator::operator*
+ Gets the line that the iterator currently points to.
+-----------------------------------------------------------------------*/
+
+std::string_view text_buffer_lines::text_buffer_line_iterator::operator*() const
+{
+ char const *const line = &m_buffer.buffer[m_buffer.lineoffs[m_lineptr]];
+
+ auto next_lineptr = m_lineptr + 1;
+ if (next_lineptr == m_buffer.linesize)
+ next_lineptr = 0;
+
+ char const *const 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 std::string_view{ line, std::string_view::size_type(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);
}