diff --git a/scripts/src/netlist.lua b/scripts/src/netlist.lua index 68f37f477dc..18f0f074d3b 100644 --- a/scripts/src/netlist.lua +++ b/scripts/src/netlist.lua @@ -48,6 +48,8 @@ project "netlist" MAME_DIR .. "src/emu/netlist/plib/pstring.h", MAME_DIR .. "src/emu/netlist/plib/pstring.c", MAME_DIR .. "src/emu/netlist/plib/pstring.h", + MAME_DIR .. "src/emu/netlist/plib/pstream.c", + MAME_DIR .. "src/emu/netlist/plib/pstream.h", MAME_DIR .. "src/emu/netlist/tools/nl_convert.c", MAME_DIR .. "src/emu/netlist/tools/nl_convert.h", MAME_DIR .. "src/emu/netlist/analog/nld_bjt.c", diff --git a/src/emu/machine/netlist.c b/src/emu/machine/netlist.c index 8db7fa3feb4..714564a563e 100644 --- a/src/emu/machine/netlist.c +++ b/src/emu/machine/netlist.c @@ -638,9 +638,13 @@ void netlist_mame_sound_device_t::sound_stream_update(sound_stream &stream, stre // memregion source support // ---------------------------------------------------------------------------------------- -bool netlist_source_memregion_t::parse(netlist::setup_t *setup, const pstring name) +bool netlist_source_memregion_t::parse(netlist::setup_t &setup, const pstring &name) { - const char *mem = (const char *)downcast(setup->netlist()).machine().root_device().memregion(m_name.cstr())->base(); - netlist::parser_t p(*setup); - return p.parse(mem, name); + // FIXME: preprocessor should be a stream! + memory_region *mem = downcast(setup.netlist()).machine().root_device().memregion(m_name.cstr()); + pimemstream istrm(mem->base(),mem->bytes() ); + pomemstream ostrm; + + pimemstream istrm2(ppreprocessor().process(istrm, ostrm)); + return netlist::parser_t(istrm2, setup).parse(name); } diff --git a/src/emu/machine/netlist.h b/src/emu/machine/netlist.h index ed93abbed3d..423919badec 100644 --- a/src/emu/machine/netlist.h +++ b/src/emu/machine/netlist.h @@ -68,7 +68,7 @@ public: { } - bool parse(netlist::setup_t *setup, const pstring name); + bool parse(netlist::setup_t &setup, const pstring &name); private: pstring m_name; }; diff --git a/src/emu/netlist/devices/nld_log.c b/src/emu/netlist/devices/nld_log.c index f6061cc3aab..d7d53aec3c1 100644 --- a/src/emu/netlist/devices/nld_log.c +++ b/src/emu/netlist/devices/nld_log.c @@ -19,7 +19,7 @@ NETLIB_START(log) register_input("I", m_I); pstring filename = pstring::sprintf("%s.log", name().cstr()); - m_file = fopen(filename, "w"); + m_strm = palloc(pofilestream(filename)); } NETLIB_RESET(log) @@ -28,12 +28,13 @@ NETLIB_RESET(log) NETLIB_UPDATE(log) { - std::fprintf(static_cast(m_file), "%20.9e %e\n", netlist().time().as_double(), (nl_double) INPANALOG(m_I)); + m_strm->writeline(pstring::sprintf("%20.9e %e", netlist().time().as_double(), (nl_double) INPANALOG(m_I)).cstr()); } NETLIB_NAME(log)::~NETLIB_NAME(log)() { - std::fclose(static_cast(m_file)); + m_strm->close(); + pfree(m_strm); } NETLIB_START(logD) @@ -48,7 +49,7 @@ NETLIB_RESET(logD) NETLIB_UPDATE(logD) { - std::fprintf(static_cast(m_file), "%e %e\n", netlist().time().as_double(), (nl_double) (INPANALOG(m_I) - INPANALOG(m_I2))); + m_strm->writeline(pstring::sprintf("%e %e", netlist().time().as_double(), (nl_double) (INPANALOG(m_I) - INPANALOG(m_I2))).cstr()); } // FIXME: Implement wav later, this must be clock triggered device where the input to be written diff --git a/src/emu/netlist/devices/nld_log.h b/src/emu/netlist/devices/nld_log.h index 9f7431ed1ee..eb3ae97d75e 100644 --- a/src/emu/netlist/devices/nld_log.h +++ b/src/emu/netlist/devices/nld_log.h @@ -18,9 +18,10 @@ #ifndef NLD_LOG_H_ #define NLD_LOG_H_ -#include "../nl_base.h" +#include "nl_base.h" +#include "plib/pstream.h" -#define LOG(_name, _I) \ +#define LOG(_name, _I) \ NET_REGISTER_DEV(??PG, _name) \ NET_CONNECT(_name, I, _I) @@ -30,7 +31,7 @@ NETLIB_DEVICE(log, ~NETLIB_NAME(log)(); analog_input_t m_I; protected: - void * m_file; + pofilestream *m_strm; ); #define LOGD(_name, _I, _I2) \ diff --git a/src/emu/netlist/nl_parser.c b/src/emu/netlist/nl_parser.c index dbdabbff725..2bd7e1d43b5 100644 --- a/src/emu/netlist/nl_parser.c +++ b/src/emu/netlist/nl_parser.c @@ -34,14 +34,8 @@ ATTR_COLD void parser_t::verror(pstring msg, int line_num, pstring line) } -bool parser_t::parse(const char *buf, const pstring nlname) +bool parser_t::parse(const pstring nlname) { - ppreprocessor prepro; - - pstring processed = prepro.process(buf); - m_buf = processed.cstr(); - - reset(m_buf); set_identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-"); set_number_chars(".0123456789", "0123456789eE-."); //FIXME: processing of numbers char ws[5]; diff --git a/src/emu/netlist/nl_parser.h b/src/emu/netlist/nl_parser.h index 89c2ba4e1e1..2a2086a0d72 100644 --- a/src/emu/netlist/nl_parser.h +++ b/src/emu/netlist/nl_parser.h @@ -18,11 +18,12 @@ namespace netlist { P_PREVENT_COPYING(parser_t) public: - parser_t(setup_t &setup) - : ptokenizer(), m_setup(setup), m_buf(NULL) {} + parser_t(pistream &strm, setup_t &setup) + : ptokenizer(strm), m_setup(setup), m_buf(NULL) {} - bool parse(const char *buf, const pstring nlname = ""); + bool parse(const pstring nlname = ""); + protected: void parse_netlist(const pstring &nlname); void net_alias(); void dippins(); @@ -38,7 +39,6 @@ namespace netlist void net_local_source(); void net_truthtable_start(); - protected: /* for debugging messages */ netlist_t &netlist() { return m_setup.netlist(); } diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c index 9ed22058530..1900cfaed91 100644 --- a/src/emu/netlist/nl_setup.c +++ b/src/emu/netlist/nl_setup.c @@ -1013,7 +1013,7 @@ void setup_t::include(const pstring &netlist_name) { for (std::size_t i=0; i < m_sources.size(); i++) { - if (m_sources[i]->parse(this, netlist_name)) + if (m_sources[i]->parse(*this, netlist_name)) return; } netlist().error("unable to find %s in source collection", netlist_name.cstr()); @@ -1023,16 +1023,31 @@ void setup_t::include(const pstring &netlist_name) // base sources // ---------------------------------------------------------------------------------------- -bool netlist_source_string_t::parse(setup_t *setup, const pstring name) +bool source_string_t::parse(setup_t &setup, const pstring &name) { - parser_t p(*setup); - return p.parse(m_str, name); + pimemstream istrm(m_str.cstr(), m_str.len()); + pomemstream ostrm; + + pimemstream istrm2(ppreprocessor().process(istrm, ostrm)); + return parser_t(istrm2, setup).parse(name); } -bool netlist_source_mem_t::parse(setup_t *setup, const pstring name) +bool source_mem_t::parse(setup_t &setup, const pstring &name) { - parser_t p(*setup); - return p.parse(m_str, name); + pimemstream istrm(m_str.cstr(), m_str.len()); + pomemstream ostrm; + + pimemstream istrm2(ppreprocessor().process(istrm, ostrm)); + return parser_t(istrm2, setup).parse(name); +} + +bool source_file_t::parse(setup_t &setup, const pstring &name) +{ + pifilestream istrm(m_filename); + pomemstream ostrm; + + pimemstream istrm2(ppreprocessor().process(istrm, ostrm)); + return parser_t(istrm2, setup).parse(name); } } diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h index 900fb810878..9f1fbdb9e6f 100644 --- a/src/emu/netlist/nl_setup.h +++ b/src/emu/netlist/nl_setup.h @@ -98,7 +98,7 @@ namespace netlist virtual ~source_t() { } - virtual bool parse(setup_t *setup, const pstring name) = 0; + virtual bool parse(setup_t &setup, const pstring &name) = 0; private: }; @@ -232,21 +232,6 @@ namespace netlist source_t::list_t m_sources; plist_t m_lib; -#if 0 - template - void remove_start_with(T &hm, pstring &sw) - { - for (std::size_t i = hm.size() - 1; i >= 0; i--) - { - pstring x = hm[i]->name(); - if (sw.equals(x.substr(0, sw.len()))) - { - NL_VERBOSE_OUT(("removing %s\n", hm[i]->name().cstr())); - hm.remove(hm[i]); - } - } - } -#endif }; // ---------------------------------------------------------------------------------------- @@ -254,31 +239,46 @@ namespace netlist // ---------------------------------------------------------------------------------------- - class netlist_source_string_t : public setup_t::source_t + class source_string_t : public setup_t::source_t { public: - netlist_source_string_t(pstring source) + source_string_t(const pstring &source) : setup_t::source_t(), m_str(source) { } - bool parse(setup_t *setup, const pstring name); + bool parse(setup_t &setup, const pstring &name); private: pstring m_str; }; - - class netlist_source_mem_t : public setup_t::source_t + class source_file_t : public setup_t::source_t { public: - netlist_source_mem_t(const char *mem) + + source_file_t(const pstring &filename) + : setup_t::source_t(), m_filename(filename) + { + } + + bool parse(setup_t &setup, const pstring &name); + + private: + pstring m_filename; + }; + + class source_mem_t : public setup_t::source_t + { + public: + source_mem_t(const char *mem) : setup_t::source_t(), m_str(mem) { } - bool parse(setup_t *setup, const pstring name); + bool parse(setup_t &setup, const pstring &name); + private: pstring m_str; }; @@ -293,11 +293,11 @@ namespace netlist { } - bool parse(setup_t *setup, const pstring name) + bool parse(setup_t &setup, const pstring &name) { if (name == m_setup_func_name) { - m_setup_func(*setup); + m_setup_func(setup); return true; } else diff --git a/src/emu/netlist/plib/pparser.c b/src/emu/netlist/plib/pparser.c index 9ea2505c327..d501ba03c6c 100644 --- a/src/emu/netlist/plib/pparser.c +++ b/src/emu/netlist/plib/pparser.c @@ -26,13 +26,7 @@ pstring ptokenizer::currentline_str() { - char buf[300]; - int bufp = 0; - const char *p = m_line_ptr; - while (*p && *p != 10) - buf[bufp++] = *p++; - buf[bufp] = 0; - return pstring(buf); + return m_cur_line; } @@ -55,15 +49,17 @@ void ptokenizer::skipeol() unsigned char ptokenizer::getc() { - if (*m_px == 10) + if (m_px >= m_cur_line.len()) { - m_line++; - m_line_ptr = m_px + 1; + if (!m_strm.eof()) + { + m_cur_line = m_strm.readline() + "\n"; + m_px = 0; + } + else + return 0; } - if (*m_px) - return *(m_px++); - else - return *m_px; + return m_cur_line[m_px++]; } void ptokenizer::ungetc() @@ -273,6 +269,7 @@ ATTR_COLD void ptokenizer::error(const char *format, ...) // ---------------------------------------------------------------------------------------- ppreprocessor::ppreprocessor() +: m_ifflag(0), m_level(0), m_lineno(0) { m_expr_sep.add("!"); m_expr_sep.add("("); @@ -285,7 +282,7 @@ ppreprocessor::ppreprocessor() m_expr_sep.add(" "); m_expr_sep.add("\t"); - m_defines.add(define_t("__PLIB_PREPROCESSOR__", "1")); + m_defines.add("__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")); } void ppreprocessor::error(const pstring &err) @@ -367,12 +364,11 @@ double ppreprocessor::expr(const pstring_list_t &sexpr, std::size_t &start, int ppreprocessor::define_t *ppreprocessor::get_define(const pstring &name) { - for (std::size_t i = 0; i= 0) + return &m_defines.value_at(idx); + else + return NULL; } pstring ppreprocessor::replace_macros(const pstring &line) @@ -401,91 +397,93 @@ static pstring catremainder(const pstring_list_t &elems, std::size_t start, pstr return pstring(ret.cstr()); } -pstring ppreprocessor::process(const pstring &contents) +pstring ppreprocessor::process_line(const pstring &line) { - pstringbuffer ret = ""; - pstring_list_t lines(contents,"\n", false); - UINT32 ifflag = 0; // 31 if levels - int level = 0; - - std::size_t i=0; - while (i 3 && lti[1].equals("NETLIST")) { - level++; - std::size_t start = 0; - lt = replace_macros(lt); - pstring_list_t t = pstring_list_t::splitexpr(lt.substr(3).replace(" ",""), m_expr_sep); - int val = expr(t, start, 0); - if (val == 0) - ifflag |= (1 << level); + if (lti[2].equals("warning")) + error("NETLIST: " + catremainder(lti, 3, " ")); } - else if (lti[0].equals("#ifdef")) + } + else if (lti[0].equals("#define")) + { + if (m_ifflag == 0) { - level++; - if (get_define(lti[1]) == NULL) - ifflag |= (1 << level); + if (lti.size() != 3) + error(pstring::sprintf("PREPRO: only simple defines allowed: %s", line.cstr())); + m_defines.add(lti[1], define_t(lti[1], lti[2])); } - else if (lti[0].equals("#ifndef")) - { - level++; - if (get_define(lti[1]) != NULL) - ifflag |= (1 << level); - } - else if (lti[0].equals("#else")) - { - ifflag ^= (1 << level); - } - else if (lti[0].equals("#endif")) - { - ifflag &= ~(1 << level); - level--; - } - else if (lti[0].equals("#include")) - { - // ignore - } - else if (lti[0].equals("#pragma")) - { - if (ifflag == 0 && lti.size() > 3 && lti[1].equals("NETLIST")) - { - if (lti[2].equals("warning")) - error("NETLIST: " + catremainder(lti, 3, " ")); - } - } - else if (lti[0].equals("#define")) - { - if (ifflag == 0) - { - if (lti.size() != 3) - error(pstring::sprintf("PREPRO: only simple defines allowed: %s", line.cstr())); - m_defines.add(define_t(lti[1], lti[2])); - } - } - else - error(pstring::sprintf("unknown directive on line %" SIZETFMT ": %s\n", SIZET_PRINTF(i), line.cstr())); } else - { - //if (ifflag == 0 && level > 0) - // fprintf(stderr, "conditional: %s\n", line.cstr()); - lt = replace_macros(lt); - if (ifflag == 0) - { - ret.cat(lt); - ret.cat("\n"); - } - } - i++; + error(pstring::sprintf("unknown directive on line %d: %s\n", m_lineno, line.cstr())); } - return pstring(ret.cstr()); + else + { + //if (ifflag == 0 && level > 0) + // fprintf(stderr, "conditional: %s\n", line.cstr()); + lt = replace_macros(lt); + if (m_ifflag == 0) + { + ret.cat(lt); + ret.cat("\n"); + } + } + return ret; +} + + +postream & ppreprocessor::process_i(pistream &istrm, postream &ostrm) +{ + while (!istrm.eof()) + { + pstring line = process_line(istrm.readline()); + ostrm.writeline(line); + } + return ostrm; } diff --git a/src/emu/netlist/plib/pparser.h b/src/emu/netlist/plib/pparser.h index 15d81294a09..0583dd09930 100644 --- a/src/emu/netlist/plib/pparser.h +++ b/src/emu/netlist/plib/pparser.h @@ -11,6 +11,7 @@ #include "pconfig.h" #include "pstring.h" #include "plists.h" +#include "pstream.h" class ptokenizer { @@ -18,8 +19,8 @@ class ptokenizer public: virtual ~ptokenizer() {} - ptokenizer() - : m_line(1), m_line_ptr(NULL), m_px(NULL), m_string('"') + ptokenizer(pistream &strm) + : m_strm(strm), m_lineno(1), m_px(0), m_string('"') {} enum token_type @@ -78,7 +79,7 @@ public: }; - int currentline_no() { return m_line; } + int currentline_no() { return m_lineno; } pstring currentline_str(); /* tokenizer stuff follows ... */ @@ -113,8 +114,6 @@ public: token_t get_token_internal(); void error(const char *format, ...) ATTR_PRINTF(2,3); - void reset(const char *p) { m_px = p; m_line = 1; m_line_ptr = p; } - protected: virtual void verror(pstring msg, int line_num, pstring line) = 0; @@ -123,11 +122,14 @@ private: unsigned char getc(); void ungetc(); - bool eof() { return *m_px == 0; } - int m_line; - const char * m_line_ptr; - const char * m_px; + bool eof() { return m_strm.eof(); } + + pistream &m_strm; + + int m_lineno; + pstring m_cur_line; + unsigned m_px; /* tokenizer stuff follows ... */ @@ -162,10 +164,16 @@ public: ppreprocessor(); virtual ~ppreprocessor() {} - pstring process(const pstring &contents); + template + OSTR &process(ISTR &istrm, OSTR &ostrm) + { + return dynamic_cast(process_i(istrm, ostrm)); + } protected: + postream &process_i(pistream &istrm, postream &ostrm); + double expr(const pstring_list_t &sexpr, std::size_t &start, int prio); define_t *get_define(const pstring &name); @@ -176,8 +184,15 @@ protected: private: - plist_t m_defines; + pstring process_line(const pstring &line); + + phashmap_t m_defines; pstring_list_t m_expr_sep; + + //pstringbuffer m_ret; + UINT32 m_ifflag; // 31 if levels + int m_level; + int m_lineno; }; #endif /* PPARSER_H_ */ diff --git a/src/emu/netlist/plib/pstream.c b/src/emu/netlist/plib/pstream.c new file mode 100644 index 00000000000..b778d33b466 --- /dev/null +++ b/src/emu/netlist/plib/pstream.c @@ -0,0 +1,267 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * pstream.c + * + */ + +#include +#include +#include +#include + +#include "pstream.h" +#include "palloc.h" + +// ----------------------------------------------------------------------------- +// Input file stream +// ----------------------------------------------------------------------------- + +pifilestream::pifilestream(const pstring &fname) : pistream(0), m_pos(0) +{ + m_file = fopen(fname, "rb"); + if (m_file == NULL) + { + set_flag(FLAG_ERROR); + set_flag(FLAG_EOF); + set_flag(FLAG_CLOSED); + } + else + { + if (ftell((FILE *) m_file) >= 0) + { + if (fseek((FILE *) m_file, 0, SEEK_SET) >= 0) + set_flag(FLAG_SEEKABLE); + } + } +} + +pifilestream::~pifilestream() +{ + if (!closed()) + close(); +} + +void pifilestream::close() +{ + fclose((FILE *) m_file); + set_flag(FLAG_CLOSED); +} + +unsigned pifilestream::vread(void *buf, unsigned n) +{ + std::size_t r = fread(buf, 1, n, (FILE *) m_file); + if (r < n) + { + if (feof((FILE *) m_file)) + set_flag(FLAG_EOF); + if (ferror((FILE *) m_file)) + set_flag(FLAG_ERROR); + } + m_pos += r; + return r; +} + +void pifilestream::vseek(pos_type n) +{ + check_seekable(); + if (fseek((FILE *) m_file, SEEK_SET, n) < 0) + set_flag(FLAG_ERROR); + else + m_pos = n; + if (feof((FILE *) m_file)) + set_flag(FLAG_EOF); + else + clear_flag(FLAG_EOF); + if (ferror((FILE *) m_file)) + set_flag(FLAG_ERROR); +} + +pifilestream::pos_type pifilestream::vtell() +{ + long ret = ftell((FILE *) m_file); + if (ret < 0) + { + return m_pos; + } + else + return ret; +} + +// ----------------------------------------------------------------------------- +// Output file stream +// ----------------------------------------------------------------------------- + +pofilestream::pofilestream(const pstring &fname) : postream(0), m_pos(0) +{ + m_file = fopen(fname, "wb"); + if (m_file == NULL) + { + set_flag(FLAG_ERROR); + set_flag(FLAG_CLOSED); + } + else + { + if (ftell((FILE *) m_file) >= 0) + { + if (fseek((FILE *) m_file, 0, SEEK_SET) >= 0) + set_flag(FLAG_SEEKABLE); + } + } +} + +pofilestream::~pofilestream() +{ + if (!closed()) + close(); +} + +void pofilestream::close() +{ + fclose((FILE *) m_file); + set_flag(FLAG_CLOSED); +} + +void pofilestream::vwrite(const void *buf, unsigned n) +{ + std::size_t r = fwrite(buf, 1, n, (FILE *) m_file); + if (r < n) + { + if (ferror((FILE *) m_file)) + set_flag(FLAG_ERROR); + } + m_pos += r; +} + +void pofilestream::vseek(pos_type n) +{ + check_seekable(); + if (fseek((FILE *) m_file, SEEK_SET, n) < 0) + set_flag(FLAG_ERROR); + else + { + m_pos = n; + if (ferror((FILE *) m_file)) + set_flag(FLAG_ERROR); + } +} + +pifilestream::pos_type pofilestream::vtell() +{ + long ret = ftell((FILE *) m_file); + if (ret < 0) + { + return m_pos; + } + else + return ret; +} + +// ----------------------------------------------------------------------------- +// Memory stream +// ----------------------------------------------------------------------------- + +pimemstream::pimemstream(const void *mem, const pos_type len) + : pistream(FLAG_SEEKABLE), m_pos(0), m_len(len), m_mem((char *) mem) +{ +} + +pimemstream::pimemstream(const pomemstream &ostrm) +: pistream(FLAG_SEEKABLE), m_pos(0), m_len(ostrm.size()), m_mem((char *) ostrm.memory()) +{ +} + +pimemstream::~pimemstream() +{ +} + +unsigned pimemstream::vread(void *buf, unsigned n) +{ + unsigned ret = (m_pos + n <= m_len) ? n : m_len - m_pos; + + if (ret > 0) + { + memcpy(buf, m_mem + m_pos, ret); + m_pos += ret; + } + + if (ret < n) + set_flag(FLAG_EOF); + + return ret; +} + +void pimemstream::vseek(pos_type n) +{ + m_pos = (n>=m_len) ? m_len : n; + clear_flag(FLAG_EOF); + +} + +pimemstream::pos_type pimemstream::vtell() +{ + return m_pos; +} + +// ----------------------------------------------------------------------------- +// Output memory stream +// ----------------------------------------------------------------------------- + +pomemstream::pomemstream() +: postream(FLAG_SEEKABLE), m_pos(0), m_capacity(1024), m_size(0) +{ + m_mem = palloc_array(char, m_capacity); +} + +pomemstream::~pomemstream() +{ + pfree_array(m_mem); +} + +void pomemstream::vwrite(const void *buf, unsigned n) +{ + if (m_pos + n >= m_capacity) + { + while (m_pos + n >= m_capacity) + m_capacity *= 2; + char *o = m_mem; + m_mem = palloc_array(char, m_capacity); + if (m_mem == NULL) + { + set_flag(FLAG_ERROR); + return; + } + memcpy(m_mem, o, m_pos); + pfree_array(o); + } + + memcpy(m_mem + m_pos, buf, n); + m_pos += n; + m_size = std::max(m_pos, m_size); +} + +void pomemstream::vseek(pos_type n) +{ + m_pos = n; + m_size = std::max(m_pos, m_size); + if (m_size >= m_capacity) + { + while (m_size >= m_capacity) + m_capacity *= 2; + char *o = m_mem; + m_mem = palloc_array(char, m_capacity); + if (m_mem == NULL) + { + set_flag(FLAG_ERROR); + return; + } + memcpy(m_mem, o, m_pos); + pfree_array(o); + } +} + +pstream::pos_type pomemstream::vtell() +{ + return m_pos; +} + diff --git a/src/emu/netlist/plib/pstream.h b/src/emu/netlist/plib/pstream.h new file mode 100644 index 00000000000..45e5d400500 --- /dev/null +++ b/src/emu/netlist/plib/pstream.h @@ -0,0 +1,301 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * pstream.h + */ + +#ifndef _PSTREAM_H_ +#define _PSTREAM_H_ + +#include +#include +#include + +#include "pconfig.h" +#include "pstring.h" + +// ----------------------------------------------------------------------------- +// pstream: things common to all streams +// ----------------------------------------------------------------------------- + +class pstream +{ + P_PREVENT_COPYING(pstream); +public: + + typedef long unsigned pos_type; + + static const pos_type SEEK_EOF = (pos_type) -1; + + pstream(unsigned flags) : m_flags(flags) + { + } + virtual ~pstream() + { + } + + bool bad() const { return ((m_flags & FLAG_ERROR) != 0); } + bool seekable() const { return ((m_flags & FLAG_SEEKABLE) != 0); } + + void seek(pos_type n) + { + check_seekable(); + return vseek(n); + } + + pos_type tell() + { + return vtell(); + } + +protected: + virtual void vseek(pos_type n) = 0; + virtual pos_type vtell() = 0; + + static const unsigned FLAG_EOF = 0x01; + static const unsigned FLAG_ERROR = 0x02; + static const unsigned FLAG_SEEKABLE = 0x04; + static const unsigned FLAG_CLOSED = 0x08; /* convenience flag */ + + bool closed() { return ((m_flags & FLAG_CLOSED) != 0); } + + void set_flag(unsigned flag) + { + m_flags |= flag; + } + void clear_flag(unsigned flag) + { + m_flags &= ~flag; + } + + void check_not_eof() const + { + if (m_flags & FLAG_EOF) + throw std::runtime_error("unexpected eof"); + } + + void check_seekable() const + { + if (m_flags & FLAG_SEEKABLE) + throw std::runtime_error("stream is not seekable"); + } + + unsigned flags() const { return m_flags; } +private: + + unsigned m_flags; +}; + +// ----------------------------------------------------------------------------- +// pistream: input stream +// ----------------------------------------------------------------------------- + +class pistream : public pstream +{ + P_PREVENT_COPYING(pistream); +public: + + pistream(unsigned flags) : pstream(flags) {} + virtual ~pistream() {} + + bool eof() const { return ((flags() & FLAG_EOF) != 0) || bad(); } + + /* this digests linux & dos/windows text files */ + + pstring readline() + { + pstringbuffer buf; + while (!eof()) + { + char c = 0; + if (this->getc(c)) + { + if (c == 10) + return buf; + else if (c != 13) /* ignore CR */ + buf += c; + } + } + return buf; + } + + bool getc(char &c) + { + return (read(&c, 1) == 1); + } + + unsigned read(void *buf, unsigned n) + { + return vread(buf, n); + } + +protected: + /* read up to n bytes from stream */ + virtual unsigned vread(void *buf, unsigned n) = 0; + +private: +}; + +// ----------------------------------------------------------------------------- +// postream: output stream +// ----------------------------------------------------------------------------- + +class postream : public pstream +{ + P_PREVENT_COPYING(postream); +public: + + postream(unsigned flags) : pstream(flags) {} + virtual ~postream() {} + + /* this digests linux & dos/windows text files */ + + void writeline(const pstring &line) + { + write(line.cstr(), line.len()); + putc(10); + } + + void write(const pstring &text) + { + write(text.cstr(), text.len()); + } + + void putc(const char c) + { + write(&c, 1); + } + + void write(const void *buf, unsigned n) + { + vwrite(buf, n); + } + +protected: + /* write n bytes to stream */ + virtual void vwrite(const void *buf, unsigned n) = 0; + +private: +}; + +// ----------------------------------------------------------------------------- +// pomemstream: output string stream +// ----------------------------------------------------------------------------- + +class pomemstream : public postream +{ + P_PREVENT_COPYING(pomemstream); +public: + + pomemstream(); + virtual ~pomemstream(); + + char *memory() const { return m_mem; } + unsigned size() const { return m_size; } + +protected: + /* write n bytes to stream */ + virtual void vwrite(const void *buf, unsigned n); + virtual void vseek(pos_type n); + virtual pos_type vtell(); + +private: + pos_type m_pos; + pos_type m_capacity; + pos_type m_size; + char *m_mem; +}; + +// ----------------------------------------------------------------------------- +// pofilestream: file output stream +// ----------------------------------------------------------------------------- + +class pofilestream : public postream +{ + P_PREVENT_COPYING(pofilestream); +public: + + pofilestream(const pstring &fname); + virtual ~pofilestream(); + + void close(); + +protected: + /* write n bytes to stream */ + virtual void vwrite(const void *buf, unsigned n); + virtual void vseek(pos_type n); + virtual pos_type vtell(); + +private: + void *m_file; + pos_type m_pos; +}; + +// ----------------------------------------------------------------------------- +// pifilestream: file input stream +// ----------------------------------------------------------------------------- + +class pifilestream : public pistream +{ + P_PREVENT_COPYING(pifilestream); +public: + + pifilestream(const pstring &fname); + virtual ~pifilestream(); + + void close(); + +protected: + /* read up to n bytes from stream */ + virtual unsigned vread(void *buf, unsigned n); + virtual void vseek(pos_type n); + virtual pos_type vtell(); + +private: + void *m_file; + pos_type m_pos; +}; + +// ----------------------------------------------------------------------------- +// pimemstream: input memory stream +// ----------------------------------------------------------------------------- + +class pimemstream : public pistream +{ + P_PREVENT_COPYING(pimemstream); +public: + + pimemstream(const void *mem, const pos_type len); + pimemstream(const pomemstream &ostrm); + virtual ~pimemstream(); + +protected: + /* read up to n bytes from stream */ + virtual unsigned vread(void *buf, unsigned n); + virtual void vseek(pos_type n); + virtual pos_type vtell(); + +private: + pos_type m_pos; + pos_type m_len; + char *m_mem; +}; + +// ----------------------------------------------------------------------------- +// pistringstream: input string stream +// ----------------------------------------------------------------------------- + +class pistringstream : public pimemstream +{ + P_PREVENT_COPYING(pistringstream); +public: + + pistringstream(const pstring &str) : pimemstream(str.cstr(), str.len()), m_str(str) { } + +private: + /* only needed for a reference till destruction */ + pstring m_str; +}; + + +#endif /* _PSTREAM_H_ */ diff --git a/src/emu/netlist/plib/pstring.c b/src/emu/netlist/plib/pstring.c index e5f73ffa17b..8d75e019716 100644 --- a/src/emu/netlist/plib/pstring.c +++ b/src/emu/netlist/plib/pstring.c @@ -259,6 +259,15 @@ void pstring::resetmem() // pstring ... // ---------------------------------------------------------------------------------------- +int pstring::scanf(const char *format, ...) const +{ + va_list ap; + va_start(ap, format); + int ret = vsscanf(cstr(), format, ap); + va_end(ap); + return ret; +} + const pstring pstring::sprintf(const char *format, ...) { va_list ap; @@ -268,7 +277,6 @@ const pstring pstring::sprintf(const char *format, ...) return ret; } - int pstring::find(const char *search, int start) const { int alen = len(); @@ -314,6 +322,7 @@ void pstringbuffer::resize(const std::size_t size) while (m_size <= size) m_size *= 2; m_ptr = palloc_array(char, m_size); + *m_ptr = 0; m_len = 0; } else if (m_size < size) diff --git a/src/emu/netlist/plib/pstring.h b/src/emu/netlist/plib/pstring.h index 7a7b536e98a..42ebd920a83 100644 --- a/src/emu/netlist/plib/pstring.h +++ b/src/emu/netlist/plib/pstring.h @@ -123,6 +123,8 @@ public: const pstring vprintf(va_list args) const; + int scanf(const char *format, ...) const; + // static static const pstring sprintf(const char *format, ...) ATTR_PRINTF(1,2); static void resetmem(); diff --git a/src/emu/netlist/tools/nl_convert.c b/src/emu/netlist/tools/nl_convert.c index 59871b96bdf..40c7257edcc 100644 --- a/src/emu/netlist/tools/nl_convert.c +++ b/src/emu/netlist/tools/nl_convert.c @@ -356,11 +356,11 @@ void nl_convert_spice_t::process_line(const pstring &line) } } - +//FIXME: should accept a stream as well void nl_convert_eagle_t::convert(const pstring &contents) { - eagle_tokenizer tok(*this); - tok.reset(contents.cstr()); + pistringstream istrm(contents); + eagle_tokenizer tok(*this, istrm); out("NETLIST_START(dummy)\n"); add_term("GND", "GND"); diff --git a/src/emu/netlist/tools/nl_convert.h b/src/emu/netlist/tools/nl_convert.h index d2e2d238718..650d23dcff6 100644 --- a/src/emu/netlist/tools/nl_convert.h +++ b/src/emu/netlist/tools/nl_convert.h @@ -165,8 +165,8 @@ public: class eagle_tokenizer : public ptokenizer { public: - eagle_tokenizer(nl_convert_eagle_t &convert) - : ptokenizer(), m_convert(convert) + eagle_tokenizer(nl_convert_eagle_t &convert, pistream &strm) + : ptokenizer(strm), m_convert(convert) { set_identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-"); set_number_chars(".0123456789", "0123456789eE-."); //FIXME: processing of numbers diff --git a/src/tools/nltool.c b/src/tools/nltool.c index 5b6ff343b94..0153653ba25 100644 --- a/src/tools/nltool.c +++ b/src/tools/nltool.c @@ -192,11 +192,11 @@ public: m_setup->init(); } - void read_netlist(const char *buffer, pstring name) + void read_netlist(const pstring &filename, const pstring &name) { // read the netlist ... - m_setup->register_source(palloc(netlist::netlist_source_mem_t(buffer))); + m_setup->register_source(palloc(netlist::source_file_t(filename))); m_setup->include(name); log_setup(); @@ -278,7 +278,7 @@ struct input_t { char buf[400]; double t; - int e = sscanf(line.cstr(), "%lf,%[^,],%lf", &t, buf, &m_value); + int e = line.scanf("%lf,%[^,],%lf", &t, buf, &m_value); if ( e!= 3) throw netlist::fatalerror_e("error %d scanning line %s\n", e, line.cstr()); m_time = netlist::netlist_time::from_double(t); @@ -310,16 +310,15 @@ plist_t *read_input(netlist::netlist_t *netlist, pstring fname) plist_t *ret = palloc(plist_t()); if (fname != "") { - pstring_list_t lines(filetobuf(fname) , "\n"); - for (unsigned i=0; iadd(inp); } - } + } while (!f.eof()); } return ret; } @@ -331,7 +330,7 @@ static void run(tool_options_t &opts) nt.m_opts = &opts; nt.init(); - nt.read_netlist(filetobuf(opts.opt_file()), opts.opt_name()); + nt.read_netlist(opts.opt_file(), opts.opt_name()); plist_t *inps = read_input(&nt, opts.opt_inp()); diff --git a/src/tools/nlwav.c b/src/tools/nlwav.c index cc6a5988e3e..d2bc2268a3e 100644 --- a/src/tools/nlwav.c +++ b/src/tools/nlwav.c @@ -3,6 +3,7 @@ #include "plib/poptions.h" #include "plib/pstring.h" #include "plib/plists.h" +#include "plib/pstream.h" #include "nl_setup.h" class nlwav_options_t : public poptions @@ -146,8 +147,8 @@ void convert(nlwav_options_t &opts) { wav_t wo(opts.opt_out(), 48000); - FILE *FIN = std::fopen(opts.opt_inp(),"r"); - if (FIN==NULL) + pifilestream fin(opts.opt_inp()); + if (fin.bad()) throw netlist::fatalerror_e("Error opening input file: %s", opts.opt_inp().cstr()); double dt = 1.0 / (double) wo.sample_rate(); @@ -165,11 +166,12 @@ void convert(nlwav_options_t &opts) //short sample = 0; - while(!std::feof(FIN)) + while(!fin.eof()) { #if 1 float t = 0.0; float v = 0.0; - fscanf(FIN, "%f %f", &t, &v); + pstring line = fin.readline(); + line.scanf("%f %f", &t, &v); while (t >= ct) { outsam += (ct - lt) * cursam; @@ -220,7 +222,7 @@ void convert(nlwav_options_t &opts) printf("Amp + %f\n", 32000.0 / (maxsam- mean)); printf("Amp - %f\n", -32000.0 / (minsam- mean)); wo.close(); - fclose(FIN); + fin.close(); }