diff options
Diffstat (limited to 'src/emu/netlist/plib/pstring.c')
-rw-r--r-- | src/emu/netlist/plib/pstring.c | 380 |
1 files changed, 283 insertions, 97 deletions
diff --git a/src/emu/netlist/plib/pstring.c b/src/emu/netlist/plib/pstring.c index e5f73ffa17b..f2583787f3e 100644 --- a/src/emu/netlist/plib/pstring.c +++ b/src/emu/netlist/plib/pstring.c @@ -5,22 +5,21 @@ * */ -#include <cstdio> #include <cstring> //FIXME:: pstring should be locale free #include <cctype> #include <cstdlib> +#include <cstdio> #include <algorithm> #include "pstring.h" #include "palloc.h" -// The following will work on linux, however not on Windows .... - -//pblockpool *pstring::m_pool = new pblockpool; -//pstring::str_t *pstring::m_zero = new(pstring::m_pool, 0) pstring::str_t(0); +template<> +pstr_t pstring_t<putf8_traits>::m_zero = pstr_t(0); +template<> +pstr_t pstring_t<pu8_traits>::m_zero = pstr_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,124 @@ 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++; } } + ret = ret.cat(cstr() + 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 +240,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 +250,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 +283,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 +292,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 +301,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 +316,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,41 +336,107 @@ void pstring::resetmem() // pstring ... // ---------------------------------------------------------------------------------------- -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 type_t(tempbuf); +} + + +const pstring::type_t pstring::sprintf(const char *format, ...) { va_list ap; va_start(ap, format); - pstring ret = pstring(format).vprintf(ap); + type_t ret = pstring(format).vprintf(ap); va_end(ap); return ret; } +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; +} -int pstring::find(const char *search, int start) const +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); } // ---------------------------------------------------------------------------------------- @@ -314,6 +457,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) @@ -321,7 +465,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; } @@ -331,30 +475,72 @@ 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; +} + +pformat::pformat(const pstring &fmt) +: m_arg(0) +{ + memcpy(m_str, fmt.cstr(), fmt.blen() + 1); +} + +pformat::pformat(const char *fmt) +: m_arg(0) +{ + strncpy(m_str, fmt, sizeof(m_str) - 1); + m_str[sizeof(m_str) - 1] = 0; } + +void pformat::format_element(const char *f, const char *l, const char *fmt_spec, ...) +{ + va_list ap; + va_start(ap, fmt_spec); + char fmt[30] = "%"; + char search[10] = ""; + char buf[1024]; + strcat(fmt, f); + strcat(fmt, l); + strcat(fmt, fmt_spec); + int nl = vsprintf(buf, fmt, ap); + m_arg++; + int sl = sprintf(search, "%%%d", m_arg); + char *p = strstr(m_str, search); + if (p != NULL) + { + // Make room + memmove(p+nl, p+sl, strlen(p) + 1 - sl); + memcpy(p, buf, nl); + } + va_end(ap); +} + + +template struct pstring_t<pu8_traits>; +template struct pstring_t<putf8_traits>; + |