netlist: source stream refactoring

* This is an infrastructure change to enable better error reporting
including file/source and line numbers in the future
This commit is contained in:
couriersud 2020-07-28 20:42:44 +02:00
parent 09e987486a
commit 0cbbbdc846
12 changed files with 101 additions and 65 deletions

View File

@ -261,8 +261,8 @@ netlist_source_memregion_t::stream_ptr netlist_source_memregion_t::stream(const
if (m_dev.has_running_machine()) if (m_dev.has_running_machine())
{ {
memory_region *mem = m_dev.memregion(m_name.c_str()); memory_region *mem = m_dev.memregion(m_name.c_str());
stream_ptr ret(std::make_unique<std::istringstream>(pstring(reinterpret_cast<char *>(mem->base()), mem->bytes()))); stream_ptr ret(std::make_unique<std::istringstream>(pstring(reinterpret_cast<char *>(mem->base()), mem->bytes())), name);
ret->imbue(std::locale::classic()); ret.stream().imbue(std::locale::classic());
return ret; return ret;
} }
else else
@ -302,12 +302,12 @@ netlist_data_memregions_t::stream_ptr netlist_data_memregions_t::stream(const ps
memory_region *mem = m_dev.memregion(name.c_str()); memory_region *mem = m_dev.memregion(name.c_str());
if (mem != nullptr) if (mem != nullptr)
{ {
stream_ptr ret(std::make_unique<std::istringstream>(std::string(reinterpret_cast<char *>(mem->base()), mem->bytes()), std::ios_base::binary)); stream_ptr ret(std::make_unique<std::istringstream>(std::string(reinterpret_cast<char *>(mem->base()), mem->bytes()), std::ios_base::binary), name);
ret->imbue(std::locale::classic()); ret.stream().imbue(std::locale::classic());
return ret; return ret;
} }
else else
return stream_ptr(nullptr); return stream_ptr();
} }
else else
{ {
@ -315,12 +315,12 @@ netlist_data_memregions_t::stream_ptr netlist_data_memregions_t::stream(const ps
if (rom_exists(m_dev.mconfig().root_device(), pstring(m_dev.tag()) + ":" + name)) if (rom_exists(m_dev.mconfig().root_device(), pstring(m_dev.tag()) + ":" + name))
{ {
// Create an empty stream. // Create an empty stream.
stream_ptr ret(std::make_unique<std::istringstream>(std::ios_base::binary)); stream_ptr ret(std::make_unique<std::istringstream>(std::ios_base::binary), name);
ret->imbue(std::locale::classic()); ret.stream().imbue(std::locale::classic());
return ret; return ret;
} }
else else
return stream_ptr(nullptr); return stream_ptr();
} }
} }
@ -978,6 +978,8 @@ std::unique_ptr<netlist::netlist_state_t> netlist_mame_device::base_validity_che
{ {
try try
{ {
//plib::chrono::timer<plib::chrono::system_ticks> t;
//t.start();
auto lnetlist = std::make_unique<netlist::netlist_state_t>("netlist", auto lnetlist = std::make_unique<netlist::netlist_state_t>("netlist",
plib::make_unique<netlist_validate_callbacks_t, netlist::host_arena>()); plib::make_unique<netlist_validate_callbacks_t, netlist::host_arena>());
// enable validation mode // enable validation mode
@ -995,6 +997,8 @@ std::unique_ptr<netlist::netlist_state_t> netlist_mame_device::base_validity_che
} }
} }
//t.stop();
//printf("time %s %f\n", this->mconfig().gamedrv().name, t.as_seconds<double>());
return lnetlist; return lnetlist;
} }
catch (memregion_not_set &err) catch (memregion_not_set &err)
@ -1015,6 +1019,7 @@ std::unique_ptr<netlist::netlist_state_t> netlist_mame_device::base_validity_che
void netlist_mame_device::device_validity_check(validity_checker &valid) const void netlist_mame_device::device_validity_check(validity_checker &valid) const
{ {
base_validity_check(valid); base_validity_check(valid);
//rom_exists(mconfig().root_device()); //rom_exists(mconfig().root_device());
LOGDEVCALLS("device_validity_check %s\n", this->mconfig().gamedrv().name); LOGDEVCALLS("device_validity_check %s\n", this->mconfig().gamedrv().name);
@ -1024,7 +1029,6 @@ void netlist_mame_device::device_validity_check(validity_checker &valid) const
void netlist_mame_device::device_start() void netlist_mame_device::device_start()
{ {
LOGDEVCALLS("device_start entry\n"); LOGDEVCALLS("device_start entry\n");
m_attotime_per_clock = attotime(0, m_attoseconds_per_clock); m_attotime_per_clock = attotime(0, m_attoseconds_per_clock);
//netlist().save(*this, m_cur_time, pstring(this->name()), "m_cur_time"); //netlist().save(*this, m_cur_time, pstring(this->name()), "m_cur_time");

View File

@ -28,6 +28,7 @@
#include "../plib/palloc.h" #include "../plib/palloc.h"
#include "../plib/pstream.h" #include "../plib/pstream.h"
#include "../plib/pstring.h" #include "../plib/pstring.h"
#include "../plib/putil.h" // psource_t
#include <memory> #include <memory>
@ -241,7 +242,7 @@ namespace netlist
{ {
} }
std::unique_ptr<std::istream> stream(); plib::psource_t::stream_ptr stream();
protected: protected:
void changed() noexcept override { } void changed() noexcept override { }
}; };
@ -261,7 +262,7 @@ namespace netlist
protected: protected:
void changed() noexcept override void changed() noexcept override
{ {
plib::istream_read(*stream(), m_data.data(), 1<<AW); plib::istream_read(stream().stream(), m_data.data(), 1<<AW);
} }
private: private:

View File

@ -903,7 +903,7 @@ namespace netlist
} }
std::unique_ptr<std::istream> param_data_t::stream() plib::psource_t::stream_ptr param_data_t::stream()
{ {
return device().state().parser().get_data_stream(str()); return device().state().parser().get_data_stream(str());
} }

View File

@ -735,10 +735,10 @@ namespace netlist
param_rom_t<ST, AW, DW>::param_rom_t(core_device_t &device, const pstring &name) param_rom_t<ST, AW, DW>::param_rom_t(core_device_t &device, const pstring &name)
: param_data_t(device, name) : param_data_t(device, name)
{ {
auto f = stream(); auto f = this->stream();
if (f != nullptr) if (!f.empty())
{ {
plib::istream_read(*f, m_data.data(), 1<<AW); plib::istream_read(f.stream(), m_data.data(), 1<<AW);
// FIXME: check for failbit if not in validation. // FIXME: check for failbit if not in validation.
} }
else else

View File

@ -24,7 +24,7 @@ namespace netlist
PERRMSGV(MF_NULLPTR_FAMILY, 2, "Unable to determine family for device {1} from model {2}") PERRMSGV(MF_NULLPTR_FAMILY, 2, "Unable to determine family for device {1} from model {2}")
PERRMSGV(MF_REMOVE_TERMINAL_1_FROM_NET_2, 2, "Can not remove terminal {1} from net {2}.") PERRMSGV(MF_REMOVE_TERMINAL_1_FROM_NET_2, 2, "Can not remove terminal {1} from net {2}.")
PERRMSGV(MF_UNKNOWN_PARAM_TYPE, 1, "Can not determine param_type for {1}") PERRMSGV(MF_UNKNOWN_PARAM_TYPE, 1, "Can not determine param_type for {1}")
PERRMSGV(MF_ERROR_CONNECTING_1_TO_2, 2, "Error connecting {1} to {2}") //PERRMSGV(MF_ERROR_CONNECTING_1_TO_2, 2, "Error connecting {1} to {2}")
PERRMSGV(ME_HND_VAL_NOT_SUPPORTED, 1, "HINT_NO_DEACTIVATE value not supported: <{1}>") PERRMSGV(ME_HND_VAL_NOT_SUPPORTED, 1, "HINT_NO_DEACTIVATE value not supported: <{1}>")
PERRMSGV(MW_ROM_NOT_FOUND, 1, "Rom {1} not found") PERRMSGV(MW_ROM_NOT_FOUND, 1, "Rom {1} not found")

View File

@ -422,10 +422,10 @@ namespace netlist
plib::psource_t::stream_ptr nlparse_t::get_data_stream(const pstring &name) plib::psource_t::stream_ptr nlparse_t::get_data_stream(const pstring &name)
{ {
auto strm = m_sources.get_stream<source_data_t>(name); auto strm = m_sources.get_stream<source_data_t>(name);
if (strm) if (!strm.empty())
return strm; return strm;
log().warning(MW_DATA_1_NOT_FOUND(name)); log().warning(MW_DATA_1_NOT_FOUND(name));
return plib::psource_t::stream_ptr(nullptr); return plib::psource_t::stream_ptr();
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -1650,30 +1650,35 @@ void setup_t::prepare_to_run()
bool source_netlist_t::parse(nlparse_t &setup, const pstring &name) bool source_netlist_t::parse(nlparse_t &setup, const pstring &name)
{ {
auto strm(stream(name)); auto strm(stream(name));
return (strm) ? setup.parse_stream(std::move(strm), name) : false; return (!strm.empty()) ? setup.parse_stream(std::move(strm), name) : false;
} }
source_string_t::stream_ptr source_string_t::stream(const pstring &name) source_string_t::stream_ptr source_string_t::stream(const pstring &name)
{ {
plib::unused_var(name); plib::unused_var(name);
source_string_t::stream_ptr ret(std::make_unique<std::istringstream>(m_str)); source_string_t::stream_ptr ret(std::make_unique<std::istringstream>(m_str), name);
ret->imbue(std::locale::classic()); ret.stream().imbue(std::locale::classic());
return ret; return ret;
} }
source_mem_t::stream_ptr source_mem_t::stream(const pstring &name) source_mem_t::stream_ptr source_mem_t::stream(const pstring &name)
{ {
plib::unused_var(name); plib::unused_var(name);
source_mem_t::stream_ptr ret(std::make_unique<std::istringstream>(m_str, std::ios_base::binary)); source_mem_t::stream_ptr ret(std::make_unique<std::istringstream>(m_str, std::ios_base::binary), name);
ret->imbue(std::locale::classic()); ret.stream().imbue(std::locale::classic());
return ret; return ret;
} }
source_file_t::stream_ptr source_file_t::stream(const pstring &name) source_file_t::stream_ptr source_file_t::stream(const pstring &name)
{ {
plib::unused_var(name); plib::unused_var(name);
auto ret(std::make_unique<plib::ifstream>(plib::filesystem::u8path(m_filename))); auto f = std::make_unique<plib::ifstream>(plib::filesystem::u8path(m_filename));
return (ret->is_open()) ? std::move(ret) : stream_ptr(nullptr); if (f->is_open())
{
return stream_ptr(std::move(f), m_filename);
}
else
return stream_ptr();
} }
bool source_proc_t::parse(nlparse_t &setup, const pstring &name) bool source_proc_t::parse(nlparse_t &setup, const pstring &name)
@ -1690,8 +1695,7 @@ bool source_proc_t::parse(nlparse_t &setup, const pstring &name)
source_proc_t::stream_ptr source_proc_t::stream(const pstring &name) source_proc_t::stream_ptr source_proc_t::stream(const pstring &name)
{ {
plib::unused_var(name); plib::unused_var(name);
stream_ptr p(nullptr); return stream_ptr();
return p;
} }
} // namespace netlist } // namespace netlist

View File

@ -219,8 +219,8 @@ namespace plib {
guard_t guard() noexcept { return guard_t(*this); } guard_t guard() noexcept { return guard_t(*this); }
// pause must be followed by cont(inue) // pause must be followed by cont(inue)
void pause() noexcept { m_time += T::stop(); } void stop() noexcept { m_time += T::stop(); }
void cont() noexcept { m_time -= T::start(); } void start() noexcept { m_time -= T::start(); }
private: private:

View File

@ -560,16 +560,16 @@ namespace plib {
// first try local context // first try local context
auto l(plib::util::buildpath({m_stack.back().m_local_path, arg})); auto l(plib::util::buildpath({m_stack.back().m_local_path, arg}));
auto lstrm(m_sources.get_stream(l)); auto lstrm(m_sources.get_stream(l));
if (lstrm) if (!lstrm.empty())
{ {
m_stack.emplace_back(input_context(std::move(lstrm), plib::util::path(l), l)); m_stack.emplace_back(input_context(lstrm.release_stream(), plib::util::path(l), l));
} }
else else
{ {
auto strm(m_sources.get_stream(arg)); auto strm(m_sources.get_stream(arg));
if (strm) if (!strm.empty())
{ {
m_stack.emplace_back(input_context(std::move(strm), plib::util::path(arg), arg)); m_stack.emplace_back(input_context(strm.release_stream(), plib::util::path(arg), arg));
} }
else else
error("include not found:" + arg); error("include not found:" + arg);

View File

@ -78,7 +78,7 @@ namespace plib {
template <typename T> template <typename T>
ppreprocessor & process(T &&istrm, const pstring &filename) ppreprocessor & process(T &&istrm, const pstring &filename)
{ {
m_stack.emplace_back(input_context(std::forward<T>(istrm),plib::util::path(filename), filename)); m_stack.emplace_back(input_context(istrm.release_stream(),plib::util::path(filename), filename));
process_stack(); process_stack();
return *this; return *this;
} }

View File

@ -154,7 +154,38 @@ namespace plib
{ {
public: public:
using stream_ptr = std::unique_ptr<std::istream>; struct stream_ext
{
explicit stream_ext() = default;
stream_ext(std::unique_ptr<std::istream> &&strm, const pstring &filename)
: m_strm(std::move(strm))
, m_filename(filename)
{
}
stream_ext(const stream_ext &) = delete;
stream_ext &operator=(const stream_ext &) = delete;
stream_ext(stream_ext &&rhs) /*noexcept*/
{
m_strm = std::move(rhs.m_strm);
m_filename = rhs.m_filename;
}
stream_ext &operator=(stream_ext &&) /*noexcept*/ = delete;
std::istream &stream() noexcept { return *m_strm; }
pstring filename() { return m_filename; }
bool empty() { return m_strm == nullptr; }
// FIXME: workaround input conext should accept stream_ptr
std::unique_ptr<std::istream> release_stream() { return std::move(m_strm); }
private:
std::unique_ptr<std::istream> m_strm;
pstring m_filename;
};
using stream_ptr = stream_ext; //FIXME: rename to stream_type
psource_t() noexcept = default; psource_t() noexcept = default;
@ -184,9 +215,9 @@ namespace plib
typename psource_t::stream_ptr stream(const pstring &name) override typename psource_t::stream_ptr stream(const pstring &name) override
{ {
if (name == m_name) if (name == m_name)
return std::make_unique<std::stringstream>(m_str); return stream_ptr(std::make_unique<std::stringstream>(m_str), name);
return psource_t::stream_ptr(nullptr); return psource_t::stream_ptr();
} }
private: private:
pstring m_name; pstring m_name;
@ -223,11 +254,11 @@ namespace plib
if (source) if (source)
{ {
auto strm = source->stream(name); auto strm = source->stream(name);
if (strm) if (!strm.empty())
return strm; return strm;
} }
} }
return typename S::stream_ptr(nullptr); return typename S::stream_ptr();
} }
template <typename S, typename F> template <typename S, typename F>

View File

@ -216,11 +216,11 @@ public:
stream_ptr stream(const pstring &file) override stream_ptr stream(const pstring &file) override
{ {
pstring name = m_folder + "/" + file; pstring name = m_folder + "/" + file;
stream_ptr strm(std::make_unique<plib::ifstream>(plib::filesystem::u8path(name))); stream_ptr strm(std::make_unique<plib::ifstream>(plib::filesystem::u8path(name)), plib::filesystem::u8path(name));
if (strm->fail()) if (strm.stream().fail())
return stream_ptr(nullptr); return stream_ptr();
strm->imbue(std::locale::classic()); strm.stream().imbue(std::locale::classic());
return strm; return strm;
} }
@ -459,11 +459,9 @@ void tool_app_t::run()
if (!plib::util::exists(opt_files()[0])) if (!plib::util::exists(opt_files()[0]))
throw netlist::nl_exception("nltool: file doesn't exists: {}", opt_files()[0]); throw netlist::nl_exception("nltool: file doesn't exists: {}", opt_files()[0]);
netlist_tool_t nt(*this, "netlist", opt_boostlib()); t.start();
{ netlist_tool_t nt(*this, "netlist", opt_boostlib());
auto t_guard(t.guard());
//plib::perftime_t<plib::exact_ticks> t;
nt.exec().enable_stats(opt_stats()); nt.exec().enable_stats(opt_stats());
@ -482,9 +480,7 @@ void tool_app_t::run()
nt.exec().reset(); nt.exec().reset();
ttr = netlist::netlist_time_ext::from_fp(opt_ttr()); ttr = netlist::netlist_time_ext::from_fp(opt_ttr());
} t.stop();
pout("startup time ==> {1:5.3f}\n", t.as_seconds<netlist::nl_fptype>() ); pout("startup time ==> {1:5.3f}\n", t.as_seconds<netlist::nl_fptype>() );
// FIXME: error handling // FIXME: error handling

View File

@ -81,14 +81,14 @@ namespace devices
} }
else else
{ {
stats()->m_stat_total_time.pause(); stats()->m_stat_total_time.stop();
for (std::size_t i = 0; i < p; i++) for (std::size_t i = 0; i < p; i++)
{ {
tmp[i]->stats()->m_stat_call_count.inc(); tmp[i]->stats()->m_stat_call_count.inc();
auto g(tmp[i]->stats()->m_stat_total_time.guard()); auto g(tmp[i]->stats()->m_stat_total_time.guard());
nt[i] = tmp[i]->solve(now, "no-parallel"); nt[i] = tmp[i]->solve(now, "no-parallel");
} }
stats()->m_stat_total_time.cont(); stats()->m_stat_total_time.start();
} }
for (std::size_t i = 0; i < p; i++) for (std::size_t i = 0; i < p; i++)