diff options
-rw-r--r-- | nl_examples/congo_bongo.c | 5 | ||||
-rw-r--r-- | src/emu/machine/netlist.c | 18 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_system.h | 2 | ||||
-rw-r--r-- | src/emu/netlist/nl_base.c | 2 | ||||
-rw-r--r-- | src/emu/netlist/nl_setup.c | 5 | ||||
-rw-r--r-- | src/emu/netlist/plib/plists.h | 16 | ||||
-rw-r--r-- | src/emu/netlist/plib/pparser.c | 23 | ||||
-rw-r--r-- | src/emu/netlist/plib/pparser.h | 2 | ||||
-rw-r--r-- | src/emu/netlist/plib/pstream.c | 4 | ||||
-rw-r--r-- | src/emu/netlist/plib/pstream.h | 33 | ||||
-rw-r--r-- | src/emu/netlist/plib/pstring.c | 344 | ||||
-rw-r--r-- | src/emu/netlist/plib/pstring.h | 355 | ||||
-rw-r--r-- | src/emu/netlist/tools/nl_convert.c | 10 | ||||
-rw-r--r-- | src/tools/nltool.c | 19 | ||||
-rw-r--r-- | src/tools/nlwav.c | 5 |
15 files changed, 563 insertions, 280 deletions
diff --git a/nl_examples/congo_bongo.c b/nl_examples/congo_bongo.c index f3b701a8196..d57f2ae388b 100644 --- a/nl_examples/congo_bongo.c +++ b/nl_examples/congo_bongo.c @@ -1,3 +1,6 @@ + +/* € */ // ABC + #include "netlist/devices/net_lib.h" #include "netlist/devices/nld_system.h" #include "netlist/analog/nld_bjt.h" @@ -33,7 +36,7 @@ NETLIST_START(dummy) // IGNORED O_AUDIO0: O_AUDIO0 64 0 // .END - SOLVER(Solver, 24000) + /* €€ */ SOLVER(Solver, 24000) PARAM(Solver.ACCURACY, 1e-8) PARAM(Solver.NR_LOOPS, 150) PARAM(Solver.SOR_FACTOR, 0.001) diff --git a/src/emu/machine/netlist.c b/src/emu/machine/netlist.c index 714564a563e..bccb11bb4f0 100644 --- a/src/emu/machine/netlist.c +++ b/src/emu/machine/netlist.c @@ -405,29 +405,29 @@ ATTR_COLD void netlist_mame_device_t::save_state() case DT_DOUBLE: { double *td = s->resolved<double>(); - if (td != NULL) save_pointer(td, s->m_name, s->m_count); + if (td != NULL) save_pointer(td, s->m_name.cstr(), s->m_count); } break; case DT_FLOAT: { float *td = s->resolved<float>(); - if (td != NULL) save_pointer(td, s->m_name, s->m_count); + if (td != NULL) save_pointer(td, s->m_name.cstr(), s->m_count); } break; case DT_INT64: - save_pointer((INT64 *) s->m_ptr, s->m_name, s->m_count); + save_pointer((INT64 *) s->m_ptr, s->m_name.cstr(), s->m_count); break; case DT_INT16: - save_pointer((INT16 *) s->m_ptr, s->m_name, s->m_count); + save_pointer((INT16 *) s->m_ptr, s->m_name.cstr(), s->m_count); break; case DT_INT8: - save_pointer((INT8 *) s->m_ptr, s->m_name, s->m_count); + save_pointer((INT8 *) s->m_ptr, s->m_name.cstr(), s->m_count); break; case DT_INT: - save_pointer((int *) s->m_ptr, s->m_name, s->m_count); + save_pointer((int *) s->m_ptr, s->m_name.cstr(), s->m_count); break; case DT_BOOLEAN: - save_pointer((bool *) s->m_ptr, s->m_name, s->m_count); + save_pointer((bool *) s->m_ptr, s->m_name.cstr(), s->m_count); break; case DT_CUSTOM: break; @@ -470,11 +470,11 @@ void netlist_mame_cpu_device_t::device_start() netlist::net_t *n = netlist().m_nets[i]; if (n->isFamily(netlist::object_t::LOGIC)) { - state_add(i*2, n->name(), downcast<netlist::logic_net_t *>(n)->Q_state_ptr()); + state_add(i*2, n->name().cstr(), downcast<netlist::logic_net_t *>(n)->Q_state_ptr()); } else { - state_add(i*2+1, n->name(), downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr()).formatstr("%20s"); + state_add(i*2+1, n->name().cstr(), downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr()).formatstr("%20s"); } } diff --git a/src/emu/netlist/devices/nld_system.h b/src/emu/netlist/devices/nld_system.h index a2ae9d10d01..d3f1aff8935 100644 --- a/src/emu/netlist/devices/nld_system.h +++ b/src/emu/netlist/devices/nld_system.h @@ -478,7 +478,7 @@ public: ATTR_COLD factory_lib_entry_t(setup_t &setup, const pstring &name, const pstring &classname, const pstring &def_param) - : base_factory_t(name, classname, def_param), m_setup(setup) { } + : base_factory_t(name, classname, def_param), m_setup(setup) { printf("devname %s\n", classname.cstr()); } class dummy : public device_t { diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c index fca4bf6d089..e7ef9d66a64 100644 --- a/src/emu/netlist/nl_base.c +++ b/src/emu/netlist/nl_base.c @@ -102,7 +102,7 @@ void queue_t::on_pre_save() pstring p = this->listptr()[i].object()->name(); int n = p.len(); n = std::min(63, n); - std::strncpy(m_names[i].m_buf, p, n); + std::strncpy(m_names[i].m_buf, p.cstr(), n); m_names[i].m_buf[n] = 0; } } diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c index 22426ac7677..228a54c090f 100644 --- a/src/emu/netlist/nl_setup.c +++ b/src/emu/netlist/nl_setup.c @@ -140,7 +140,7 @@ device_t *setup_t::register_dev(const pstring &classname, const pstring &name) void setup_t::register_model(const pstring &model_in) { - int pos = model_in.find(' '); + int pos = model_in.find(" "); if (pos < 0) netlist().error("Unable to parse model: %s", model_in.cstr()); pstring model = model_in.left(pos).trim().ucase(); @@ -955,10 +955,11 @@ void setup_t::model_parse(const pstring &model_in, model_map_t &map) if (!remainder.endsWith(")")) netlist().error("Model error %s\n", model.cstr()); remainder = remainder.left(remainder.len() - 1); + pstring_list_t pairs(remainder," ", true); for (unsigned i=0; i<pairs.size(); i++) { - int pose = pairs[i].find('='); + int pose = pairs[i].find("="); if (pose < 0) netlist().error("Model error on pair %s\n", model.cstr()); map[pairs[i].left(pose).ucase()] = pairs[i].substr(pose+1); diff --git a/src/emu/netlist/plib/plists.h b/src/emu/netlist/plib/plists.h index 96f2d41f42e..af3521bd7db 100644 --- a/src/emu/netlist/plib/plists.h +++ b/src/emu/netlist/plib/plists.h @@ -580,12 +580,12 @@ public: pstring col = ""; int i = 0; - while (i<str.len()) + while (i<str.blen()) { int p = -1; for (std::size_t j=0; j < onstrl.size(); j++) { - if (std::strncmp(onstrl[j].cstr(), &(str.cstr()[i]), onstrl[j].len())==0) + if (std::memcmp(onstrl[j].cstr(), &(str.cstr()[i]), onstrl[j].blen())==0) { p = j; break; @@ -595,14 +595,16 @@ public: { if (col != "") temp.add(col); + col = ""; temp.add(onstrl[p]); - i += onstrl[p].len(); + i += onstrl[p].blen(); } else { - col += str.cstr()[i]; - i++; + pstring::traits::code_t c = pstring::traits::code(str.cstr() + i); + col += c; + i+=pstring::traits::codelen(c); } } if (col != "") @@ -639,9 +641,9 @@ struct phash_functor<pstring> phash_functor(const pstring &v) { /* modified djb2 */ - const char *string = v.cstr(); + const pstring::mem_t *string = v.cstr(); unsigned result = 5381; - for (UINT8 c = *string; c != 0; c = *string++) + for (pstring::mem_t c = *string; c != 0; c = *string++) result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ c; //result = (result*33) ^ c; m_hash = result; diff --git a/src/emu/netlist/plib/pparser.c b/src/emu/netlist/plib/pparser.c index d80c3f83327..8473d58fc2a 100644 --- a/src/emu/netlist/plib/pparser.c +++ b/src/emu/netlist/plib/pparser.c @@ -31,7 +31,7 @@ pstring ptokenizer::currentline_str() void ptokenizer::skipeol() { - char c = getc(); + pstring::code_t c = getc(); while (c) { if (c == 10) @@ -46,19 +46,19 @@ void ptokenizer::skipeol() } -unsigned char ptokenizer::getc() +pstring::code_t ptokenizer::getc() { if (m_px >= m_cur_line.len()) { - if (!m_strm.eof()) + if (m_strm.readline(m_cur_line)) { - m_cur_line = m_strm.readline() + "\n"; + m_cur_line += "\n"; m_px = 0; } else return 0; } - return m_cur_line[m_px++]; + return m_cur_line.code_at(m_px++); } void ptokenizer::ungetc() @@ -160,14 +160,16 @@ ptokenizer::token_t ptokenizer::get_token() skipeol(); } else + { return ret; + } } } ptokenizer::token_t ptokenizer::get_token_internal() { /* skip ws */ - char c = getc(); + pstring::code_t c = getc(); while (m_whitespace.find(c)>=0) { c = getc(); @@ -382,7 +384,7 @@ pstring ppreprocessor::replace_macros(const pstring &line) else ret.cat(elems[i]); } - return pstring(ret.cstr()); + return ret; } static pstring catremainder(const pstring_list_t &elems, std::size_t start, pstring sep) @@ -462,8 +464,6 @@ pstring ppreprocessor::process_line(const pstring &line) } else { - //if (ifflag == 0 && level > 0) - // fprintf(stderr, "conditional: %s\n", line.cstr()); lt = replace_macros(lt); if (m_ifflag == 0) { @@ -477,9 +477,10 @@ pstring ppreprocessor::process_line(const pstring &line) postream & ppreprocessor::process_i(pistream &istrm, postream &ostrm) { - while (!istrm.eof()) + pstring line; + while (istrm.readline(line)) { - pstring line = process_line(istrm.readline()); + line = process_line(line); ostrm.writeline(line); } return ostrm; diff --git a/src/emu/netlist/plib/pparser.h b/src/emu/netlist/plib/pparser.h index 0583dd09930..95356dae224 100644 --- a/src/emu/netlist/plib/pparser.h +++ b/src/emu/netlist/plib/pparser.h @@ -120,7 +120,7 @@ protected: private: void skipeol(); - unsigned char getc(); + pstring::code_t getc(); void ungetc(); bool eof() { return m_strm.eof(); } diff --git a/src/emu/netlist/plib/pstream.c b/src/emu/netlist/plib/pstream.c index b778d33b466..07ef55730da 100644 --- a/src/emu/netlist/plib/pstream.c +++ b/src/emu/netlist/plib/pstream.c @@ -19,7 +19,7 @@ pifilestream::pifilestream(const pstring &fname) : pistream(0), m_pos(0) { - m_file = fopen(fname, "rb"); + m_file = fopen(fname.cstr(), "rb"); if (m_file == NULL) { set_flag(FLAG_ERROR); @@ -94,7 +94,7 @@ pifilestream::pos_type pifilestream::vtell() pofilestream::pofilestream(const pstring &fname) : postream(0), m_pos(0) { - m_file = fopen(fname, "wb"); + m_file = fopen(fname.cstr(), "wb"); if (m_file == NULL) { set_flag(FLAG_ERROR); diff --git a/src/emu/netlist/plib/pstream.h b/src/emu/netlist/plib/pstream.h index e82141b0371..d0cfd8e21d8 100644 --- a/src/emu/netlist/plib/pstream.h +++ b/src/emu/netlist/plib/pstream.h @@ -103,24 +103,29 @@ public: /* this digests linux & dos/windows text files */ - pstring readline() + bool readline(pstring &line) { + UINT8 c = 0; pstringbuffer buf; - while (!eof()) + if (!this->read(c)) { - char c = 0; - if (this->getc(c)) - { - if (c == 10) - return buf; - else if (c != 13) /* ignore CR */ - buf += c; - } + line = ""; + return false; } - return buf; + while (true) + { + if (c == 10) + break; + else if (c != 13) /* ignore CR */ + buf += c; + if (!this->read(c)) + break; + } + line = buf; + return true; } - bool getc(char &c) + bool read(UINT8 &c) { return (read(&c, 1) == 1); } @@ -153,13 +158,13 @@ public: void writeline(const pstring &line) { - write(line.cstr(), line.len()); + write(line.cstr(), line.blen()); write(10); } void write(const pstring &text) { - write(text.cstr(), text.len()); + write(text.cstr(), text.blen()); } void write(const char c) diff --git a/src/emu/netlist/plib/pstring.c b/src/emu/netlist/plib/pstring.c index 3533a26f922..8ff8ae8c9a7 100644 --- a/src/emu/netlist/plib/pstring.c +++ b/src/emu/netlist/plib/pstring.c @@ -15,12 +15,11 @@ #include "pstring.h" #include "palloc.h" -// The following will work on linux, however not on Windows .... +template<> +pstr_t pstring_t<putf8_traits>::m_zero = pstr_t(0); +template<> +pstr_t pstring_t<pu8_traits>::m_zero = pstr_t(0); -//pblockpool *pstring::m_pool = new pblockpool; -//pstring::str_t *pstring::m_zero = new(pstring::m_pool, 0) pstring::str_t(0); - -pstring::str_t pstring::m_zero = str_t(0); /* * Uncomment the following to override defaults @@ -45,15 +44,17 @@ pstring::str_t pstring::m_zero = str_t(0); #endif #endif -pstring::~pstring() +template<typename F> +pstring_t<F>::~pstring_t() { sfree(m_ptr); } -void pstring::pcat(const char *s) +template<typename F> +void pstring_t<F>::pcat(const mem_t *s) { int slen = strlen(s); - str_t *n = salloc(m_ptr->len() + slen); + pstr_t *n = salloc(m_ptr->len() + slen); if (m_ptr->len() > 0) std::memcpy(n->str(), m_ptr->str(), m_ptr->len()); if (slen > 0) @@ -63,9 +64,49 @@ void pstring::pcat(const char *s) m_ptr = n; } -void pstring::pcopy(const char *from, int size) +template<typename F> +void pstring_t<F>::pcat(const pstring_t &s) +{ + int slen = s.blen(); + pstr_t *n = salloc(m_ptr->len() + slen); + if (m_ptr->len() > 0) + std::memcpy(n->str(), m_ptr->str(), m_ptr->len()); + if (slen > 0) + std::memcpy(n->str() + m_ptr->len(), s.cstr(), slen); + *(n->str() + n->len()) = 0; + sfree(m_ptr); + m_ptr = n; +} + +template<typename F> +int pstring_t<F>::pcmp(const pstring_t &right) const +{ + long l = std::min(blen(), right.blen()); + if (l == 0) + { + if (blen() == 0 && right.blen() == 0) + return 0; + else if (right.blen() == 0) + return 1; + else + return -1; + } + int ret = memcmp(m_ptr->str(), right.cstr(), l); + if (ret == 0) + ret = this->blen() - right.blen(); + if (ret < 0) + return -1; + else if (ret > 0) + return 1; + else + return 0; +} + + +template<typename F> +void pstring_t<F>::pcopy(const mem_t *from, int size) { - str_t *n = salloc(size); + pstr_t *n = salloc(size); if (size > 0) std::memcpy(n->str(), from, size); *(n->str() + size) = 0; @@ -73,78 +114,123 @@ void pstring::pcopy(const char *from, int size) m_ptr = n; } -const pstring pstring::substr(unsigned int start, int count) const +template<typename F> +const pstring_t<F> pstring_t<F>::substr(int start, int count) const { - pstring ret; + pstring_t ret; unsigned alen = len(); + if (start < 0) + start = 0; if (start >= alen) return ret; if (count <0 || start + count > alen) count = alen - start; - ret.pcopy(cstr() + start, count); + const char *p = cstr(); + if (count <= 0) + ret.pcopy(p, 0); + else + { + //FIXME: Trait to tell which one + //ret.pcopy(cstr() + start, count); + // find start + for (int i=0; i<start; i++) + p += F::codelen(p); + const char *e = p; + for (int i=0; i<count; i++) + e += F::codelen(e); + ret.pcopy(p, e-p); + } return ret; } -const pstring pstring::ucase() const +template<typename F> +const pstring_t<F> pstring_t<F>::ucase() const { - pstring ret = *this; - ret.pcopy(cstr(), len()); + pstring_t ret = *this; + ret.pcopy(cstr(), blen()); for (int i=0; i<ret.len(); i++) ret.m_ptr->str()[i] = toupper((unsigned) ret.m_ptr->str()[i]); return ret; } -int pstring::find_first_not_of(const pstring &no) const +template<typename F> +int pstring_t<F>::find_first_not_of(const pstring_t &no) const { - for (int i=0; i < len(); i++) + char *t = m_ptr->str(); + unsigned nolen = no.len(); + unsigned tlen = len(); + for (int i=0; i < tlen; i++) { + char *n = no.m_ptr->str(); bool f = true; - for (int j=0; j < no.len(); j++) - if (m_ptr->str()[i] == no.m_ptr->str()[j]) + for (int j=0; j < nolen; j++) + { + if (F::code(t) == F::code(n)) f = false; + n += F::codelen(t); + } if (f) return i; + t += F::codelen(t); } return -1; } -int pstring::find_last_not_of(const pstring &no) const +template<typename F> +int pstring_t<F>::find_last_not_of(const pstring_t &no) const { - for (int i=len() - 1; i >= 0; i--) + char *t = m_ptr->str(); + unsigned nolen = no.len(); + unsigned tlen = len(); + int last_found = -1; + for (int i=0; i < tlen; i++) { + char *n = no.m_ptr->str(); bool f = true; - for (int j=0; j < no.len(); j++) - if (m_ptr->str()[i] == no.m_ptr->str()[j]) + for (int j=0; j < nolen; j++) + { + if (F::code(t) == F::code(n)) f = false; + n += F::codelen(t); + } if (f) - return i; + last_found = i; + t += F::codelen(t); } - return -1; + return last_found; } -pstring pstring::replace(const pstring &search, const pstring &replace) const +template<typename F> +pstring_t<F> pstring_t<F>::replace(const pstring_t &search, const pstring_t &replace) const { - pstring ret = ""; + // FIXME: use this pstringbuffer ret = ""; + pstring_t ret = ""; + const int slen = search.blen(); + const int tlen = blen(); - if (search.len() == 0) + if (slen == 0 || tlen < slen ) return *this; int i = 0; - while (i<len()) + while (i < tlen - slen + 1) { - if (strncmp(cstr()+i,search.cstr(),search.len()) == 0) + if (memcmp(cstr()+i,search.cstr(),slen) == 0) { ret += replace; - i += search.len(); + i += slen; } else { - ret += *(cstr() + i); + /* avoid adding a code, cat a string ... */ + mem_t buf[2] = { *(cstr() + i), 0 }; + ret = ret.cat(buf); i++; } } return ret; } -const pstring pstring::ltrim(const pstring &ws) const + +template<typename F> +const pstring_t<F> pstring_t<F>::ltrim(const pstring_t &ws) const { int f = find_first_not_of(ws); if (f>=0) @@ -153,7 +239,8 @@ const pstring pstring::ltrim(const pstring &ws) const return ""; } -const pstring pstring::rtrim(const pstring &ws) const +template<typename F> +const pstring_t<F> pstring_t<F>::rtrim(const pstring_t &ws) const { int f = find_last_not_of(ws); if (f>=0) @@ -162,32 +249,26 @@ const pstring pstring::rtrim(const pstring &ws) const return ""; } -void pstring::pcopy(const char *from) +template<typename F> +const pstring_t<F> pstring_t<F>::rpad(const pstring_t &ws, const int cnt) const { - pcopy(from, strlen(from)); + // FIXME: pstringbuffer ret(*this); + + pstring_t ret(*this); + while (ret.len() < cnt) + ret += ws; + return pstring_t(ret).substr(0, cnt); } -//------------------------------------------------- -// pcmpi - compare a character array to an nstring -//------------------------------------------------- -int pstring::pcmpi(const char *lhs, const char *rhs, int count) const +template<typename F> +void pstring_t<F>::pcopy(const mem_t *from) { - // loop while equal until we hit the end of strings - int index; - for (index = 0; index < count; index++) - if (lhs[index] == 0 || std::tolower(lhs[index]) != std::tolower(rhs[index])) - break; - - // determine the final result - if (index < count) - return std::tolower(lhs[index]) - std::tolower(rhs[index]); - if (lhs[index] == 0) - return 0; - return 1; + pcopy(from, strlen(from)); } -double pstring::as_double(bool *error) const +template<typename F> +double pstring_t<F>::as_double(bool *error) const { double ret; char *e = NULL; @@ -201,7 +282,8 @@ double pstring::as_double(bool *error) const return ret; } -long pstring::as_long(bool *error) const +template<typename F> +long pstring_t<F>::as_long(bool *error) const { long ret; char *e = NULL; @@ -209,7 +291,7 @@ long pstring::as_long(bool *error) const if (error != NULL) *error = false; if (startsWith("0x")) - ret = strtol(&(cstr()[2]), &e, 16); + ret = strtol(substr(2).cstr(), &e, 16); else ret = strtol(cstr(), &e, 10); if (*e != 0) @@ -218,20 +300,12 @@ long pstring::as_long(bool *error) const return ret; } -const pstring pstring::vprintf(va_list args) const -{ - // sprintf into the temporary buffer - char tempbuf[4096]; - std::vsprintf(tempbuf, cstr(), args); - - return pstring(tempbuf); -} - // ---------------------------------------------------------------------------------------- // static stuff ... // ---------------------------------------------------------------------------------------- -void pstring::sfree(str_t *s) +template<typename F> +void pstring_t<F>::sfree(pstr_t *s) { s->m_ref_count--; if (s->m_ref_count == 0 && s != &m_zero) @@ -241,16 +315,18 @@ void pstring::sfree(str_t *s) } } -pstring::str_t *pstring::salloc(int n) +template<typename F> +pstr_t *pstring_t<F>::salloc(int n) { - int size = sizeof(str_t) + n + 1; - str_t *p = (str_t *) palloc_array(char, size); + int size = sizeof(pstr_t) + n + 1; + pstr_t *p = (pstr_t *) palloc_array(char, size); // str_t *p = (str_t *) _mm_malloc(size, 8); p->init(n); return p; } -void pstring::resetmem() +template<typename F> +void pstring_t<F>::resetmem() { // Release the 0 string } @@ -259,49 +335,116 @@ void pstring::resetmem() // pstring ... // ---------------------------------------------------------------------------------------- -int pstring::scanf(const char *format, ...) const +int pstring::scanf(const type_t &format, ...) const { va_list ap; va_start(ap, format); - int ret = vsscanf(cstr(), format, ap); + int ret = vsscanf(cstr(), format.cstr(), ap); va_end(ap); return ret; } -const pstring pstring::sprintf(const char *format, ...) +const pstring::type_t pstring::vprintf(va_list args) const +{ + // sprintf into the temporary buffer + char tempbuf[4096]; + std::vsprintf(tempbuf, cstr(), args); + + return pstring_t(tempbuf); +} + + +const pstring::type_t pstring::sprintf(const char *format, ...) { va_list ap; va_start(ap, format); - pstring ret = pstring(format).vprintf(ap); + pstring_t ret = pstring(format).vprintf(ap); va_end(ap); return ret; } -int pstring::find(const char *search, int start) const +template<typename F> +int pstring_t<F>::find(const pstring_t &search, unsigned start) const +{ + const unsigned tlen = len(); + const unsigned slen = search.len(); + const char *s = search.cstr(); + const unsigned startt = std::min(start, tlen); + const char *t = cstr(); + for (int i=0; i<startt; i++) + t += F::codelen(t); + for (int i=0; i <= (int) tlen - (int) startt - (int) slen; i++) + { + if (F::code(t) == F::code(s)) + if (std::memcmp(t,s,search.blen())==0) + return i+startt; + t += F::codelen(t); + } + return -1; +} + +template<typename F> +int pstring_t<F>::find(const mem_t *search, unsigned start) const { - int alen = len(); - const char *result = std::strstr(cstr() + std::min(start, alen), search); - return (result != NULL) ? (result - cstr()) : -1; + const unsigned tlen = len(); + unsigned slen = 0; + unsigned sblen = 0; + const mem_t *x = search; + while (*x != 0) + { + slen++; + const unsigned sl = F::codelen(x); + x += sl; + sblen += sl; + } + const char *s = search; + const unsigned startt = std::min(start, tlen); + const char *t = cstr(); + for (int i=0; i<startt; i++) + t += F::codelen(t); + for (int i=0; i <= (int) tlen - (int) startt - (int) slen; i++) + { + if (F::code(t) == F::code(s)) + if (std::memcmp(t,s,sblen)==0) + return i+startt; + t += F::codelen(t); + } + return -1; } -int pstring::find(const char search, int start) const +template<typename F> +bool pstring_t<F>::startsWith(const pstring_t &arg) const { - int alen = len(); - const char *result = std::strchr(cstr() + std::min(start, alen), search); - return (result != NULL) ? (result - cstr()) : -1; + if (arg.blen() > blen()) + return false; + else + return (memcmp(arg.cstr(), cstr(), arg.len()) == 0); } -bool pstring::startsWith(const char *arg) const +template<typename F> +bool pstring_t<F>::endsWith(const pstring_t &arg) const { - return (pcmp(cstr(), arg, std::strlen(arg)) == 0); + if (arg.blen() > blen()) + return false; + else + return (memcmp(cstr()+this->len()-arg.len(), arg.cstr(), arg.len()) == 0); } -int pstring::pcmp(const char *left, const char *right, int count) const + +template<typename F> +bool pstring_t<F>::startsWith(const mem_t *arg) const { - if (count < 0) - return std::strcmp(left, right); + int alen = strlen(arg); + if (alen > blen()) + return false; else - return std::strncmp(left, right, count); + return (memcmp(arg, cstr(), alen) == 0); +} + +template<typename F> +int pstring_t<F>::pcmp(const mem_t *right) const +{ + return std::strcmp(m_ptr->str(), right); } // ---------------------------------------------------------------------------------------- @@ -330,7 +473,7 @@ void pstringbuffer::resize(const std::size_t size) while (m_size < size) m_size *= 2; char *new_buf = palloc_array(char, m_size); - std::strncpy(new_buf, m_ptr, m_len + 1); + std::memcpy(new_buf, m_ptr, m_len + 1); pfree_array(m_ptr); m_ptr = new_buf; } @@ -340,30 +483,35 @@ void pstringbuffer::pcopy(const char *from) { std::size_t nl = strlen(from) + 1; resize(nl); - std::strncpy(m_ptr, from, nl); + std::memcpy(m_ptr, from, nl); } void pstringbuffer::pcopy(const pstring &from) { - std::size_t nl = from.len() + 1; + std::size_t nl = from.blen() + 1; resize(nl); - std::strncpy(m_ptr, from.cstr(), nl); + std::memcpy(m_ptr, from.cstr(), nl); } void pstringbuffer::pcat(const char *s) { - std::size_t slen = std::strlen(s); - std::size_t nl = m_len + slen + 1; + const std::size_t slen = std::strlen(s); + const std::size_t nl = m_len + slen + 1; resize(nl); - std::strncpy(m_ptr + m_len, s, slen + 1); + std::memcpy(m_ptr + m_len, s, slen + 1); m_len += slen; } void pstringbuffer::pcat(const pstring &s) { - std::size_t slen = s.len(); - std::size_t nl = m_len + slen + 1; + const std::size_t slen = s.blen(); + const std::size_t nl = m_len + slen + 1; resize(nl); - std::strncpy(m_ptr + m_len, s.cstr(), slen + 1); + std::memcpy(m_ptr + m_len, s.cstr(), slen); m_len += slen; + m_ptr[m_len] = 0; } + +template struct pstring_t<pu8_traits>; +template struct pstring_t<putf8_traits>; + diff --git a/src/emu/netlist/plib/pstring.h b/src/emu/netlist/plib/pstring.h index 42ebd920a83..013593e4f55 100644 --- a/src/emu/netlist/plib/pstring.h +++ b/src/emu/netlist/plib/pstring.h @@ -19,140 +19,141 @@ // It uses reference counts and only uses new memory when a string changes. // ---------------------------------------------------------------------------------------- -struct pstring + struct pstr_t + { + //str_t() : m_ref_count(1), m_len(0) { m_str[0] = 0; } + pstr_t(const int alen) + { + init(alen); + } + void init(const int alen) + { + m_ref_count = 1; + m_len = alen; + m_str[0] = 0; + } + char *str() { return &m_str[0]; } + int len() const { return m_len; } + int m_ref_count; + private: + int m_len; + char m_str[1]; + }; + + +template <typename F> +struct pstring_t { public: + typedef F traits; + + typedef typename traits::mem_t mem_t; + typedef typename traits::code_t code_t; + // simple construction/destruction - pstring() + pstring_t() { init(); } - ~pstring(); + ~pstring_t(); // construction with copy - pstring(const char *string) {init(); if (string != NULL && *string != 0) pcopy(string); } - pstring(const pstring &string) {init(); pcopy(string); } + pstring_t(const mem_t *string) {init(); if (string != NULL && *string != 0) pcopy(string); } + pstring_t(const pstring_t &string) {init(); pcopy(string); } // assignment operators - pstring &operator=(const char *string) { pcopy(string); return *this; } - pstring &operator=(const pstring &string) { pcopy(string); return *this; } + pstring_t &operator=(const mem_t *string) { pcopy(string); return *this; } + pstring_t &operator=(const pstring_t &string) { pcopy(string); return *this; } - // C string conversion operators and helpers - operator const char *() const { return m_ptr->str(); } - const char *cstr() const { return m_ptr->str(); } + // C string conversion helpers + const mem_t *cstr() const { return m_ptr->str(); } // concatenation operators - pstring& operator+=(const char c) { char buf[2] = { c, 0 }; pcat(buf); return *this; } - pstring& operator+=(const pstring &string) { pcat(string.cstr()); return *this; } - pstring& operator+=(const char *string) { pcat(string); return *this; } - friend pstring operator+(const pstring &lhs, const pstring &rhs) { return pstring(lhs) += rhs; } - friend pstring operator+(const pstring &lhs, const char *rhs) { return pstring(lhs) += rhs; } - friend pstring operator+(const pstring &lhs, const char rhs) { return pstring(lhs) += rhs; } - friend pstring operator+(const char *lhs, const pstring &rhs) { return pstring(lhs) += rhs; } + pstring_t& operator+=(const pstring_t &string) { pcat(string); return *this; } + pstring_t& operator+=(const mem_t *string) { pcat(string); return *this; } + friend pstring_t operator+(const pstring_t &lhs, const pstring_t &rhs) { return pstring_t(lhs) += rhs; } + friend pstring_t operator+(const pstring_t &lhs, const mem_t *rhs) { return pstring_t(lhs) += rhs; } + friend pstring_t operator+(const mem_t *lhs, const pstring_t &rhs) { return pstring_t(lhs) += rhs; } // comparison operators - bool operator==(const char *string) const { return (pcmp(string) == 0); } - bool operator==(const pstring &string) const { return (pcmp(string.cstr()) == 0); } - bool operator!=(const char *string) const { return (pcmp(string) != 0); } - bool operator!=(const pstring &string) const { return (pcmp(string.cstr()) != 0); } - bool operator<(const char *string) const { return (pcmp(string) < 0); } - bool operator<(const pstring &string) const { return (pcmp(string.cstr()) < 0); } - bool operator<=(const char *string) const { return (pcmp(string) <= 0); } - bool operator<=(const pstring &string) const { return (pcmp(string.cstr()) <= 0); } - bool operator>(const char *string) const { return (pcmp(string) > 0); } - bool operator>(const pstring &string) const { return (pcmp(string.cstr()) > 0); } - bool operator>=(const char *string) const { return (pcmp(string) >= 0); } - bool operator>=(const pstring &string) const { return (pcmp(string.cstr()) >= 0); } - - int len() const { return m_ptr->len(); } - - bool equals(const pstring &string) const { return (pcmp(string.cstr(), m_ptr->str()) == 0); } - bool iequals(const pstring &string) const { return (pcmpi(string.cstr(), m_ptr->str()) == 0); } + bool operator==(const mem_t *string) const { return (pcmp(string) == 0); } + bool operator==(const pstring_t &string) const { return (pcmp(string) == 0); } + bool operator!=(const mem_t *string) const { return (pcmp(string) != 0); } + bool operator!=(const pstring_t &string) const { return (pcmp(string) != 0); } - int cmp(const pstring &string) const { return pcmp(string.cstr()); } - int cmpi(const pstring &string) const { return pcmpi(cstr(), string.cstr()); } + bool operator<(const mem_t *string) const { return (pcmp(string) < 0); } + bool operator<(const pstring_t &string) const { return (pcmp(string) < 0); } + bool operator<=(const mem_t *string) const { return (pcmp(string) <= 0); } + bool operator<=(const pstring_t &string) const { return (pcmp(string) <= 0); } + bool operator>(const mem_t *string) const { return (pcmp(string) > 0); } + bool operator>(const pstring_t &string) const { return (pcmp(string) > 0); } + bool operator>=(const mem_t *string) const { return (pcmp(string) >= 0); } + bool operator>=(const pstring_t &string) const { return (pcmp(string) >= 0); } - int find(const char *search, int start = 0) const; + bool equals(const pstring_t &string) const { return (pcmp(string) == 0); } - int find(const char search, int start = 0) const; + int cmp(const pstring_t &string) const { return pcmp(string); } + int cmp(const mem_t *string) const { return pcmp(string); } - // various + bool startsWith(const pstring_t &arg) const; + bool startsWith(const mem_t *arg) const; - bool startsWith(const pstring &arg) const { return (pcmp(cstr(), arg.cstr(), arg.len()) == 0); } - bool startsWith(const char *arg) const; + bool endsWith(const pstring_t &arg) const; + bool endsWith(const mem_t *arg) const { return endsWith(pstring_t(arg)); } - bool endsWith(const pstring &arg) const { return (this->right(arg.len()) == arg); } - bool endsWith(const char *arg) const { return endsWith(pstring(arg)); } + pstring_t replace(const pstring_t &search, const pstring_t &replace) const; - pstring replace(const pstring &search, const pstring &replace) const; + const pstring_t cat(const pstring_t &s) const { return *this + s; } + const pstring_t cat(const mem_t *s) const { return *this + s; } - // these return nstring ... - const pstring cat(const pstring &s) const { return *this + s; } - const pstring cat(const char *s) const { return *this + s; } + unsigned blen() const { return m_ptr->len(); } - const pstring substr(unsigned int start, int count = -1) const ; - - const pstring left(unsigned int count) const { return substr(0, count); } - const pstring right(unsigned int count) const { return substr(len() - count, count); } + // conversions - int find_first_not_of(const pstring &no) const; - int find_last_not_of(const pstring &no) const; + double as_double(bool *error = NULL) const; + long as_long(bool *error = NULL) const; - const pstring ltrim(const pstring &ws = " \t\n\r") const; - const pstring rtrim(const pstring &ws = " \t\n\r") const; - const pstring trim(const pstring &ws = " \t\n\r") const { return this->ltrim(ws).rtrim(ws); } + /* + * everything below MAY not work for utf8. + * Example a=s.find(EUROSIGN); b=s.substr(a,1); will deliver invalid utf8 + */ - const pstring rpad(const pstring &ws, const int cnt) const + unsigned len() const { - // FIXME: slow! - pstring ret = *this; - while (ret.len() < cnt) - ret += ws; - return ret.substr(0, cnt); + return F::len(m_ptr); } - const pstring ucase() const; + pstring_t& operator+=(const code_t c) { mem_t buf[F::MAXCODELEN+1] = { 0 }; F::encode(c, buf); pcat(buf); return *this; } + friend pstring_t operator+(const pstring_t &lhs, const mem_t rhs) { return pstring_t(lhs) += rhs; } - // conversions + int find(const pstring_t &search, unsigned start = 0) const; + int find(const mem_t *search, unsigned start = 0) const; + int find(const code_t search, unsigned start = 0) const { mem_t buf[F::MAXCODELEN+1] = { 0 }; F::encode(search, buf); return find(buf, start); }; - double as_double(bool *error = NULL) const; + const pstring_t substr(int start, int count = -1) const ; - long as_long(bool *error = NULL) const; + const pstring_t left(unsigned count) const { return substr(0, count); } + const pstring_t right(unsigned count) const { return substr((int) len() - (int) count, count); } - // printf using string as format ... + int find_first_not_of(const pstring_t &no) const; + int find_last_not_of(const pstring_t &no) const; - const pstring vprintf(va_list args) const; + // FIXME: + code_t code_at(const unsigned pos) const { return F::code(F::nthcode(m_ptr->str(),pos)); } - int scanf(const char *format, ...) const; + const pstring_t ltrim(const pstring_t &ws = " \t\n\r") const; + const pstring_t rtrim(const pstring_t &ws = " \t\n\r") const; + const pstring_t trim(const pstring_t &ws = " \t\n\r") const { return this->ltrim(ws).rtrim(ws); } + + const pstring_t rpad(const pstring_t &ws, const int cnt) const; + + const pstring_t ucase() const; - // static - static const pstring sprintf(const char *format, ...) ATTR_PRINTF(1,2); static void resetmem(); protected: - struct str_t - { - //str_t() : m_ref_count(1), m_len(0) { m_str[0] = 0; } - str_t(const int alen) - { - init(alen); - } - void init(const int alen) - { - m_ref_count = 1; - m_len = alen; - m_str[0] = 0; - } - char *str() { return &m_str[0]; } - int len() { return m_len; } - int m_ref_count; - private: - int m_len; - char m_str[1]; - }; - - str_t *m_ptr; + pstr_t *m_ptr; private: void init() @@ -161,32 +162,156 @@ private: m_ptr->m_ref_count++; } - int pcmp(const char *right) const - { - return pcmp(m_ptr->str(), right); - } - - int pcmp(const char *left, const char *right, int count = -1) const; + int pcmp(const pstring_t &right) const; - int pcmpi(const char *lhs, const char *rhs, int count = -1) const; + int pcmp(const mem_t *right) const; - void pcopy(const char *from, int size); + void pcopy(const mem_t *from, int size); - void pcopy(const char *from); + void pcopy(const mem_t *from); - void pcopy(const pstring &from) + void pcopy(const pstring_t &from) { sfree(m_ptr); m_ptr = from.m_ptr; m_ptr->m_ref_count++; } - void pcat(const char *s); + void pcat(const mem_t *s); + void pcat(const pstring_t &s); + + static pstr_t *salloc(int n); + static void sfree(pstr_t *s); + + static pstr_t m_zero; +}; + +struct pu8_traits +{ + static const unsigned MAXCODELEN = 1; /* in memory units */ + typedef char mem_t; + typedef char code_t; + static unsigned len(const pstr_t *p) { return p->len(); } + static unsigned codelen(const mem_t *p) { return 1; } + static unsigned codelen(const code_t c) { return 1; } + static code_t code(const mem_t *p) { return *p; } + static void encode(const code_t c, mem_t *p) { *p = c; } + static const mem_t *nthcode(const mem_t *p, const unsigned n) { return &(p[n]); } +}; + +/* No checking, this may deliver invalid codes */ +struct putf8_traits +{ + static const unsigned MAXCODELEN = 4; /* in memory units, RFC 3629 */ + typedef char mem_t; + typedef unsigned code_t; + static unsigned len(pstr_t *p) + { + unsigned ret = 0; + unsigned char *c = (unsigned char *) p->str(); + while (*c) + { + if (!((*c & 0xC0) == 0x80)) + ret++; + c++; + } + return ret; + } + static unsigned codelen(const mem_t *p) + { + unsigned char *p1 = (unsigned char *) p; + if ((*p1 & 0x80) == 0x00) + return 1; + else if ((*p1 & 0xE0) == 0xC0) + return 2; + else if ((*p1 & 0xF0) == 0xE0) + return 3; + else if ((*p1 & 0xF8) == 0xF0) + return 4; + else + { + return 1; // not correct + } + } + static unsigned codelen(const code_t c) + { + if (c < 0x0080) + return 1; + else if (c < 0x800) + return 2; + else if (c < 0x10000) + return 3; + else /* U+10000 U+1FFFFF */ + return 4; /* no checks */ + } + static code_t code(const mem_t *p) + { + unsigned char *p1 = (unsigned char *)p; + if ((*p1 & 0x80) == 0x00) + return (code_t) *p1; + else if ((*p1 & 0xE0) == 0xC0) + return ((p1[0] & 0x3f) << 6) | ((p1[1] & 0x3f)); + else if ((*p1 & 0xF0) == 0xE0) + return ((p1[0] & 0x1f) << 12) | ((p1[1] & 0x3f) << 6) | ((p1[2] & 0x3f) << 0); + else if ((*p1 & 0xF8) == 0xF0) + return ((p1[0] & 0x0f) << 18) | ((p1[1] & 0x3f) << 12) | ((p1[2] & 0x3f) << 6) | ((p1[3] & 0x3f) << 0); + else + return *p1; // not correct + } + static void encode(const code_t c, mem_t *p) + { + unsigned char *m = (unsigned char*)p; + if (c < 0x0080) + { + m[0] = c; + } + else if (c < 0x800) + { + m[0] = 0xC0 | (c >> 6); + m[1] = 0x80 | (c & 0x3f); + } + else if (c < 0x10000) + { + m[0] = 0xE0 | (c >> 12); + m[1] = 0x80 | ((c>>6) & 0x3f); + m[2] = 0x80 | (c & 0x3f); + } + else /* U+10000 U+1FFFFF */ + { + m[0] = 0xF0 | (c >> 18); + m[1] = 0x80 | ((c>>12) & 0x3f); + m[2] = 0x80 | ((c>>6) & 0x3f); + m[3] = 0x80 | (c & 0x3f); + } + } + static const mem_t *nthcode(const mem_t *p, const unsigned n) + { + const mem_t *p1 = p; + int i = n; + while (i-- > 0) + p1 += codelen(p1); + return p1; + } +}; - static str_t *salloc(int n); - static void sfree(str_t *s); +struct pstring : public pstring_t<putf8_traits> +{ +public: + + typedef pstring_t<putf8_traits> type_t; + + // simple construction/destruction + pstring() : type_t() { } + + // construction with copy + pstring(const mem_t *string) : type_t(string) { } + pstring(const type_t &string) : type_t(string) { } + + const type_t vprintf(va_list args) const; + int scanf(const type_t &format, ...) const; + + static const type_t sprintf(const char *format, ...) ATTR_PRINTF(1,2); - static str_t m_zero; }; // ---------------------------------------------------------------------------------------- @@ -199,6 +324,7 @@ private: struct pstringbuffer { public: + static const int DEFAULT_SIZE = 2048; // simple construction/destruction pstringbuffer() @@ -216,28 +342,23 @@ public: // assignment operators pstringbuffer &operator=(const char *string) { pcopy(string); return *this; } pstringbuffer &operator=(const pstring &string) { pcopy(string); return *this; } - pstringbuffer &operator=(const pstringbuffer &string) { pcopy(string.cstr()); return *this; } + pstringbuffer &operator=(const pstringbuffer &string) { pcopy(string); return *this; } - // C string conversion operators and helpers - operator const char *() const { return m_ptr; } + // C string conversion helpers const char *cstr() const { return m_ptr; } operator pstring() const { return pstring(m_ptr); } // concatenation operators - pstringbuffer& operator+=(const char c) { char buf[2] = { c, 0 }; pcat(buf); return *this; } - pstringbuffer& operator+=(const pstring &string) { pcat(string.cstr()); return *this; } + pstringbuffer& operator+=(const UINT8 c) { char buf[2] = { c, 0 }; pcat(buf); return *this; } + pstringbuffer& operator+=(const pstring &string) { pcat(string); return *this; } + pstringbuffer& operator+=(const char *string) { pcat(string); return *this; } std::size_t len() const { return m_len; } void cat(const pstring &s) { pcat(s); } void cat(const char *s) { pcat(s); } - pstring substr(unsigned int start, int count = -1) - { - return pstring(m_ptr).substr(start, count); - } - private: void init() diff --git a/src/emu/netlist/tools/nl_convert.c b/src/emu/netlist/tools/nl_convert.c index 40c7257edcc..265e20c1c93 100644 --- a/src/emu/netlist/tools/nl_convert.c +++ b/src/emu/netlist/tools/nl_convert.c @@ -235,7 +235,7 @@ void nl_convert_spice_t::process_line(const pstring &line) { pstring_list_t tt(line, " ", true); double val = 0.0; - switch (tt[0].cstr()[0]) + switch (tt[0].code_at(0)) { case ';': out("// %s\n", line.substr(1).cstr()); @@ -280,9 +280,9 @@ void nl_convert_spice_t::process_line(const pstring &line) pins = m[1].left(3); } add_device("QBJT_EB", tt[0], m[0]); - add_term(tt[1], tt[0] + "." + pins[0]); - add_term(tt[2], tt[0] + "." + pins[1]); - add_term(tt[3], tt[0] + "." + pins[2]); + add_term(tt[1], tt[0] + "." + pins.code_at(0)); + add_term(tt[2], tt[0] + "." + pins.code_at(1)); + add_term(tt[3], tt[0] + "." + pins.code_at(2)); } break; case 'R': @@ -397,7 +397,7 @@ void nl_convert_eagle_t::convert(const pstring &contents) tok.require_token(tok.m_tok_SEMICOLON); token = tok.get_token(); } - switch (name.cstr()[0]) + switch (name.code_at(0)) { case 'Q': { diff --git a/src/tools/nltool.c b/src/tools/nltool.c index a13d7dd183c..0d34eb9d1ae 100644 --- a/src/tools/nltool.c +++ b/src/tools/nltool.c @@ -155,7 +155,7 @@ pstring filetobuf(pstring fname) else { FILE *f; - f = fopen(fname, "rb"); + f = fopen(fname.cstr(), "rb"); fseek(f, 0, SEEK_END); long fsize = ftell(f); fseek(f, 0, SEEK_SET); @@ -267,11 +267,8 @@ void usage(tool_options_t &opts) struct input_t { - netlist::netlist_time m_time; - netlist::param_t *m_param; - double m_value; - input_t() + : m_param(NULL), m_value(0.0) { } input_t(netlist::netlist_t *netlist, const pstring &line) @@ -303,6 +300,11 @@ struct input_t break; } } + + netlist::netlist_time m_time; + netlist::param_t *m_param; + double m_value; + }; plist_t<input_t> *read_input(netlist::netlist_t *netlist, pstring fname) @@ -311,14 +313,15 @@ plist_t<input_t> *read_input(netlist::netlist_t *netlist, pstring fname) if (fname != "") { pifilestream f(fname); - do { - pstring l = f.readline(); + pstring l; + while (f.readline(l)) + { if (l != "") { input_t inp(netlist, l); ret->add(inp); } - } while (!f.eof()); + } } return ret; } diff --git a/src/tools/nlwav.c b/src/tools/nlwav.c index 862888b2eed..9d9ad911afe 100644 --- a/src/tools/nlwav.c +++ b/src/tools/nlwav.c @@ -160,13 +160,12 @@ void convert(nlwav_options_t &opts) double minsam = 1e9; int n = 0; //short sample = 0; + pstring line; - - while(!fin.eof()) + while(fin.readline(line)) { #if 1 float t = 0.0; float v = 0.0; - pstring line = fin.readline(); line.scanf("%f %f", &t, &v); while (t >= ct) { |