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.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",

View File

@ -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<netlist_mame_t &>(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<netlist_mame_t &>(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);
}

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:
pstring m_name;
};

View File

@ -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<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)()
{
std::fclose(static_cast<FILE *>(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<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

View File

@ -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) \

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

View File

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

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

View File

@ -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<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:
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

View File

@ -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<m_defines.size(); i++)
{
if (m_defines[i].m_name == name)
return &m_defines[i];
}
return NULL;
int idx = m_defines.index_of(name);
if (idx >= 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<lines.size())
pstring lt = line.replace("\t"," ").trim();
pstringbuffer ret;
m_lineno++;
// FIXME ... revise and extend macro handling
if (lt.startsWith("#"))
{
pstring line = lines[i];
pstring lt = line.replace("\t"," ").trim();
// FIXME ... revise and extend macro handling
if (lt.startsWith("#"))
pstring_list_t lti(lt, " ", true);
if (lti[0].equals("#if"))
{
pstring_list_t lti(lt, " ", true);
if (lti[0].equals("#if"))
m_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)
m_ifflag |= (1 << m_level);
}
else if (lti[0].equals("#ifdef"))
{
m_level++;
if (get_define(lti[1]) == NULL)
m_ifflag |= (1 << m_level);
}
else if (lti[0].equals("#ifndef"))
{
m_level++;
if (get_define(lti[1]) != NULL)
m_ifflag |= (1 << m_level);
}
else if (lti[0].equals("#else"))
{
m_ifflag ^= (1 << m_level);
}
else if (lti[0].equals("#endif"))
{
m_ifflag &= ~(1 << m_level);
m_level--;
}
else if (lti[0].equals("#include"))
{
// ignore
}
else if (lti[0].equals("#pragma"))
{
if (m_ifflag == 0 && lti.size() > 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;
}

View File

@ -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<class ISTR, class OSTR>
OSTR &process(ISTR &istrm, OSTR &ostrm)
{
return dynamic_cast<OSTR &>(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<define_t> m_defines;
pstring process_line(const pstring &line);
phashmap_t<pstring, define_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_ */

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 ...
// ----------------------------------------------------------------------------------------
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)

View File

@ -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();

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)
{
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");

View File

@ -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

View File

@ -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<input_t> *read_input(netlist::netlist_t *netlist, pstring fname)
plist_t<input_t> *ret = palloc(plist_t<input_t>());
if (fname != "")
{
pstring_list_t lines(filetobuf(fname) , "\n");
for (unsigned i=0; i<lines.size(); i++)
{
pstring l = lines[i].trim();
pifilestream f(fname);
do {
pstring l = f.readline();
if (l != "")
{
input_t inp(netlist, l);
ret->add(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<input_t> *inps = read_input(&nt, opts.opt_inp());

View File

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