Added simple stream classes to netlist code. (nw)

This commit is contained in:
couriersud 2015-08-02 02:05:15 +02:00
parent 0bda22c079
commit d0466dd4da
19 changed files with 792 additions and 182 deletions

View File

@ -48,6 +48,8 @@ project "netlist"
MAME_DIR .. "src/emu/netlist/plib/pstring.h", MAME_DIR .. "src/emu/netlist/plib/pstring.h",
MAME_DIR .. "src/emu/netlist/plib/pstring.c", MAME_DIR .. "src/emu/netlist/plib/pstring.c",
MAME_DIR .. "src/emu/netlist/plib/pstring.h", 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.c",
MAME_DIR .. "src/emu/netlist/tools/nl_convert.h", MAME_DIR .. "src/emu/netlist/tools/nl_convert.h",
MAME_DIR .. "src/emu/netlist/analog/nld_bjt.c", MAME_DIR .. "src/emu/netlist/analog/nld_bjt.c",

View File

@ -638,9 +638,13 @@ void netlist_mame_sound_device_t::sound_stream_update(sound_stream &stream, stre
// memregion source support // 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<netlist_mame_t &>(setup->netlist()).machine().root_device().memregion(m_name.cstr())->base(); // FIXME: preprocessor should be a stream!
netlist::parser_t p(*setup); memory_region *mem = downcast<netlist_mame_t &>(setup.netlist()).machine().root_device().memregion(m_name.cstr());
return p.parse(mem, name); pimemstream istrm(mem->base(),mem->bytes() );
pomemstream ostrm;
pimemstream istrm2(ppreprocessor().process(istrm, ostrm));
return netlist::parser_t(istrm2, setup).parse(name);
} }

View File

@ -68,7 +68,7 @@ public:
{ {
} }
bool parse(netlist::setup_t *setup, const pstring name); bool parse(netlist::setup_t &setup, const pstring &name);
private: private:
pstring m_name; pstring m_name;
}; };

View File

@ -19,7 +19,7 @@ NETLIB_START(log)
register_input("I", m_I); register_input("I", m_I);
pstring filename = pstring::sprintf("%s.log", name().cstr()); pstring filename = pstring::sprintf("%s.log", name().cstr());
m_file = fopen(filename, "w"); m_strm = palloc(pofilestream(filename));
} }
NETLIB_RESET(log) NETLIB_RESET(log)
@ -28,12 +28,13 @@ NETLIB_RESET(log)
NETLIB_UPDATE(log) NETLIB_UPDATE(log)
{ {
std::fprintf(static_cast<FILE *>(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)() NETLIB_NAME(log)::~NETLIB_NAME(log)()
{ {
std::fclose(static_cast<FILE *>(m_file)); m_strm->close();
pfree(m_strm);
} }
NETLIB_START(logD) NETLIB_START(logD)
@ -48,7 +49,7 @@ NETLIB_RESET(logD)
NETLIB_UPDATE(logD) NETLIB_UPDATE(logD)
{ {
std::fprintf(static_cast<FILE *>(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 // FIXME: Implement wav later, this must be clock triggered device where the input to be written

View File

@ -18,7 +18,8 @@
#ifndef NLD_LOG_H_ #ifndef NLD_LOG_H_
#define 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_REGISTER_DEV(??PG, _name) \
@ -30,7 +31,7 @@ NETLIB_DEVICE(log,
~NETLIB_NAME(log)(); ~NETLIB_NAME(log)();
analog_input_t m_I; analog_input_t m_I;
protected: protected:
void * m_file; pofilestream *m_strm;
); );
#define LOGD(_name, _I, _I2) \ #define LOGD(_name, _I, _I2) \

View File

@ -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_identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-");
set_number_chars(".0123456789", "0123456789eE-."); //FIXME: processing of numbers set_number_chars(".0123456789", "0123456789eE-."); //FIXME: processing of numbers
char ws[5]; char ws[5];

View File

@ -18,11 +18,12 @@ namespace netlist
{ {
P_PREVENT_COPYING(parser_t) P_PREVENT_COPYING(parser_t)
public: public:
parser_t(setup_t &setup) parser_t(pistream &strm, setup_t &setup)
: ptokenizer(), m_setup(setup), m_buf(NULL) {} : 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 parse_netlist(const pstring &nlname);
void net_alias(); void net_alias();
void dippins(); void dippins();
@ -38,7 +39,6 @@ namespace netlist
void net_local_source(); void net_local_source();
void net_truthtable_start(); void net_truthtable_start();
protected:
/* for debugging messages */ /* for debugging messages */
netlist_t &netlist() { return m_setup.netlist(); } netlist_t &netlist() { return m_setup.netlist(); }

View File

@ -1013,7 +1013,7 @@ void setup_t::include(const pstring &netlist_name)
{ {
for (std::size_t i=0; i < m_sources.size(); i++) 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; return;
} }
netlist().error("unable to find %s in source collection", netlist_name.cstr()); 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 // 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); pimemstream istrm(m_str.cstr(), m_str.len());
return p.parse(m_str, name); 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); pimemstream istrm(m_str.cstr(), m_str.len());
return p.parse(m_str, name); 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);
} }
} }

View File

@ -98,7 +98,7 @@ namespace netlist
virtual ~source_t() { } virtual ~source_t() { }
virtual bool parse(setup_t *setup, const pstring name) = 0; virtual bool parse(setup_t &setup, const pstring &name) = 0;
private: private:
}; };
@ -232,21 +232,6 @@ namespace netlist
source_t::list_t m_sources; source_t::list_t m_sources;
plist_t<pstring> m_lib; plist_t<pstring> m_lib;
#if 0
template <class T>
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: public:
netlist_source_string_t(pstring source) source_string_t(const pstring &source)
: setup_t::source_t(), m_str(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: private:
pstring m_str; pstring m_str;
}; };
class source_file_t : public setup_t::source_t
class netlist_source_mem_t : public setup_t::source_t
{ {
public: 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) : setup_t::source_t(), m_str(mem)
{ {
} }
bool parse(setup_t *setup, const pstring name); bool parse(setup_t &setup, const pstring &name);
private: private:
pstring m_str; 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) if (name == m_setup_func_name)
{ {
m_setup_func(*setup); m_setup_func(setup);
return true; return true;
} }
else else

View File

@ -26,13 +26,7 @@
pstring ptokenizer::currentline_str() pstring ptokenizer::currentline_str()
{ {
char buf[300]; return m_cur_line;
int bufp = 0;
const char *p = m_line_ptr;
while (*p && *p != 10)
buf[bufp++] = *p++;
buf[bufp] = 0;
return pstring(buf);
} }
@ -55,15 +49,17 @@ void ptokenizer::skipeol()
unsigned char ptokenizer::getc() unsigned char ptokenizer::getc()
{ {
if (*m_px == 10) if (m_px >= m_cur_line.len())
{ {
m_line++; if (!m_strm.eof())
m_line_ptr = m_px + 1; {
m_cur_line = m_strm.readline() + "\n";
m_px = 0;
} }
if (*m_px)
return *(m_px++);
else else
return *m_px; return 0;
}
return m_cur_line[m_px++];
} }
void ptokenizer::ungetc() void ptokenizer::ungetc()
@ -273,6 +269,7 @@ ATTR_COLD void ptokenizer::error(const char *format, ...)
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
ppreprocessor::ppreprocessor() ppreprocessor::ppreprocessor()
: m_ifflag(0), m_level(0), m_lineno(0)
{ {
m_expr_sep.add("!"); m_expr_sep.add("!");
m_expr_sep.add("("); m_expr_sep.add("(");
@ -285,7 +282,7 @@ ppreprocessor::ppreprocessor()
m_expr_sep.add(" "); m_expr_sep.add(" ");
m_expr_sep.add("\t"); 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) void ppreprocessor::error(const pstring &err)
@ -367,11 +364,10 @@ double ppreprocessor::expr(const pstring_list_t &sexpr, std::size_t &start, int
ppreprocessor::define_t *ppreprocessor::get_define(const pstring &name) ppreprocessor::define_t *ppreprocessor::get_define(const pstring &name)
{ {
for (std::size_t i = 0; i<m_defines.size(); i++) int idx = m_defines.index_of(name);
{ if (idx >= 0)
if (m_defines[i].m_name == name) return &m_defines.value_at(idx);
return &m_defines[i]; else
}
return NULL; return NULL;
} }
@ -401,52 +397,45 @@ static pstring catremainder(const pstring_list_t &elems, std::size_t start, pstr
return pstring(ret.cstr()); 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<lines.size())
{
pstring line = lines[i];
pstring lt = line.replace("\t"," ").trim(); pstring lt = line.replace("\t"," ").trim();
pstringbuffer ret;
m_lineno++;
// FIXME ... revise and extend macro handling // FIXME ... revise and extend macro handling
if (lt.startsWith("#")) if (lt.startsWith("#"))
{ {
pstring_list_t lti(lt, " ", true); pstring_list_t lti(lt, " ", true);
if (lti[0].equals("#if")) if (lti[0].equals("#if"))
{ {
level++; m_level++;
std::size_t start = 0; std::size_t start = 0;
lt = replace_macros(lt); lt = replace_macros(lt);
pstring_list_t t = pstring_list_t::splitexpr(lt.substr(3).replace(" ",""), m_expr_sep); pstring_list_t t = pstring_list_t::splitexpr(lt.substr(3).replace(" ",""), m_expr_sep);
int val = expr(t, start, 0); int val = expr(t, start, 0);
if (val == 0) if (val == 0)
ifflag |= (1 << level); m_ifflag |= (1 << m_level);
} }
else if (lti[0].equals("#ifdef")) else if (lti[0].equals("#ifdef"))
{ {
level++; m_level++;
if (get_define(lti[1]) == NULL) if (get_define(lti[1]) == NULL)
ifflag |= (1 << level); m_ifflag |= (1 << m_level);
} }
else if (lti[0].equals("#ifndef")) else if (lti[0].equals("#ifndef"))
{ {
level++; m_level++;
if (get_define(lti[1]) != NULL) if (get_define(lti[1]) != NULL)
ifflag |= (1 << level); m_ifflag |= (1 << m_level);
} }
else if (lti[0].equals("#else")) else if (lti[0].equals("#else"))
{ {
ifflag ^= (1 << level); m_ifflag ^= (1 << m_level);
} }
else if (lti[0].equals("#endif")) else if (lti[0].equals("#endif"))
{ {
ifflag &= ~(1 << level); m_ifflag &= ~(1 << m_level);
level--; m_level--;
} }
else if (lti[0].equals("#include")) else if (lti[0].equals("#include"))
{ {
@ -454,7 +443,7 @@ pstring ppreprocessor::process(const pstring &contents)
} }
else if (lti[0].equals("#pragma")) else if (lti[0].equals("#pragma"))
{ {
if (ifflag == 0 && lti.size() > 3 && lti[1].equals("NETLIST")) if (m_ifflag == 0 && lti.size() > 3 && lti[1].equals("NETLIST"))
{ {
if (lti[2].equals("warning")) if (lti[2].equals("warning"))
error("NETLIST: " + catremainder(lti, 3, " ")); error("NETLIST: " + catremainder(lti, 3, " "));
@ -462,30 +451,39 @@ pstring ppreprocessor::process(const pstring &contents)
} }
else if (lti[0].equals("#define")) else if (lti[0].equals("#define"))
{ {
if (ifflag == 0) if (m_ifflag == 0)
{ {
if (lti.size() != 3) if (lti.size() != 3)
error(pstring::sprintf("PREPRO: only simple defines allowed: %s", line.cstr())); error(pstring::sprintf("PREPRO: only simple defines allowed: %s", line.cstr()));
m_defines.add(define_t(lti[1], lti[2])); m_defines.add(lti[1], define_t(lti[1], lti[2]));
} }
} }
else else
error(pstring::sprintf("unknown directive on line %" SIZETFMT ": %s\n", SIZET_PRINTF(i), line.cstr())); error(pstring::sprintf("unknown directive on line %d: %s\n", m_lineno, line.cstr()));
} }
else else
{ {
//if (ifflag == 0 && level > 0) //if (ifflag == 0 && level > 0)
// fprintf(stderr, "conditional: %s\n", line.cstr()); // fprintf(stderr, "conditional: %s\n", line.cstr());
lt = replace_macros(lt); lt = replace_macros(lt);
if (ifflag == 0) if (m_ifflag == 0)
{ {
ret.cat(lt); ret.cat(lt);
ret.cat("\n"); ret.cat("\n");
} }
} }
i++; return ret;
}
postream & ppreprocessor::process_i(pistream &istrm, postream &ostrm)
{
while (!istrm.eof())
{
pstring line = process_line(istrm.readline());
ostrm.writeline(line);
} }
return pstring(ret.cstr()); return ostrm;
} }

View File

@ -11,6 +11,7 @@
#include "pconfig.h" #include "pconfig.h"
#include "pstring.h" #include "pstring.h"
#include "plists.h" #include "plists.h"
#include "pstream.h"
class ptokenizer class ptokenizer
{ {
@ -18,8 +19,8 @@ class ptokenizer
public: public:
virtual ~ptokenizer() {} virtual ~ptokenizer() {}
ptokenizer() ptokenizer(pistream &strm)
: m_line(1), m_line_ptr(NULL), m_px(NULL), m_string('"') : m_strm(strm), m_lineno(1), m_px(0), m_string('"')
{} {}
enum token_type enum token_type
@ -78,7 +79,7 @@ public:
}; };
int currentline_no() { return m_line; } int currentline_no() { return m_lineno; }
pstring currentline_str(); pstring currentline_str();
/* tokenizer stuff follows ... */ /* tokenizer stuff follows ... */
@ -113,8 +114,6 @@ public:
token_t get_token_internal(); token_t get_token_internal();
void error(const char *format, ...) ATTR_PRINTF(2,3); 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: protected:
virtual void verror(pstring msg, int line_num, pstring line) = 0; virtual void verror(pstring msg, int line_num, pstring line) = 0;
@ -123,11 +122,14 @@ private:
unsigned char getc(); unsigned char getc();
void ungetc(); void ungetc();
bool eof() { return *m_px == 0; }
int m_line; bool eof() { return m_strm.eof(); }
const char * m_line_ptr;
const char * m_px; pistream &m_strm;
int m_lineno;
pstring m_cur_line;
unsigned m_px;
/* tokenizer stuff follows ... */ /* tokenizer stuff follows ... */
@ -162,10 +164,16 @@ public:
ppreprocessor(); ppreprocessor();
virtual ~ppreprocessor() {} virtual ~ppreprocessor() {}
pstring process(const pstring &contents); template<class ISTR, class OSTR>
OSTR &process(ISTR &istrm, OSTR &ostrm)
{
return dynamic_cast<OSTR &>(process_i(istrm, ostrm));
}
protected: protected:
postream &process_i(pistream &istrm, postream &ostrm);
double expr(const pstring_list_t &sexpr, std::size_t &start, int prio); double expr(const pstring_list_t &sexpr, std::size_t &start, int prio);
define_t *get_define(const pstring &name); define_t *get_define(const pstring &name);
@ -176,8 +184,15 @@ protected:
private: private:
plist_t<define_t> m_defines; pstring process_line(const pstring &line);
phashmap_t<pstring, define_t> m_defines;
pstring_list_t m_expr_sep; pstring_list_t m_expr_sep;
//pstringbuffer m_ret;
UINT32 m_ifflag; // 31 if levels
int m_level;
int m_lineno;
}; };
#endif /* PPARSER_H_ */ #endif /* PPARSER_H_ */

View File

@ -0,0 +1,267 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* pstream.c
*
*/
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#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;
}

View File

@ -0,0 +1,301 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* pstream.h
*/
#ifndef _PSTREAM_H_
#define _PSTREAM_H_
#include <cstdarg>
#include <cstddef>
#include <stdexcept>
#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_ */

View File

@ -259,6 +259,15 @@ void pstring::resetmem()
// pstring ... // 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, ...) const pstring pstring::sprintf(const char *format, ...)
{ {
va_list ap; va_list ap;
@ -268,7 +277,6 @@ const pstring pstring::sprintf(const char *format, ...)
return ret; return ret;
} }
int pstring::find(const char *search, int start) const int pstring::find(const char *search, int start) const
{ {
int alen = len(); int alen = len();
@ -314,6 +322,7 @@ void pstringbuffer::resize(const std::size_t size)
while (m_size <= size) while (m_size <= size)
m_size *= 2; m_size *= 2;
m_ptr = palloc_array(char, m_size); m_ptr = palloc_array(char, m_size);
*m_ptr = 0;
m_len = 0; m_len = 0;
} }
else if (m_size < size) else if (m_size < size)

View File

@ -123,6 +123,8 @@ public:
const pstring vprintf(va_list args) const; const pstring vprintf(va_list args) const;
int scanf(const char *format, ...) const;
// static // static
static const pstring sprintf(const char *format, ...) ATTR_PRINTF(1,2); static const pstring sprintf(const char *format, ...) ATTR_PRINTF(1,2);
static void resetmem(); static void resetmem();

View File

@ -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) void nl_convert_eagle_t::convert(const pstring &contents)
{ {
eagle_tokenizer tok(*this); pistringstream istrm(contents);
tok.reset(contents.cstr()); eagle_tokenizer tok(*this, istrm);
out("NETLIST_START(dummy)\n"); out("NETLIST_START(dummy)\n");
add_term("GND", "GND"); add_term("GND", "GND");

View File

@ -165,8 +165,8 @@ public:
class eagle_tokenizer : public ptokenizer class eagle_tokenizer : public ptokenizer
{ {
public: public:
eagle_tokenizer(nl_convert_eagle_t &convert) eagle_tokenizer(nl_convert_eagle_t &convert, pistream &strm)
: ptokenizer(), m_convert(convert) : ptokenizer(strm), m_convert(convert)
{ {
set_identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-"); set_identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-");
set_number_chars(".0123456789", "0123456789eE-."); //FIXME: processing of numbers set_number_chars(".0123456789", "0123456789eE-."); //FIXME: processing of numbers

View File

@ -192,11 +192,11 @@ public:
m_setup->init(); m_setup->init();
} }
void read_netlist(const char *buffer, pstring name) void read_netlist(const pstring &filename, const pstring &name)
{ {
// read the netlist ... // 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); m_setup->include(name);
log_setup(); log_setup();
@ -278,7 +278,7 @@ struct input_t
{ {
char buf[400]; char buf[400];
double t; 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) if ( e!= 3)
throw netlist::fatalerror_e("error %d scanning line %s\n", e, line.cstr()); throw netlist::fatalerror_e("error %d scanning line %s\n", e, line.cstr());
m_time = netlist::netlist_time::from_double(t); m_time = netlist::netlist_time::from_double(t);
@ -310,16 +310,15 @@ plist_t<input_t> *read_input(netlist::netlist_t *netlist, pstring fname)
plist_t<input_t> *ret = palloc(plist_t<input_t>()); plist_t<input_t> *ret = palloc(plist_t<input_t>());
if (fname != "") if (fname != "")
{ {
pstring_list_t lines(filetobuf(fname) , "\n"); pifilestream f(fname);
for (unsigned i=0; i<lines.size(); i++) do {
{ pstring l = f.readline();
pstring l = lines[i].trim();
if (l != "") if (l != "")
{ {
input_t inp(netlist, l); input_t inp(netlist, l);
ret->add(inp); ret->add(inp);
} }
} } while (!f.eof());
} }
return ret; return ret;
} }
@ -331,7 +330,7 @@ static void run(tool_options_t &opts)
nt.m_opts = &opts; nt.m_opts = &opts;
nt.init(); nt.init();
nt.read_netlist(filetobuf(opts.opt_file()), opts.opt_name()); nt.read_netlist(opts.opt_file(), opts.opt_name());
plist_t<input_t> *inps = read_input(&nt, opts.opt_inp()); plist_t<input_t> *inps = read_input(&nt, opts.opt_inp());

View File

@ -3,6 +3,7 @@
#include "plib/poptions.h" #include "plib/poptions.h"
#include "plib/pstring.h" #include "plib/pstring.h"
#include "plib/plists.h" #include "plib/plists.h"
#include "plib/pstream.h"
#include "nl_setup.h" #include "nl_setup.h"
class nlwav_options_t : public poptions class nlwav_options_t : public poptions
@ -146,8 +147,8 @@ void convert(nlwav_options_t &opts)
{ {
wav_t wo(opts.opt_out(), 48000); wav_t wo(opts.opt_out(), 48000);
FILE *FIN = std::fopen(opts.opt_inp(),"r"); pifilestream fin(opts.opt_inp());
if (FIN==NULL) if (fin.bad())
throw netlist::fatalerror_e("Error opening input file: %s", opts.opt_inp().cstr()); throw netlist::fatalerror_e("Error opening input file: %s", opts.opt_inp().cstr());
double dt = 1.0 / (double) wo.sample_rate(); double dt = 1.0 / (double) wo.sample_rate();
@ -165,11 +166,12 @@ void convert(nlwav_options_t &opts)
//short sample = 0; //short sample = 0;
while(!std::feof(FIN)) while(!fin.eof())
{ {
#if 1 #if 1
float t = 0.0; float v = 0.0; 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) while (t >= ct)
{ {
outsam += (ct - lt) * cursam; 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 / (maxsam- mean));
printf("Amp - %f\n", -32000.0 / (minsam- mean)); printf("Amp - %f\n", -32000.0 / (minsam- mean));
wo.close(); wo.close();
fclose(FIN); fin.close();
} }