mirror of
https://github.com/holub/mame
synced 2025-06-10 06:47:18 +03:00

This removes all allocation code from pstring. const_iterator is consequently now based on pstring::const_iterator. Removed pstring_buffer. This was class wasn't a good idea. Vas was right: This change did not impact runtime performance. Startup performance (string intensive) increased. (nw)
136 lines
2.8 KiB
C++
136 lines
2.8 KiB
C++
// license:GPL-2.0+
|
|
// copyright-holders:Couriersud
|
|
/*
|
|
* nl_string.c
|
|
*
|
|
*/
|
|
|
|
#include "pfmtlog.h"
|
|
#include "palloc.h"
|
|
|
|
#include <cstring>
|
|
#include <cstdlib>
|
|
#include <cstdarg>
|
|
#include <algorithm>
|
|
|
|
//* FIXME: remove cstring, replace with pstring */
|
|
|
|
namespace plib {
|
|
|
|
plog_dispatch_intf::~plog_dispatch_intf()
|
|
{
|
|
}
|
|
|
|
pfmt::pfmt(const pstring &fmt)
|
|
: m_str(m_str_buf), m_allocated(0), m_arg(0)
|
|
{
|
|
std::size_t l = fmt.size() + 1;
|
|
if (l>sizeof(m_str_buf))
|
|
{
|
|
m_allocated = 2 * l;
|
|
m_str = palloc_array<char>(2 * l);
|
|
}
|
|
std::copy(fmt.c_str(), fmt.c_str() + l, m_str);
|
|
}
|
|
|
|
pfmt::~pfmt()
|
|
{
|
|
if (m_allocated > 0)
|
|
pfree_array(m_str);
|
|
}
|
|
|
|
void pfmt::format_element(const char *f, const char *l, const char *fmt_spec, ...)
|
|
{
|
|
va_list ap;
|
|
va_start(ap, fmt_spec);
|
|
char fmt[30] = "%";
|
|
char search[10] = "";
|
|
char buf[2048];
|
|
m_arg++;
|
|
std::size_t sl = static_cast<std::size_t>(sprintf(search, "{%d:", m_arg));
|
|
char *p = strstr(m_str, search);
|
|
if (p == nullptr)
|
|
{
|
|
sl = static_cast<std::size_t>(sprintf(search, "{%d}", m_arg));
|
|
p = strstr(m_str, search);
|
|
if (p == nullptr)
|
|
{
|
|
sl = 2;
|
|
p = strstr(m_str, "{}");
|
|
}
|
|
if (p==nullptr)
|
|
{
|
|
sl=1;
|
|
p = strstr(m_str, "{");
|
|
if (p != nullptr)
|
|
{
|
|
char *p1 = strstr(p, "}");
|
|
if (p1 != nullptr)
|
|
{
|
|
sl = static_cast<std::size_t>(p1 - p + 1);
|
|
strncat(fmt, p+1, static_cast<std::size_t>(p1 - p - 2));
|
|
}
|
|
else
|
|
strcat(fmt, f);
|
|
}
|
|
else
|
|
strcat(fmt, f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char *p1 = strstr(p, "}");
|
|
if (p1 != nullptr)
|
|
{
|
|
sl = static_cast<std::size_t>(p1 - p + 1);
|
|
if (m_arg>=10)
|
|
strncat(fmt, p+4, static_cast<std::size_t>(p1 - p - 4));
|
|
else
|
|
strncat(fmt, p+3, static_cast<std::size_t>(p1 - p - 3));
|
|
}
|
|
else
|
|
strcat(fmt, f);
|
|
}
|
|
strcat(fmt, l);
|
|
char *pend = fmt + strlen(fmt) - 1;
|
|
if (strchr("fge", *fmt_spec) != nullptr)
|
|
{
|
|
if (strchr("fge", *pend) == nullptr)
|
|
strcat(fmt, fmt_spec);
|
|
}
|
|
else if (strchr("duxo", *fmt_spec) != nullptr)
|
|
{
|
|
if (strchr("duxo", *pend) == nullptr)
|
|
strcat(fmt, fmt_spec);
|
|
}
|
|
else
|
|
strcat(fmt, fmt_spec);
|
|
std::size_t nl = static_cast<std::size_t>(vsprintf(buf, fmt, ap));
|
|
if (p != nullptr)
|
|
{
|
|
// check room
|
|
std::size_t new_size = static_cast<std::size_t>(p - m_str) + nl + strlen(p) + 1 - sl;
|
|
if (new_size > m_allocated)
|
|
{
|
|
std::size_t old_alloc = std::max(m_allocated, sizeof(m_str_buf));
|
|
if (m_allocated < old_alloc)
|
|
m_allocated = old_alloc;
|
|
while (new_size > m_allocated)
|
|
m_allocated *= 2;
|
|
char *np = palloc_array<char>(m_allocated);
|
|
std::copy(m_str, m_str + old_alloc, np);
|
|
p = np + (p - m_str);
|
|
if (m_str != m_str_buf)
|
|
pfree_array(m_str);
|
|
m_str = np;
|
|
}
|
|
// Make room
|
|
//memmove(p+nl, p+sl, strlen(p) + 1 - sl);
|
|
std::copy_backward(p + sl, p + strlen(p) + 1, p + nl + strlen(p) + 1 - sl);
|
|
std::copy(buf, buf + nl, p);
|
|
}
|
|
va_end(ap);
|
|
}
|
|
|
|
}
|