summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Couriersud <couriersud@users.noreply.github.com>2013-11-24 20:08:04 +0000
committer Couriersud <couriersud@users.noreply.github.com>2013-11-24 20:08:04 +0000
commitcb6f1d0194b07e3817131d9b589797f7b67a7d59 (patch)
tree397a12f9c437dbcc549effed69505c7b85804e8a
parent0d0f072d59bdd04ce519c7ec6d61e13ebcf0c6dc (diff)
Netlist: Added pascal like strings (pstring) class. These use only size(void *) in objects. Uses reference counter to share identical string between various pstrings.
In addition, fixed some bugs and added auto-sizing to netlist_list_t. There shouldn't be memory holes left now, apart from memory allocated in a static class factory.
-rw-r--r--.gitattributes2
-rw-r--r--src/emu/machine/netlist.c6
-rw-r--r--src/emu/machine/netlist.h4
-rw-r--r--src/emu/netlist/devices/net_lib.c4
-rw-r--r--src/emu/netlist/devices/nld_system.c37
-rw-r--r--src/emu/netlist/devices/nld_system.h12
-rw-r--r--src/emu/netlist/netlist.mak3
-rw-r--r--src/emu/netlist/nl_base.c65
-rw-r--r--src/emu/netlist/nl_base.h64
-rw-r--r--src/emu/netlist/nl_config.h2
-rw-r--r--src/emu/netlist/nl_lists.h63
-rw-r--r--src/emu/netlist/nl_parser.c35
-rw-r--r--src/emu/netlist/nl_parser.h8
-rw-r--r--src/emu/netlist/nl_setup.c139
-rw-r--r--src/emu/netlist/nl_setup.h53
-rw-r--r--src/emu/netlist/nl_time.h56
-rw-r--r--src/emu/netlist/pstring.c218
-rw-r--r--src/emu/netlist/pstring.h164
18 files changed, 690 insertions, 245 deletions
diff --git a/.gitattributes b/.gitattributes
index 8c5b99a3cd4..dd2cb945d36 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2144,6 +2144,8 @@ src/emu/netlist/nl_parser.h svneol=native#text/plain
src/emu/netlist/nl_setup.c svneol=native#text/plain
src/emu/netlist/nl_setup.h svneol=native#text/plain
src/emu/netlist/nl_time.h svneol=native#text/plain
+src/emu/netlist/pstring.c svneol=native#text/plain
+src/emu/netlist/pstring.h svneol=native#text/plain
src/emu/network.c svneol=native#text/plain
src/emu/network.h svneol=native#text/plain
src/emu/output.c svneol=native#text/plain
diff --git a/src/emu/machine/netlist.c b/src/emu/machine/netlist.c
index 81bee490d21..55fbb9782b5 100644
--- a/src/emu/machine/netlist.c
+++ b/src/emu/machine/netlist.c
@@ -49,8 +49,6 @@
#include "netlist/nl_setup.h"
#include "netlist/devices/net_lib.h"
-const netlist_time netlist_time::zero = netlist_time::from_raw(0);
-
// ----------------------------------------------------------------------------------------
// netlist_mame_device
// ----------------------------------------------------------------------------------------
@@ -91,8 +89,8 @@ void netlist_mame_device::device_start()
m_setup->start_devices();
bool allok = true;
- for (on_device_start **ods = m_device_start_list.first(); ods <= m_device_start_list.last(); ods++)
- allok &= (*ods)->OnDeviceStart();
+ for (device_start_list_t::entry_t *ods = m_device_start_list.first(); ods != NULL; ods = m_device_start_list.next(ods))
+ allok &= ods->object()->OnDeviceStart();
if (!allok)
fatalerror("required elements not found\n");
diff --git a/src/emu/machine/netlist.h b/src/emu/machine/netlist.h
index b3704b0d0d9..d79b0c4f783 100644
--- a/src/emu/machine/netlist.h
+++ b/src/emu/machine/netlist.h
@@ -118,7 +118,9 @@ public:
netlist_setup_t &setup() { return *m_setup; }
netlist_t &netlist() { return *m_netlist; }
- netlist_list_t<on_device_start *> m_device_start_list;
+ typedef netlist_list_t<on_device_start *> device_start_list_t;
+
+ device_start_list_t m_device_start_list;
protected:
// device-level overrides
diff --git a/src/emu/netlist/devices/net_lib.c b/src/emu/netlist/devices/net_lib.c
index e646dd46e85..86feecff40b 100644
--- a/src/emu/netlist/devices/net_lib.c
+++ b/src/emu/netlist/devices/net_lib.c
@@ -987,7 +987,7 @@ static const net_device_t_base_factory *netregistry[] =
NULL
};
-netlist_device_t *net_create_device_by_classname(const astring &classname, netlist_setup_t &setup)
+netlist_device_t *net_create_device_by_classname(const pstring &classname, netlist_setup_t &setup)
{
const net_device_t_base_factory **p = &netregistry[0];
while (*p != NULL)
@@ -1003,7 +1003,7 @@ netlist_device_t *net_create_device_by_classname(const astring &classname, netli
return NULL; // appease code analysis
}
-netlist_device_t *net_create_device_by_name(const astring &name, netlist_setup_t &setup)
+netlist_device_t *net_create_device_by_name(const pstring &name, netlist_setup_t &setup)
{
const net_device_t_base_factory **p = &netregistry[0];
while (*p != NULL)
diff --git a/src/emu/netlist/devices/nld_system.c b/src/emu/netlist/devices/nld_system.c
index 0d34efba4af..747088b9077 100644
--- a/src/emu/netlist/devices/nld_system.c
+++ b/src/emu/netlist/devices/nld_system.c
@@ -98,13 +98,24 @@ NETLIB_UPDATE_PARAM(solver)
m_inc = netlist_time::from_hz(m_freq.Value());
}
+NETLIB_NAME(solver)::~NETLIB_NAME(solver)()
+{
+ net_list_t::entry_t *p = m_nets.first();
+ while (p != NULL)
+ {
+ net_list_t::entry_t *pn = m_nets.next(pn);
+ delete pn->object();
+ p = pn;
+ }
+}
+
NETLIB_FUNC_VOID(solver, post_start, ())
{
NL_VERBOSE_OUT(("post start solver ...\n"));
- for (netlist_net_t **pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
+ for (net_list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
{
NL_VERBOSE_OUT(("setting up net\n"));
- for (netlist_terminal_t *p = (*pn)->m_head; p != NULL; p = p->m_update_list_next)
+ for (netlist_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next)
{
switch (p->type())
{
@@ -121,11 +132,11 @@ NETLIB_FUNC_VOID(solver, post_start, ())
break;
}
}
- if ((*pn)->m_head == NULL)
+ if (pn->object()->m_head == NULL)
{
NL_VERBOSE_OUT(("Deleting net ...\n"));
- netlist_net_t *to_delete = *pn;
- m_nets.del(to_delete);
+ netlist_net_t *to_delete = pn->object();
+ m_nets.remove(to_delete);
delete to_delete;
pn--;
}
@@ -146,15 +157,15 @@ NETLIB_UPDATE(solver)
NL_VERBOSE_OUT(("Step!\n"));
/* update all terminals for new time step */
m_last_step = now;
- for (netlist_terminal_t **p = m_terms.first(); p != NULL; p = m_terms.next(p))
- (*p)->netdev().step_time(delta.as_double());
+ for (terminal_list_t::entry_t *p = m_terms.first(); p != NULL; p = m_terms.next(p))
+ p->object()->netdev().step_time(delta.as_double());
}
- for (netlist_net_t **pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
+ for (net_list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
{
double gtot = 0;
double iIdr = 0;
- for (netlist_terminal_t *p = (*pn)->m_head; p != NULL; p = p->m_update_list_next)
+ for (netlist_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next)
{
if (p->isType(netlist_terminal_t::TERMINAL))
{
@@ -165,9 +176,9 @@ NETLIB_UPDATE(solver)
}
double new_val = iIdr / gtot;
- if (fabs(new_val - (*pn)->m_cur.Analog) > 1e-4)
+ if (fabs(new_val - pn->object()->m_cur.Analog) > 1e-4)
resched = true;
- (*pn)->m_cur.Analog = (*pn)->m_new.Analog = new_val;
+ pn->object()->m_cur.Analog = pn->object()->m_new.Analog = new_val;
NL_VERBOSE_OUT(("Info: %d\n", (*pn)->m_num_cons));
NL_VERBOSE_OUT(("New: %lld %f %f\n", netlist().time().as_raw(), netlist().time().as_double(), new_val));
@@ -179,8 +190,8 @@ NETLIB_UPDATE(solver)
else
{
/* update all inputs connected */
- for (netlist_terminal_t **p = m_inps.first(); p != NULL; p = m_inps.next(p))
- (*p)->netdev().update_dev();
+ for (terminal_list_t::entry_t *p = m_inps.first(); p != NULL; p = m_inps.next(p))
+ p->object()->netdev().update_dev();
/* step circuit */
if (!m_Q.net().is_queued())
{
diff --git a/src/emu/netlist/devices/nld_system.h b/src/emu/netlist/devices/nld_system.h
index bd62ed4bfac..20ba1f21f75 100644
--- a/src/emu/netlist/devices/nld_system.h
+++ b/src/emu/netlist/devices/nld_system.h
@@ -96,6 +96,9 @@ NETLIB_DEVICE_WITH_PARAMS(clock,
// ----------------------------------------------------------------------------------------
NETLIB_DEVICE_WITH_PARAMS(solver,
+ typedef netlist_list_t<netlist_terminal_t *> terminal_list_t;
+ typedef netlist_list_t<netlist_net_t *> net_list_t;
+
netlist_ttl_input_t m_feedback;
netlist_ttl_output_t m_Q;
@@ -104,11 +107,14 @@ NETLIB_DEVICE_WITH_PARAMS(solver,
netlist_time m_inc;
netlist_time m_last_step;
- netlist_list_t<netlist_terminal_t *> m_terms;
- netlist_list_t<netlist_terminal_t *> m_inps;
+ terminal_list_t m_terms;
+ terminal_list_t m_inps;
public:
- netlist_list_t<netlist_net_t *> m_nets;
+
+ ~NETLIB_NAME(solver)();
+
+ net_list_t m_nets;
ATTR_HOT inline void schedule();
diff --git a/src/emu/netlist/netlist.mak b/src/emu/netlist/netlist.mak
index 0580146c918..c0d215d2e5c 100644
--- a/src/emu/netlist/netlist.mak
+++ b/src/emu/netlist/netlist.mak
@@ -18,8 +18,9 @@ NETLISTOBJ = $(EMUOBJ)/netlist
#-------------------------------------------------
NETLISTOBJS+= \
- $(NETLISTOBJ)/nl_setup.o \
$(NETLISTOBJ)/nl_base.o \
+ $(NETLISTOBJ)/pstring.o \
+ $(NETLISTOBJ)/nl_setup.o \
$(NETLISTOBJ)/nl_parser.o \
$(NETLISTOBJ)/devices/nld_system.o \
$(NETLISTOBJ)/devices/net_lib.o \
diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c
index 2ee646a48aa..c9892b98fcc 100644
--- a/src/emu/netlist/nl_base.c
+++ b/src/emu/netlist/nl_base.c
@@ -5,6 +5,9 @@
#include "nl_base.h"
#include "devices/nld_system.h"
+#include "pstring.h"
+
+const netlist_time netlist_time::zero = netlist_time::from_raw(0);
// ----------------------------------------------------------------------------------------
// netlist_object_t
@@ -14,25 +17,24 @@ ATTR_COLD netlist_object_t::netlist_object_t(const type_t atype, const family_t
: m_objtype(atype)
, m_family(afamily)
, m_netlist(NULL)
-, m_name(NULL)
{}
ATTR_COLD netlist_object_t::~netlist_object_t()
{
- delete m_name;
+ //delete m_name;
}
-ATTR_COLD void netlist_object_t::init_object(netlist_base_t &nl, const astring &aname)
+ATTR_COLD void netlist_object_t::init_object(netlist_base_t &nl, const pstring &aname)
{
m_netlist = &nl;
- m_name = new astring(aname);
+ m_name = aname;
}
-ATTR_COLD const astring &netlist_object_t::name() const
+ATTR_COLD const pstring &netlist_object_t::name() const
{
- if (m_name == NULL)
+ if (m_name == "")
fatalerror("object not initialized");
- return *m_name;
+ return m_name;
}
// ----------------------------------------------------------------------------------------
@@ -47,7 +49,7 @@ ATTR_COLD netlist_owned_object_t::netlist_owned_object_t(const type_t atype,
}
ATTR_COLD void netlist_owned_object_t::init_object(netlist_core_device_t &dev,
- const astring &aname)
+ const pstring &aname)
{
netlist_object_t::init_object(dev.netlist(), aname);
m_netdev = &dev;
@@ -58,15 +60,17 @@ ATTR_COLD void netlist_owned_object_t::init_object(netlist_core_device_t &dev,
// ----------------------------------------------------------------------------------------
netlist_base_t::netlist_base_t()
- : m_mainclock(NULL),
- m_time_ps(netlist_time::zero),
+ : m_time_ps(netlist_time::zero),
m_rem(0),
- m_div(NETLIST_DIV)
+ m_div(NETLIST_DIV),
+ m_mainclock(NULL),
+ m_solver(NULL)
{
}
netlist_base_t::~netlist_base_t()
{
+ pstring::resetmem();
}
ATTR_COLD void netlist_base_t::set_mainclock_dev(NETLIB_NAME(mainclock) *dev)
@@ -81,11 +85,12 @@ ATTR_COLD void netlist_base_t::set_solver_dev(NETLIB_NAME(solver) *dev)
ATTR_COLD void netlist_base_t::reset()
{
- m_time_ps = netlist_time::zero;
- m_rem = 0;
- m_queue.clear();
- if (m_mainclock != NULL)
- m_mainclock->m_Q.net().set_time(netlist_time::zero);
+ m_time_ps = netlist_time::zero;
+ m_rem = 0;
+ m_queue.clear();
+ if (m_mainclock != NULL)
+ m_mainclock->m_Q.net().set_time(netlist_time::zero);
+
}
@@ -121,7 +126,7 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(INT32 &atime)
{
while ( (atime > 0) && (m_queue.is_not_empty()))
{
- const queue_t::entry_t e = m_queue.pop();
+ const queue_t::entry_t &e = m_queue.pop();
update_time(e.time(), atime);
//if (FATAL_ERROR_AFTER_NS)
@@ -156,7 +161,7 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(INT32 &atime)
NETLIB_NAME(mainclock)::mc_update(mcQ, time() + inc);
}
- const queue_t::entry_t e = m_queue.pop();
+ const queue_t::entry_t &e = m_queue.pop();
update_time(e.time(), atime);
@@ -197,7 +202,7 @@ netlist_core_device_t::netlist_core_device_t()
{
}
-ATTR_COLD void netlist_core_device_t::init(netlist_setup_t &setup, const astring &name)
+ATTR_COLD void netlist_core_device_t::init(netlist_setup_t &setup, const pstring &name)
{
init_object(setup.netlist(), name);
@@ -248,7 +253,7 @@ netlist_device_t::~netlist_device_t()
//NL_VERBOSE_OUT(("~net_device_t\n");
}
-ATTR_COLD void netlist_device_t::init(netlist_setup_t &setup, const astring &name)
+ATTR_COLD void netlist_device_t::init(netlist_setup_t &setup, const pstring &name)
{
netlist_core_device_t::init(setup, name);
m_setup = &setup;
@@ -256,33 +261,33 @@ ATTR_COLD void netlist_device_t::init(netlist_setup_t &setup, const astring &nam
}
-ATTR_COLD void netlist_device_t::register_sub(netlist_core_device_t &dev, const astring &name)
+ATTR_COLD void netlist_device_t::register_sub(netlist_core_device_t &dev, const pstring &name)
{
dev.init(*m_setup, this->name() + "." + name);
}
-ATTR_COLD void netlist_device_t::register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &port)
+ATTR_COLD void netlist_device_t::register_output(netlist_core_device_t &dev, const pstring &name, netlist_output_t &port)
{
m_setup->register_object(*this, dev, name, port, netlist_terminal_t::STATE_OUT);
}
-ATTR_COLD void netlist_device_t::register_terminal(const astring &name, netlist_terminal_t &port)
+ATTR_COLD void netlist_device_t::register_terminal(const pstring &name, netlist_terminal_t &port)
{
m_setup->register_object(*this,*this,name, port, netlist_terminal_t::STATE_INP_ACTIVE);
}
-ATTR_COLD void netlist_device_t::register_output(const astring &name, netlist_output_t &port)
+ATTR_COLD void netlist_device_t::register_output(const pstring &name, netlist_output_t &port)
{
m_setup->register_object(*this,*this,name, port, netlist_terminal_t::STATE_OUT);
}
-ATTR_COLD void netlist_device_t::register_input(netlist_core_device_t &dev, const astring &name, netlist_input_t &inp, netlist_input_t::state_e type)
+ATTR_COLD void netlist_device_t::register_input(netlist_core_device_t &dev, const pstring &name, netlist_input_t &inp, netlist_input_t::state_e type)
{
m_terminals.add(name);
m_setup->register_object(*this, dev, name, inp, type);
}
-ATTR_COLD void netlist_device_t::register_input(const astring &name, netlist_input_t &inp, netlist_input_t::state_e type)
+ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_input_t &inp, netlist_input_t::state_e type)
{
register_input(*this, name, inp, type);
}
@@ -303,14 +308,14 @@ ATTR_COLD void netlist_device_t::register_link_internal(netlist_input_t &in, net
register_link_internal(*this, in, out, aState);
}
-ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const astring &name, netlist_param_t &param, double initialVal)
+ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const pstring &name, netlist_param_t &param, double initialVal)
{
param.set_netdev(dev);
param.initial(initialVal);
m_setup->register_object(*this, *this, name, param, netlist_terminal_t::STATE_NONEX);
}
-ATTR_COLD void netlist_device_t::register_param(const astring &name, netlist_param_t &param, double initialVal)
+ATTR_COLD void netlist_device_t::register_param(const pstring &name, netlist_param_t &param, double initialVal)
{
register_param(*this,name, param, initialVal);
}
@@ -451,7 +456,7 @@ ATTR_COLD netlist_terminal_t::netlist_terminal_t()
}
-ATTR_COLD void netlist_terminal_t::init_object(netlist_core_device_t &dev, const astring &aname, const state_e astate)
+ATTR_COLD void netlist_terminal_t::init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate)
{
set_state(astate);
netlist_owned_object_t::init_object(dev, aname);
@@ -480,7 +485,7 @@ netlist_output_t::netlist_output_t(const type_t atype, const family_t afamily)
this->set_net(m_my_net);
}
-ATTR_COLD void netlist_output_t::init_object(netlist_core_device_t &dev, const astring &aname)
+ATTR_COLD void netlist_output_t::init_object(netlist_core_device_t &dev, const pstring &aname)
{
netlist_terminal_t::init_object(dev, aname, STATE_OUT);
net().init_object(dev.netlist(), aname);
diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h
index 9901716c4f7..22c813e2c3e 100644
--- a/src/emu/netlist/nl_base.h
+++ b/src/emu/netlist/nl_base.h
@@ -138,6 +138,7 @@
#include "nl_config.h"
#include "nl_lists.h"
#include "nl_time.h"
+#include "pstring.h"
// ----------------------------------------------------------------------------------------
// Type definitions
@@ -248,9 +249,9 @@ public:
virtual ~netlist_object_t();
- ATTR_COLD void init_object(netlist_base_t &nl, const astring &aname);
+ ATTR_COLD void init_object(netlist_base_t &nl, const pstring &aname);
- ATTR_COLD const astring &name() const;
+ ATTR_COLD const pstring &name() const;
ATTR_HOT inline const type_t type() const { return m_objtype; }
ATTR_HOT inline const family_t family() const { return m_family; }
@@ -262,10 +263,10 @@ public:
ATTR_HOT inline const netlist_base_t & RESTRICT netlist() const { return *m_netlist; }
private:
+ pstring m_name;
const type_t m_objtype;
const family_t m_family;
netlist_base_t * RESTRICT m_netlist;
- astring *m_name;
};
// ----------------------------------------------------------------------------------------
@@ -277,7 +278,7 @@ class netlist_owned_object_t : public netlist_object_t
public:
ATTR_COLD netlist_owned_object_t(const type_t atype, const family_t afamily);
- ATTR_COLD void init_object(netlist_core_device_t &dev, const astring &aname);
+ ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname);
ATTR_HOT inline netlist_core_device_t & RESTRICT netdev() const { return *m_netdev; }
private:
@@ -306,7 +307,7 @@ public:
ATTR_COLD netlist_terminal_t(const type_t atype, const family_t afamily);
ATTR_COLD netlist_terminal_t();
- ATTR_COLD void init_object(netlist_core_device_t &dev, const astring &aname, const state_e astate);
+ ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate);
ATTR_COLD void set_net(netlist_net_t &anet);
ATTR_COLD inline bool has_net() { return (m_net != NULL); }
@@ -515,7 +516,7 @@ public:
ATTR_COLD netlist_output_t(const type_t atype, const family_t afamily);
- ATTR_COLD void init_object(netlist_core_device_t &dev, const astring &aname);
+ ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname);
double m_low_V;
double m_high_V;
@@ -601,7 +602,7 @@ public:
ATTR_COLD virtual ~netlist_core_device_t();
- ATTR_COLD virtual void init(netlist_setup_t &setup, const astring &name);
+ ATTR_COLD virtual void init(netlist_setup_t &setup, const pstring &name);
ATTR_HOT virtual void update_param() {}
@@ -656,9 +657,11 @@ public:
ATTR_HOT virtual void step_time(const double st) { }
ATTR_HOT virtual void update_terminals() { }
- /* stats */
+#if (NL_KEEP_STATISTICS)
+ /* stats */
osd_ticks_t total_time;
INT32 stat_count;
+#endif
#if USE_DELEGATES
net_update_delegate static_update;
@@ -681,21 +684,21 @@ public:
ATTR_COLD virtual ~netlist_device_t();
- ATTR_COLD virtual void init(netlist_setup_t &setup, const astring &name);
+ ATTR_COLD virtual void init(netlist_setup_t &setup, const pstring &name);
ATTR_COLD const netlist_setup_t *setup() const { return m_setup; }
ATTR_COLD bool variable_input_count() { return m_variable_input_count; }
- ATTR_COLD void register_sub(netlist_core_device_t &dev, const astring &name);
+ ATTR_COLD void register_sub(netlist_core_device_t &dev, const pstring &name);
- ATTR_COLD void register_terminal(const astring &name, netlist_terminal_t &port);
+ ATTR_COLD void register_terminal(const pstring &name, netlist_terminal_t &port);
- ATTR_COLD void register_output(const astring &name, netlist_output_t &out);
- ATTR_COLD void register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &out);
+ ATTR_COLD void register_output(const pstring &name, netlist_output_t &out);
+ ATTR_COLD void register_output(netlist_core_device_t &dev, const pstring &name, netlist_output_t &out);
- ATTR_COLD void register_input(const astring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE);
- ATTR_COLD void register_input(netlist_core_device_t &dev, const astring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE);
+ ATTR_COLD void register_input(const pstring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE);
+ ATTR_COLD void register_input(netlist_core_device_t &dev, const pstring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE);
ATTR_COLD void register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState);
ATTR_COLD void register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState);
@@ -703,15 +706,15 @@ public:
ATTR_HOT virtual void update_terminals() { }
/* driving logic outputs don't count in here */
- netlist_list_t<astring> m_terminals;
+ netlist_list_t<pstring, 20> m_terminals;
protected:
virtual void update() { }
virtual void start() { }
- ATTR_COLD void register_param(const astring &sname, netlist_param_t &param, const double initialVal = 0.0);
- ATTR_COLD void register_param(netlist_core_device_t &dev, const astring &sname, netlist_param_t &param, const double initialVal = 0.0);
+ ATTR_COLD void register_param(const pstring &sname, netlist_param_t &param, const double initialVal = 0.0);
+ ATTR_COLD void register_param(netlist_core_device_t &dev, const pstring &sname, netlist_param_t &param, const double initialVal = 0.0);
netlist_setup_t *m_setup;
bool m_variable_input_count;
@@ -780,19 +783,22 @@ public:
ATTR_COLD void reset();
protected:
+#if (NL_KEEP_STATISTICS)
// performance
int m_perf_out_processed;
int m_perf_inp_processed;
int m_perf_inp_active;
+#endif
private:
+ netlist_time m_time_ps;
queue_t m_queue;
- NETLIB_NAME(mainclock) * m_mainclock;
- NETLIB_NAME(solver) * m_solver;
- netlist_time m_time_ps;
UINT32 m_rem;
UINT32 m_div;
+ NETLIB_NAME(mainclock) * m_mainclock;
+ NETLIB_NAME(solver) * m_solver;
+
ATTR_HOT void update_time(const netlist_time t, INT32 &atime);
};
@@ -994,7 +1000,7 @@ ATTR_HOT inline const bool netlist_analog_input_t::is_highz() const
class net_device_t_base_factory
{
public:
- net_device_t_base_factory(const astring &name, const astring &classname)
+ net_device_t_base_factory(const pstring &name, const pstring &classname)
: m_name(name), m_classname(classname)
{}
@@ -1002,18 +1008,18 @@ public:
virtual netlist_device_t *Create() const = 0;
- const astring &name() const { return m_name; }
- const astring &classname() const { return m_classname; }
+ const pstring &name() const { return m_name; }
+ const pstring &classname() const { return m_classname; }
protected:
- astring m_name; /* device name */
- astring m_classname; /* device class name */
+ pstring m_name; /* device name */
+ pstring m_classname; /* device class name */
};
template <class C>
class net_device_t_factory : public net_device_t_base_factory
{
public:
- net_device_t_factory(const astring &name, const astring &classname)
+ net_device_t_factory(const pstring &name, const pstring &classname)
: net_device_t_base_factory(name, classname) { }
netlist_device_t *Create() const
@@ -1024,8 +1030,8 @@ public:
}
};
-netlist_device_t *net_create_device_by_classname(const astring &classname, netlist_setup_t &setup);
-netlist_device_t *net_create_device_by_name(const astring &name, netlist_setup_t &setup);
+netlist_device_t *net_create_device_by_classname(const pstring &classname, netlist_setup_t &setup);
+netlist_device_t *net_create_device_by_name(const pstring &name, netlist_setup_t &setup);
#endif /* NLBASE_H_ */
diff --git a/src/emu/netlist/nl_config.h b/src/emu/netlist/nl_config.h
index e68fdf35a27..1f07d4c8354 100644
--- a/src/emu/netlist/nl_config.h
+++ b/src/emu/netlist/nl_config.h
@@ -16,6 +16,8 @@
// SETUP
//============================================================
+//#define astring breakme()
+
#define USE_DELEGATES (0)
/*
* The next options needs -Wno-pmf-conversions to compile and gcc
diff --git a/src/emu/netlist/nl_lists.h b/src/emu/netlist/nl_lists.h
index 8d73ddcae0f..a42a7a339a1 100644
--- a/src/emu/netlist/nl_lists.h
+++ b/src/emu/netlist/nl_lists.h
@@ -15,14 +15,23 @@
// ----------------------------------------------------------------------------------------
-template <class _ListClass>
+template <class _ListClass, int _NumElem = 128>
struct netlist_list_t
{
public:
- ATTR_COLD netlist_list_t(int numElements = 100)
+
+ struct entry_t {
+
+ // keep compatibility with tagmap
+ _ListClass object() { return m_obj; }
+
+ _ListClass m_obj;
+ };
+
+ ATTR_COLD netlist_list_t(int numElements = _NumElem)
{
m_num_elements = numElements;
- m_list = new _ListClass[m_num_elements];
+ m_list = new entry_t[m_num_elements];
m_ptr = m_list;
m_ptr--;
}
@@ -32,24 +41,29 @@ public:
}
ATTR_HOT inline void add(const _ListClass elem)
{
- assert(m_ptr-m_list <= m_num_elements - 1);
+ if (m_ptr-m_list >= m_num_elements - 1)
+ resize(m_num_elements * 2);
- *(++m_ptr) = elem;
+ (++m_ptr)->m_obj = elem;
}
ATTR_HOT inline void resize(const int new_size)
{
int cnt = count();
- _ListClass *m_new = new _ListClass[new_size];
- memcpy(m_new, m_list, new_size * sizeof(_ListClass));
+ entry_t *m_new = new entry_t[new_size];
+ entry_t *pd = m_new;
+
+ for (entry_t *ps = m_list; ps <= m_ptr; ps++, pd++)
+ *pd = *ps;
delete[] m_list;
m_list = m_new;
m_ptr = m_list + cnt - 1;
+ m_num_elements = new_size;
}
- ATTR_HOT inline void del(const _ListClass elem)
+ ATTR_HOT inline void remove(const _ListClass elem)
{
- for (_ListClass * i=m_list; i<=m_ptr; i++)
+ for (entry_t *i = m_list; i <= m_ptr; i++)
{
- if (*i == elem)
+ if (i->object() == elem)
{
while (i <= m_ptr)
{
@@ -61,16 +75,16 @@ public:
}
}
}
- ATTR_HOT inline _ListClass *first() { return (m_ptr >= m_list ? &m_list[0] : NULL ); }
- ATTR_HOT inline _ListClass *next(_ListClass *lc) { return (lc < last() ? lc + 1 : NULL ); }
- ATTR_HOT inline _ListClass *last() { return m_ptr; }
- ATTR_HOT inline _ListClass *item(int i) { return &m_list[i]; }
+ ATTR_HOT inline entry_t *first() { return (m_ptr >= m_list ? &m_list[0] : NULL ); }
+ ATTR_HOT inline entry_t *next(entry_t *lc) { return (lc < last() ? lc + 1 : NULL ); }
+ ATTR_HOT inline entry_t *last() { return m_ptr; }
+ ATTR_HOT inline entry_t *item(int i) { return &m_list[i]; }
ATTR_HOT inline int count() const { return m_ptr - m_list + 1; }
ATTR_HOT inline bool empty() { return (m_ptr < m_list); }
- ATTR_HOT inline void clear() { m_ptr = m_list - 1; }
+ ATTR_HOT inline void reset() { m_ptr = m_list - 1; }
private:
- _ListClass * m_ptr;
- _ListClass * m_list;
+ entry_t * m_ptr;
+ entry_t * m_list;
int m_num_elements;
//_ListClass m_list[_NumElements];
};
@@ -111,7 +125,7 @@ public:
if (is_empty() || (e.time() <= (m_end - 1)->time()))
{
*m_end++ = e;
- //inc_stat(m_prof_end);
+ inc_stat(m_prof_end);
}
else
{
@@ -120,20 +134,20 @@ public:
{
i--;
*(i+1) = *i;
- //inc_stat(m_prof_sortmove);
+ inc_stat(m_prof_sortmove);
}
*i = e;
- //inc_stat(m_prof_sort);
+ inc_stat(m_prof_sort);
}
assert(m_end - m_list < _Size);
}
- ATTR_HOT inline const entry_t pop()
+ ATTR_HOT inline const entry_t &pop()
{
return *--m_end;
}
- ATTR_HOT inline const entry_t peek() const
+ ATTR_HOT inline const entry_t &peek() const
{
return *(m_end-1);
}
@@ -142,12 +156,15 @@ public:
{
m_end = &m_list[0];
}
- // profiling
+#if (NL_KEEP_STATISTICS)
+ // profiling
INT32 m_prof_start;
INT32 m_prof_end;
INT32 m_prof_sortmove;
INT32 m_prof_sort;
+#endif
+
private:
entry_t * RESTRICT m_end;
diff --git a/src/emu/netlist/nl_parser.c b/src/emu/netlist/nl_parser.c
index e47e7d644c5..3233b4c3773 100644
--- a/src/emu/netlist/nl_parser.c
+++ b/src/emu/netlist/nl_parser.c
@@ -16,7 +16,7 @@ void netlist_parser::parse(char *buf)
m_p = buf;
while (*m_p)
{
- astring n;
+ pstring n;
skipws();
if (!*m_p) break;
n = getname('(');
@@ -34,8 +34,8 @@ void netlist_parser::parse(char *buf)
void netlist_parser::net_alias()
{
- astring alias;
- astring out;
+ pstring alias;
+ pstring out;
skipws();
alias = getname(',');
skipws();
@@ -46,7 +46,7 @@ void netlist_parser::net_alias()
void netlist_parser::netdev_param()
{
- astring param;
+ pstring param;
double val;
skipws();
param = getname(',');
@@ -58,11 +58,11 @@ void netlist_parser::netdev_param()
check_char(')');
}
-void netlist_parser::netdev_const(const astring &dev_name)
+void netlist_parser::netdev_const(const pstring &dev_name)
{
- astring name;
+ pstring name;
netlist_device_t *dev;
- astring paramfq;
+ pstring paramfq;
double val;
skipws();
@@ -72,16 +72,15 @@ void netlist_parser::netdev_const(const astring &dev_name)
skipws();
val = eval_param();
check_char(')');
- paramfq = name;
- paramfq.cat(".CONST");
+ paramfq = name + ".CONST";
NL_VERBOSE_OUT(("Parser: Const: %s %f\n", name.cstr(), val));
//m_setup.find_param(paramfq).initial(val);
m_setup.register_param(paramfq, val);
}
-void netlist_parser::netdev_device(const astring &dev_type)
+void netlist_parser::netdev_device(const pstring &dev_type)
{
- astring devname;
+ pstring devname;
netlist_device_t *dev;
int cnt;
@@ -96,11 +95,9 @@ void netlist_parser::netdev_device(const astring &dev_type)
{
m_p++;
skipws();
- astring output_name = getname2(',', ')');
+ pstring output_name = getname2(',', ')');
NL_VERBOSE_OUT(("Parser: ID: %s %s\n", output_name.cstr(), dev->m_terminals.item(cnt)->cstr()));
- astring temp;
- temp.printf("%s.[%d]", devname.cstr(), cnt);
- m_setup.register_link(temp, output_name);
+ m_setup.register_link(pstring::sprintf("%s.[%d]", devname.cstr(), cnt), output_name);
skipws();
cnt++;
}
@@ -156,7 +153,7 @@ void netlist_parser::skipws()
}
}
-astring netlist_parser::getname(char sep)
+pstring netlist_parser::getname(char sep)
{
char buf[300];
char *p1 = buf;
@@ -165,10 +162,10 @@ astring netlist_parser::getname(char sep)
*p1++ = *m_p++;
*p1 = 0;
m_p++;
- return astring(buf);
+ return pstring(buf);
}
-astring netlist_parser::getname2(char sep1, char sep2)
+pstring netlist_parser::getname2(char sep1, char sep2)
{
char buf[300];
char *p1 = buf;
@@ -176,7 +173,7 @@ astring netlist_parser::getname2(char sep1, char sep2)
while ((*m_p != sep1) && (*m_p != sep2))
*p1++ = *m_p++;
*p1 = 0;
- return astring(buf);
+ return pstring(buf);
}
void netlist_parser::check_char(char ctocheck)
diff --git a/src/emu/netlist/nl_parser.h b/src/emu/netlist/nl_parser.h
index 79b3882ac37..892c167c660 100644
--- a/src/emu/netlist/nl_parser.h
+++ b/src/emu/netlist/nl_parser.h
@@ -19,15 +19,15 @@ public:
void parse(char *buf);
void net_alias();
void netdev_param();
- void netdev_const(const astring &dev_name);
- void netdev_device(const astring &dev_type);
+ void netdev_const(const pstring &dev_name);
+ void netdev_device(const pstring &dev_type);
private:
void skipeol();
void skipws();
- astring getname(char sep);
- astring getname2(char sep1, char sep2);
+ pstring getname(char sep);
+ pstring getname2(char sep1, char sep2);
void check_char(char ctocheck);
double eval_param();
diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c
index d5c0d566f3c..d2786cd8730 100644
--- a/src/emu/netlist/nl_setup.c
+++ b/src/emu/netlist/nl_setup.c
@@ -41,13 +41,17 @@ static void tagmap_free_entries(T &tm)
netlist_setup_t::~netlist_setup_t()
{
tagmap_free_entries<tagmap_devices_t>(m_devices);
- tagmap_free_entries<tagmap_link_t>(m_links);
- tagmap_free_entries<tagmap_astring_t>(m_alias);
+ //tagmap_free_entries<tagmap_link_t>(m_links);
+ //tagmap_free_entries<tagmap_nstring_t>(m_alias);
+ m_links.reset();
+ m_alias.reset();
m_params.reset();
m_terminals.reset();
+ m_params_temp.reset();
+ pstring::resetmem();
}
-netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const astring &name)
+netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const pstring &name)
{
if (!(m_devices.add(name, dev, false)==TMERR_NONE))
fatalerror("Error adding %s to device list\n", name.cstr());
@@ -55,13 +59,14 @@ netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const ast
}
template <class T>
-static void remove_start_with(T &hm, astring &sw)
+static void remove_start_with(T &hm, pstring &sw)
{
typename T::entry_t *entry = hm.first();
while (entry != NULL)
{
typename T::entry_t *next = hm.next(entry);
- if (sw.cmpsubstr(entry->tag(), 0, sw.len()) == 0)
+ pstring x = entry->tag().cstr();
+ if (sw.equals(x.substr(0, sw.len())))
{
NL_VERBOSE_OUT(("removing %s\n", entry->tag().cstr()));
hm.remove(entry->object());
@@ -70,15 +75,13 @@ static void remove_start_with(T &hm, astring &sw)
}
}
-void netlist_setup_t::remove_dev(const astring &name)
+void netlist_setup_t::remove_dev(const pstring &name)
{
netlist_device_t *dev = m_devices.find(name);
- astring temp = name;
+ pstring temp = name + ".";
if (dev == NULL)
fatalerror("Device %s does not exist\n", name.cstr());
- temp.cat(".");
-
//remove_start_with<tagmap_input_t>(m_inputs, temp);
remove_start_with<tagmap_terminal_t>(m_terminals, temp);
remove_start_with<tagmap_param_t>(m_params, temp);
@@ -87,14 +90,14 @@ void netlist_setup_t::remove_dev(const astring &name)
while (p != NULL)
{
tagmap_link_t::entry_t *n = m_links.next(p);
- if (temp.cmpsubstr(p->object()->e1,0,temp.len()) == 0 || temp.cmpsubstr(p->object()->e2,0,temp.len()) == 0)
+ if (temp.equals(p->object().e1.substr(0,temp.len())) || temp.equals(p->object().e2.substr(0,temp.len())))
m_links.remove(p->object());
p = n;
}
m_devices.remove(name);
}
-void netlist_setup_t::register_callback(const astring &devname, netlist_output_delegate delegate)
+void netlist_setup_t::register_callback(const pstring &devname, netlist_output_delegate delegate)
{
NETLIB_NAME(analog_callback) *dev = (NETLIB_NAME(analog_callback) *) m_devices.find(devname);
if (dev == NULL)
@@ -102,13 +105,14 @@ void netlist_setup_t::register_callback(const astring &devname, netlist_output_d
dev->register_callback(delegate);
}
-void netlist_setup_t::register_alias(const astring &alias, const astring &out)
+void netlist_setup_t::register_alias(const pstring &alias, const pstring &out)
{
- if (!(m_alias.add(alias, new astring(out), false)==TMERR_NONE))
+ //if (!(m_alias.add(alias, new nstring(out), false)==TMERR_NONE))
+ if (!(m_alias.add(alias, out, false)==TMERR_NONE))
fatalerror("Error adding alias %s to alias list\n", alias.cstr());
}
-astring netlist_setup_t::objtype_as_astr(netlist_object_t &in)
+pstring netlist_setup_t::objtype_as_astr(netlist_object_t &in)
{
switch (in.type())
{
@@ -134,7 +138,7 @@ astring netlist_setup_t::objtype_as_astr(netlist_object_t &in)
fatalerror("Unknown object type %d\n", in.type());
}
-void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_object_t &obj, netlist_input_t::state_e state)
+void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const pstring &name, netlist_object_t &obj, netlist_input_t::state_e state)
{
switch (obj.type())
{
@@ -157,17 +161,16 @@ void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device
break;
case netlist_terminal_t::PARAM:
{
+
netlist_param_t &param = dynamic_cast<netlist_param_t &>(obj);
- astring temp = param.netdev().name();
- temp.cat(".");
- temp.cat(name);
- const astring *val = m_params_temp.find(temp);
- if (val != NULL)
+ pstring temp = param.netdev().name() + "." + name;
+ const pstring val = m_params_temp.find(temp);
+ if (val != "")
{
//printf("Found parameter ... %s : %s\n", temp.cstr(), val->cstr());
double vald = 0;
- if (sscanf(val->cstr(), "%lf", &vald) != 1)
- fatalerror("Invalid number conversion %s : %s\n", temp.cstr(), val->cstr());
+ if (sscanf(val.cstr(), "%lf", &vald) != 1)
+ fatalerror("Invalid number conversion %s : %s\n", temp.cstr(), val.cstr());
param.initial(vald);
}
if (!(m_params.add(temp, &param, false)==TMERR_NONE))
@@ -179,52 +182,52 @@ void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device
}
}
-void netlist_setup_t::register_link(const astring &sin, const astring &sout)
+void netlist_setup_t::register_link(const pstring &sin, const pstring &sout)
{
- link_t *temp = new link_t(sin, sout);
+ link_t temp = link_t(sin, sout);
NL_VERBOSE_OUT(("link %s <== %s\n", sin.cstr(), sout.cstr()));
- if (!(m_links.add(sin + "." + sout, temp, false)==TMERR_NONE))
- fatalerror("Error adding link %s<==%s to link list\n", sin.cstr(), sout.cstr());
+ m_links.add(temp);
+ //if (!(m_links.add(sin + "." + sout, temp, false)==TMERR_NONE))
+ // fatalerror("Error adding link %s<==%s to link list\n", sin.cstr(), sout.cstr());
}
-void netlist_setup_t::register_param(const astring &param, const double value)
+void netlist_setup_t::register_param(const pstring &param, const double value)
{
// FIXME: there should be a better way
- astring temp;
- temp.printf("%.9e", value);
- register_param(param, temp);
+ register_param(param, pstring::sprintf("%.9e", value));
}
-void netlist_setup_t::register_param(const astring &param, const astring &value)
+void netlist_setup_t::register_param(const pstring &param, const pstring &value)
{
- if (!(m_params_temp.add(param, new astring(value), false)==TMERR_NONE))
+ //if (!(m_params_temp.add(param, new nstring(value), false)==TMERR_NONE))
+ if (!(m_params_temp.add(param, value, false)==TMERR_NONE))
fatalerror("Error adding parameter %s to parameter list\n", param.cstr());
}
-const astring netlist_setup_t::resolve_alias(const astring &name) const
+const pstring netlist_setup_t::resolve_alias(const pstring &name) const
{
- const astring *temp = m_alias.find(name);
- astring ret = name;
- if (temp != NULL)
- ret = *temp;
+ const pstring temp = m_alias.find(name);
+ pstring ret = name;
+ if (temp != "")
+ ret = temp;
int p = ret.find(".[");
if (p > 0)
{
- astring dname = ret;
+ pstring dname = ret;
netlist_device_t *dev = m_devices.find(dname.substr(0,p));
if (dev == NULL)
fatalerror("Device for %s not found\n", name.cstr());
- ret.substr(p+2,ret.len()-p-3);
- int c = atoi(ret);
- ret = dev->name() + "." + *(dev->m_terminals.item(c));
+ int c = atoi(ret.substr(p+2,ret.len()-p-3));
+ ret = dev->name() + "." + dev->m_terminals.item(c)->object();
}
+ //printf("%s==>%s\n", name.cstr(), ret.cstr());
return ret;
}
-netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in)
+netlist_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in)
{
- const astring &tname = resolve_alias(terminal_in);
+ const pstring &tname = resolve_alias(terminal_in);
netlist_terminal_t *ret;
ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(tname));
@@ -232,8 +235,7 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in)
if (ret == NULL)
{
/* look for ".Q" std output */
- astring s = tname;
- s.cat(".Q");
+ pstring s = tname + ".Q";
ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(s));
}
if (ret == NULL)
@@ -242,9 +244,9 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in)
return *ret;
}
-netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in, netlist_object_t::type_t atype)
+netlist_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in, netlist_object_t::type_t atype)
{
- const astring &tname = resolve_alias(terminal_in);
+ const pstring &tname = resolve_alias(terminal_in);
netlist_terminal_t *ret;
ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(tname));
@@ -252,8 +254,7 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in, n
if (ret == NULL && atype == netlist_object_t::OUTPUT)
{
/* look for ".Q" std output */
- astring s = tname;
- s.cat(".Q");
+ pstring s = tname + ".Q";
ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(s));
}
if (ret == NULL)
@@ -264,9 +265,9 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in, n
return *ret;
}
-netlist_param_t &netlist_setup_t::find_param(const astring &param_in)
+netlist_param_t &netlist_setup_t::find_param(const pstring &param_in)
{
- const astring &outname = resolve_alias(param_in);
+ const pstring &outname = resolve_alias(param_in);
netlist_param_t *ret;
ret = m_params.find(outname);
@@ -282,10 +283,10 @@ void netlist_setup_t::connect_input_output(netlist_input_t &in, netlist_output_t
if (out.isFamily(netlist_terminal_t::ANALOG) && in.isFamily(netlist_terminal_t::LOGIC))
{
nld_a_to_d_proxy *proxy = new nld_a_to_d_proxy(in);
- astring x = "";
- x.printf("proxy_ad_%d", m_proxy_cnt++);
+ pstring x = pstring::sprintf("proxy_ad_%d", m_proxy_cnt);
+ m_proxy_cnt++;
- proxy->init(*this, x.cstr());
+ proxy->init(*this, x);
register_dev(proxy, x);
proxy->m_Q.net().register_con(in);
@@ -296,9 +297,10 @@ void netlist_setup_t::connect_input_output(netlist_input_t &in, netlist_output_t
{
//printf("here 1\n");
nld_d_to_a_proxy *proxy = new nld_d_to_a_proxy(out);
- astring x = "";
- x.printf("proxy_da_%d", m_proxy_cnt++);
- proxy->init(*this, x.cstr());
+ pstring x = pstring::sprintf("proxy_da_%d", m_proxy_cnt);
+ m_proxy_cnt++;
+
+ proxy->init(*this, x);
register_dev(proxy, x);
proxy->m_Q.net().register_con(in);
@@ -320,9 +322,10 @@ void netlist_setup_t::connect_terminal_input(netlist_terminal_t &term, netlist_i
{
NL_VERBOSE_OUT(("connect_terminal_input: connecting proxy\n"));
nld_a_to_d_proxy *proxy = new nld_a_to_d_proxy(inp);
- astring x = "";
- x.printf("proxy_da_%d", m_proxy_cnt++);
- proxy->init(*this, x.cstr());
+ pstring x = pstring::sprintf("proxy_da_%d", m_proxy_cnt);
+ m_proxy_cnt++;
+
+ proxy->init(*this, x);
register_dev(proxy, x);
connect_terminals(term, proxy->m_I);
@@ -355,9 +358,10 @@ void netlist_setup_t::connect_terminal_output(netlist_terminal_t &in, netlist_ou
{
NL_VERBOSE_OUT(("connect_terminal_output: connecting proxy\n"));
nld_d_to_a_proxy *proxy = new nld_d_to_a_proxy(out);
- astring x = "";
- x.printf("proxy_da_%d", m_proxy_cnt++);
- proxy->init(*this, x.cstr());
+ pstring x = pstring::sprintf("proxy_da_%d", m_proxy_cnt);
+ m_proxy_cnt++;
+
+ proxy->init(*this, x);
register_dev(proxy, x);
out.net().register_con(proxy->m_I);
@@ -426,8 +430,8 @@ void netlist_setup_t::resolve_inputs(void)
NL_VERBOSE_OUT(("Resolving ...\n"));
for (tagmap_link_t::entry_t *entry = m_links.first(); entry != NULL; entry = m_links.next(entry))
{
- const astring t1s = entry->object()->e1;
- const astring t2s = entry->object()->e2;
+ const pstring t1s = entry->object().e1;
+ const pstring t2s = entry->object().e2;
netlist_terminal_t &t1 = find_terminal(t1s);
netlist_terminal_t &t2 = find_terminal(t2s);
@@ -490,7 +494,7 @@ void netlist_setup_t::start_devices(void)
for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
{
netlist_device_t *dev = entry->object();
- dev->init(*this, entry->tag());
+ dev->init(*this, entry->tag().cstr());
}
}
@@ -518,7 +522,7 @@ void netlist_setup_t::parse(char *buf)
void netlist_setup_t::print_stats()
{
- if (NL_KEEP_STATISTICS)
+#if (NL_KEEP_STATISTICS)
{
for (netlist_setup_t::tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
{
@@ -530,4 +534,5 @@ void netlist_setup_t::print_stats()
printf("Queue Sort %15d\n", m_netlist.queue().m_prof_sort);
printf("Queue Move %15d\n", m_netlist.queue().m_prof_sortmove);
}
+#endif
}
diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h
index de8452c3806..ba4b5ad3d13 100644
--- a/src/emu/netlist/nl_setup.h
+++ b/src/emu/netlist/nl_setup.h
@@ -68,42 +68,53 @@ public:
struct link_t
{
- link_t(const astring &ae1, const astring &ae2)
+ link_t() { }
+ // Copy constructor
+ link_t(const link_t &from)
+ {
+ e1 = from.e1;
+ e2 = from.e2;
+ }
+
+ link_t(const pstring &ae1, const pstring &ae2)
{
e1 = ae1;
e2 = ae2;
}
- astring e1;
- astring e2;
+ pstring e1;
+ pstring e2;
+
+ bool operator==(const link_t &rhs) const { return (e1 == rhs.e1) && (e2 == rhs.e2); }
+ link_t &operator=(const link_t &rhs) { e1 = rhs.e1; e2 = rhs.e2; return *this; }
};
typedef tagmap_t<netlist_device_t *, 393> tagmap_devices_t;
- typedef tagmap_t<link_t *, 393> tagmap_link_t;
- typedef tagmap_t<const astring *, 393> tagmap_astring_t;
+ typedef tagmap_t<pstring, 393> tagmap_nstring_t;
typedef tagmap_t<netlist_param_t *, 393> tagmap_param_t;
typedef tagmap_t<netlist_terminal_t *, 393> tagmap_terminal_t;
+ typedef netlist_list_t<link_t> tagmap_link_t;
netlist_setup_t(netlist_base_t &netlist);
~netlist_setup_t();
netlist_base_t &netlist() { return m_netlist; }
- netlist_device_t *register_dev(netlist_device_t *dev, const astring &name);
- void remove_dev(const astring &name);
+ netlist_device_t *register_dev(netlist_device_t *dev, const pstring &name);
+ void remove_dev(const pstring &name);
- void register_alias(const astring &alias, const astring &out);
- void register_link(const astring &sin, const astring &sout);
- void register_param(const astring &param, const astring &value);
- void register_param(const astring &param, const double value);
+ void register_alias(const pstring &alias, const pstring &out);
+ void register_link(const pstring &sin, const pstring &sout);
+ void register_param(const pstring &param, const pstring &value);
+ void register_param(const pstring &param, const double value);
- void register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_object_t &obj, netlist_input_t::state_e state);
+ void register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const pstring &name, netlist_object_t &obj, netlist_input_t::state_e state);
- netlist_terminal_t &find_terminal(const astring &outname_in);
- netlist_terminal_t &find_terminal(const astring &outname_in, netlist_object_t::type_t atype);
+ netlist_terminal_t &find_terminal(const pstring &outname_in);
+ netlist_terminal_t &find_terminal(const pstring &outname_in, netlist_object_t::type_t atype);
- netlist_param_t &find_param(const astring &param_in);
+ netlist_param_t &find_param(const pstring &param_in);
- void register_callback(const astring &devname, netlist_output_delegate delegate);
+ void register_callback(const pstring &devname, netlist_output_delegate delegate);
void parse(char *buf);
@@ -123,10 +134,10 @@ private:
netlist_base_t &m_netlist;
tagmap_devices_t m_devices;
- tagmap_astring_t m_alias;
+ tagmap_nstring_t m_alias;
tagmap_param_t m_params;
- tagmap_link_t m_links;
- tagmap_astring_t m_params_temp;
+ tagmap_link_t m_links;
+ tagmap_nstring_t m_params_temp;
int m_proxy_cnt;
@@ -136,9 +147,9 @@ private:
void connect_terminal_input(netlist_terminal_t &term, netlist_input_t &inp);
// helpers
- astring objtype_as_astr(netlist_object_t &in);
+ pstring objtype_as_astr(netlist_object_t &in);
- const astring resolve_alias(const astring &name) const;
+ const pstring resolve_alias(const pstring &name) const;
};
#endif /* NLSETUP_H_ */
diff --git a/src/emu/netlist/nl_time.h b/src/emu/netlist/nl_time.h
index 61b8ebfea6f..2935e35e6af 100644
--- a/src/emu/netlist/nl_time.h
+++ b/src/emu/netlist/nl_time.h
@@ -26,50 +26,50 @@ struct netlist_time
{
public:
- typedef UINT64 INTERNALTYPE;
+ typedef UINT64 INTERNALTYPE;
- static const INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES;
+ static const INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES;
- ATTR_HOT inline netlist_time() : m_time(0) {}
+ ATTR_HOT inline netlist_time() : m_time(0) {}
- ATTR_HOT friend inline const netlist_time operator-(const netlist_time &left, const netlist_time &right);
- ATTR_HOT friend inline const netlist_time operator+(const netlist_time &left, const netlist_time &right);
- ATTR_HOT friend inline const netlist_time operator*(const netlist_time &left, const UINT32 factor);
+ ATTR_HOT friend inline const netlist_time operator-(const netlist_time &left, const netlist_time &right);
+ ATTR_HOT friend inline const netlist_time operator+(const netlist_time &left, const netlist_time &right);
+ ATTR_HOT friend inline const netlist_time operator*(const netlist_time &left, const UINT32 factor);
ATTR_HOT friend inline const UINT32 operator/(const netlist_time &left, const netlist_time &right);
- ATTR_HOT friend inline bool operator>(const netlist_time &left, const netlist_time &right);
- ATTR_HOT friend inline bool operator<(const netlist_time &left, const netlist_time &right);
- ATTR_HOT friend inline bool operator>=(const netlist_time &left, const netlist_time &right);
- ATTR_HOT friend inline bool operator<=(const netlist_time &left, const netlist_time &right);
+ ATTR_HOT friend inline bool operator>(const netlist_time &left, const netlist_time &right);
+ ATTR_HOT friend inline bool operator<(const netlist_time &left, const netlist_time &right);
+ ATTR_HOT friend inline bool operator>=(const netlist_time &left, const netlist_time &right);
+ ATTR_HOT friend inline bool operator<=(const netlist_time &left, const netlist_time &right);
- ATTR_HOT inline const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; }
- ATTR_HOT inline const netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; }
+ ATTR_HOT inline const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; }
+ ATTR_HOT inline const netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; }
- ATTR_HOT inline const INTERNALTYPE as_raw() const { return m_time; }
+ ATTR_HOT inline const INTERNALTYPE as_raw() const { return m_time; }
ATTR_HOT inline const double as_double() const { return (double) m_time / (double) RESOLUTION; }
- ATTR_HOT static inline const netlist_time from_nsec(const int ns) { return netlist_time((UINT64) ns * (RESOLUTION / U64(1000000000))); }
- ATTR_HOT static inline const netlist_time from_usec(const int us) { return netlist_time((UINT64) us * (RESOLUTION / U64(1000000))); }
- ATTR_HOT static inline const netlist_time from_msec(const int ms) { return netlist_time((UINT64) ms * (RESOLUTION / U64(1000))); }
- ATTR_HOT static inline const netlist_time from_hz(const UINT64 hz) { return netlist_time(RESOLUTION / hz); }
- ATTR_HOT static inline const netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw); }
+ ATTR_HOT static inline const netlist_time from_nsec(const int ns) { return netlist_time((UINT64) ns * (RESOLUTION / U64(1000000000))); }
+ ATTR_HOT static inline const netlist_time from_usec(const int us) { return netlist_time((UINT64) us * (RESOLUTION / U64(1000000))); }
+ ATTR_HOT static inline const netlist_time from_msec(const int ms) { return netlist_time((UINT64) ms * (RESOLUTION / U64(1000))); }
+ ATTR_HOT static inline const netlist_time from_hz(const UINT64 hz) { return netlist_time(RESOLUTION / hz); }
+ ATTR_HOT static inline const netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw); }
- static const netlist_time zero;
+ static const netlist_time zero;
protected:
- ATTR_HOT inline netlist_time(const INTERNALTYPE val) : m_time(val) {}
+ ATTR_HOT inline netlist_time(const INTERNALTYPE val) : m_time(val) {}
- INTERNALTYPE m_time;
+ INTERNALTYPE m_time;
};
ATTR_HOT inline const netlist_time operator-(const netlist_time &left, const netlist_time &right)
{
- return netlist_time::from_raw(left.m_time - right.m_time);
+ return netlist_time::from_raw(left.m_time - right.m_time);
}
ATTR_HOT inline const netlist_time operator*(const netlist_time &left, const UINT32 factor)
{
- return netlist_time::from_raw(left.m_time * factor);
+ return netlist_time::from_raw(left.m_time * factor);
}
ATTR_HOT inline const UINT32 operator/(const netlist_time &left, const netlist_time &right)
@@ -79,27 +79,27 @@ ATTR_HOT inline const UINT32 operator/(const netlist_time &left, const netlist_t
ATTR_HOT inline const netlist_time operator+(const netlist_time &left, const netlist_time &right)
{
- return netlist_time::from_raw(left.m_time + right.m_time);
+ return netlist_time::from_raw(left.m_time + right.m_time);
}
ATTR_HOT inline bool operator<(const netlist_time &left, const netlist_time &right)
{
- return (left.m_time < right.m_time);
+ return (left.m_time < right.m_time);
}
ATTR_HOT inline bool operator>(const netlist_time &left, const netlist_time &right)
{
- return (left.m_time > right.m_time);
+ return (left.m_time > right.m_time);
}
ATTR_HOT inline bool operator<=(const netlist_time &left, const netlist_time &right)
{
- return (left.m_time <= right.m_time);
+ return (left.m_time <= right.m_time);
}
ATTR_HOT inline bool operator>=(const netlist_time &left, const netlist_time &right)
{
- return (left.m_time >= right.m_time);
+ return (left.m_time >= right.m_time);
}
diff --git a/src/emu/netlist/pstring.c b/src/emu/netlist/pstring.c
new file mode 100644
index 00000000000..e23718a16a9
--- /dev/null
+++ b/src/emu/netlist/pstring.c
@@ -0,0 +1,218 @@
+/*
+ * nl_string.c
+ *
+ */
+
+#include "pstring.h"
+#include <cstdio>
+
+//nstring::str_t *nstring::m_zero = NULL;
+pstring::str_t *pstring::m_zero = pstring::salloc(0);
+pstring::memblock *pstring::m_first = NULL;
+
+#define IMMEDIATE_MODE (1)
+#define DEBUG_MODE (0)
+
+pstring::~pstring()
+{
+ sfree(m_ptr);
+}
+
+void pstring::init()
+{
+ if (m_zero == NULL)
+ {
+ m_zero = (str_t *) alloc_str(sizeof(str_t) + 1);
+ m_zero->reference_count = 1;
+ m_zero->m_len = 0;
+ m_zero->m_str[0] = 0;
+ }
+ m_ptr = m_zero;
+ m_ptr->reference_count++;
+}
+
+void pstring::pcat(const char *s)
+{
+ int slen = strlen(s);
+ str_t *n = salloc(m_ptr->len() + slen);
+ if (m_ptr->len() > 0)
+ memcpy(n->str(), m_ptr->str(), m_ptr->len());
+ if (slen > 0)
+ memcpy(n->str() + m_ptr->len(), s, slen);
+ *(n->str() + n->len()) = 0;
+ sfree(m_ptr);
+ m_ptr = n;
+}
+
+void pstring::pcopy(const char *from, int size)
+{
+ str_t *n = salloc(size);
+ if (size > 0)
+ memcpy(n->str(), from, size);
+ *(n->str() + size) = 0;
+ sfree(m_ptr);
+ m_ptr = n;
+}
+
+pstring pstring::substr(unsigned int start, int count) const
+{
+ int alen = len();
+ if (start >= alen)
+ return pstring();
+ if (count <0 || start + count > alen)
+ count = alen - start;
+ pstring ret;
+ ret.pcopy(cstr() + start, count);
+ return ret;
+}
+
+pstring pstring::vprintf(va_list args) const
+{
+ // sprintf into the temporary buffer
+ char tempbuf[4096];
+ vsprintf(tempbuf, cstr(), args);
+
+ return pstring(tempbuf);
+}
+
+// ----------------------------------------------------------------------------------------
+// static stuff ...
+// ----------------------------------------------------------------------------------------
+
+void pstring::sfree(str_t *s)
+{
+ s->reference_count--;
+ if (s->reference_count == 0)
+ dealloc_str(s);
+}
+
+pstring::str_t *pstring::salloc(int n)
+{
+ str_t *ret = (str_t *) alloc_str(sizeof(str_t) + n + 1);
+ ret->reference_count = 1;
+ ret->m_len = n;
+ ret->m_str[0] = 0;
+ return ret;
+ //std::printf("old string %d <%s> %p %p\n", n, old, old, m_ptr);
+}
+
+pstring pstring::sprintf(const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ pstring ret = pstring(format).vprintf(ap);
+ va_end(ap);
+ return ret;
+}
+
+char *pstring::alloc_str(int n)
+{
+#if (IMMEDIATE_MODE)
+ return (char *) malloc(n);
+#else
+#if (DEBUG_MODE)
+ int min_alloc = MAX(0, n+sizeof(memblock));
+#else
+ int min_alloc = MAX(8192, n+sizeof(memblock));
+#endif
+ char *ret = NULL;
+
+ //std::printf("m_first %p\n", m_first);
+ for (memblock *p = m_first; p != NULL && ret == NULL; p = p->next)
+ {
+ if (p->remaining > n)
+ {
+ ret = p->cur;
+ p->cur += n;
+ p->allocated += 1;
+ p->remaining -= n;
+ }
+ }
+
+ if (ret == NULL)
+ {
+ // need to allocate a new block
+ memblock *p = (memblock *) malloc(min_alloc); //new char[min_alloc];
+ p->allocated = 0;
+ p->cur = &p->data[0];
+ p->size = p->remaining = min_alloc - sizeof(memblock);
+ p->next = m_first;
+ //std::printf("allocated block size %d\n", p->size);
+
+ ret = p->cur;
+ p->cur += n;
+ p->allocated += 1;
+ p->remaining -= n;
+
+ m_first = p;
+ }
+
+ return ret;
+#endif
+}
+
+void pstring::dealloc_str(void *ptr)
+{
+#if (IMMEDIATE_MODE)
+ free(ptr);
+#else
+ for (memblock *p = m_first; p != NULL; p = p->next)
+ {
+ if (ptr >= &p->data[0] && ptr < &p->data[p->size])
+ {
+ p->allocated -= 1;
+ if (p->allocated < 0)
+ fatalerror("nstring: memory corruption\n");
+ if (p->allocated == 0)
+ {
+ //std::printf("Block entirely freed\n");
+ p->remaining = p->size;
+ p->cur = &p->data[0];
+ }
+ // shutting down ?
+ if (m_zero == NULL)
+ resetmem(); // try to free blocks
+ return;
+ }
+ }
+ fatalerror("nstring: string <%p> not found\n", ptr);
+#endif
+}
+
+void pstring::resetmem()
+{
+#if (IMMEDIATE_MODE)
+#else
+ memblock **p = &m_first;
+ int totalblocks = 0;
+ int freedblocks = 0;
+
+ // Release the 0 string
+ if (m_zero != NULL) sfree(m_zero);
+ m_zero = NULL;
+
+ while (*p != NULL)
+ {
+ totalblocks++;
+ memblock **next = &((*p)->next);
+ if ((*p)->allocated == 0)
+ {
+ //std::printf("freeing block %p\n", *p);
+ memblock *freeme = *p;
+ *p = *next;
+ free(freeme); //delete[] *p;
+ freedblocks++;
+ }
+ else
+ {
+#if (DEBUG_MODE)
+ std::printf("Allocated: <%s>\n", ((str_t *)(&(*p)->data[0]))->str());
+#endif
+ p = next;
+ }
+ }
+#if (DEBUG_MODE)
+ std::printf("Freed %d out of total %d blocks\n", freedblocks, totalblocks);
+#endif
+#endif
+}
diff --git a/src/emu/netlist/pstring.h b/src/emu/netlist/pstring.h
new file mode 100644
index 00000000000..0481b381c35
--- /dev/null
+++ b/src/emu/netlist/pstring.h
@@ -0,0 +1,164 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * pstring.h
+ */
+
+#ifndef _PSTRING_H_
+#define _PSTRING_H_
+
+#include "nl_config.h"
+
+// ----------------------------------------------------------------------------------------
+// nstring: immutable strings ...
+//
+// nstrings are just a pointer to a "pascal-style" string representation.
+// It uses reference counts and only uses new memory when a string changes.
+// ----------------------------------------------------------------------------------------
+
+struct pstring
+{
+public:
+ // simple construction/destruction
+ pstring()
+ {
+ init();
+ }
+ ~pstring();
+
+ // construction with copy
+ pstring(const char *string) {init(); if (string != NULL) pcopy(string); }
+ pstring(const pstring &string) {init(); pcopy(string); }
+
+ // assignment operators
+ pstring &operator=(const char *string) { pcopy(string); return *this; }
+ pstring &operator=(const pstring &string) { pcopy(string); return *this; }
+
+ // C string conversion operators and helpers
+ operator const char *() const { return m_ptr->str(); }
+ inline const char *cstr() const { return m_ptr->str(); }
+
+ // concatenation operators
+ pstring& operator+=(const pstring &string) { pcat(string.cstr()); return *this; }
+ friend pstring operator+(const pstring &lhs, const pstring &rhs) { return pstring(lhs) += rhs; }
+ friend pstring operator+(const pstring &lhs, const char *rhs) { return pstring(lhs) += rhs; }
+ friend pstring operator+(const char *lhs, const pstring &rhs) { return pstring(lhs) += rhs; }
+
+ // comparison operators
+ bool operator==(const char *string) const { return (pcmp(string) == 0); }
+ bool operator==(const pstring &string) const { return (pcmp(string.cstr()) == 0); }
+ bool operator!=(const char *string) const { return (pcmp(string) != 0); }
+ bool operator!=(const pstring &string) const { return (pcmp(string.cstr()) != 0); }
+ bool operator<(const char *string) const { return (pcmp(string) < 0); }
+ bool operator<(const pstring &string) const { return (pcmp(string.cstr()) < 0); }
+ bool operator<=(const char *string) const { return (pcmp(string) <= 0); }
+ bool operator<=(const pstring &string) const { return (pcmp(string.cstr()) <= 0); }
+ bool operator>(const char *string) const { return (pcmp(string) > 0); }
+ bool operator>(const pstring &string) const { return (pcmp(string.cstr()) > 0); }
+ bool operator>=(const char *string) const { return (pcmp(string) >= 0); }
+ bool operator>=(const pstring &string) const { return (pcmp(string.cstr()) >= 0); }
+
+ //
+ inline const int len() const { return m_ptr->len(); }
+
+ inline bool equals(const pstring &string) { return (pcmp(string.cstr(), m_ptr->str()) == 0); }
+ int cmp(pstring &string) { return pcmp(string.cstr()); }
+
+ int find(const char *search, int start = 0) const
+ {
+ int alen = len();
+ const char *result = strstr(cstr() + MIN(start, alen), search);
+ return (result != NULL) ? (result - cstr()) : -1;
+ }
+
+ // various
+
+ bool startsWith(pstring &arg) { return (pcmp(cstr(), arg.cstr(), arg.len()) == 0); }
+ bool startsWith(const char *arg) { return (pcmp(cstr(), arg, strlen(arg)) == 0); }
+
+ // these return nstring ...
+ pstring cat(const pstring &s) const { return *this + s; }
+ pstring cat(const char *s) const { return *this + s; }
+
+ pstring substr(unsigned int start, int count = -1) const ;
+
+ pstring left(unsigned int count) const { return substr(0, count); }
+ pstring right(unsigned int count) const { return substr(len() - count, count); }
+
+ // printf using string as format ...
+
+ pstring vprintf(va_list args) const;
+
+ // static
+ static pstring sprintf(const char *format, ...);
+ static void resetmem();
+
+protected:
+
+ struct str_t
+ {
+ int reference_count;
+ char *str() { return &m_str[0]; }
+ int len() { return m_len; }
+ //private:
+ int m_len;
+ char m_str[];
+ };
+
+ str_t *m_ptr;
+
+private:
+ void init();
+
+ inline int pcmp(const char *right) const
+ {
+ return pcmp(m_ptr->str(), right);
+ }
+
+ inline int pcmp(const char *left, const char *right, int count = -1) const
+ {
+ if (count < 0)
+ return strcmp(left, right);
+ else
+ return strncmp(left, right, count);
+ }
+
+ void pcopy(const char *from, int size);
+
+ inline void pcopy(const char *from)
+ {
+ pcopy(from, strlen(from));
+ }
+
+ inline void pcopy(const pstring &from)
+ {
+ sfree(m_ptr);
+ m_ptr = from.m_ptr;
+ m_ptr->reference_count++;
+ }
+
+ void pcat(const char *s);
+
+ static str_t *m_zero;
+
+ static str_t *salloc(int n);
+ static void sfree(str_t *s);
+
+ struct memblock
+ {
+ memblock *next;
+ int size;
+ int allocated;
+ int remaining;
+ char *cur;
+ char data[];
+ };
+
+ static memblock *m_first;
+ static char *alloc_str(int n);
+ static void dealloc_str(void *ptr);
+};
+
+
+#endif /* _PSTRING_H_ */
+