mame/src/lib/netlist/plib/pfmtlog.cpp
couriersud ac13946ffb Change pstring to use std::string as storage container.
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)
2017-03-30 22:06:03 +02:00

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);
}
}