From e72ac348f1633f955444519e9eaf500659ff02cc Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 21 Apr 2014 15:22:49 +0000 Subject: [PATCH] Core: Split/Join/Merge refactored git-svn-id: svn://ultimatepp.org/upp/trunk@7285 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/AString.hpp | 18 +- uppsrc/Core/Core.h | 2 + uppsrc/Core/Core.upp | 2 + uppsrc/Core/SplitMerge.cpp | 313 +++++++++++++++++++++++ uppsrc/Core/SplitMerge.h | 80 ++++++ uppsrc/Core/StrUtil.cpp | 2 +- uppsrc/Core/String.cpp | 25 +- uppsrc/Core/String.h | 43 ++-- uppsrc/Core/Util.cpp | 114 --------- uppsrc/Core/Util.h | 42 --- uppsrc/Core/WString.cpp | 14 +- uppsrc/Core/src.tpp/SplitMerge$en-us.tpp | 163 ++++++++++++ uppsrc/ide/Builders/CppBuilder.cpp | 2 +- uppsrc/ide/Builders/init | 10 +- uppsrc/ide/Core/Core.h | 4 - uppsrc/ide/Core/Workspace.cpp | 11 +- uppsrc/ide/Debuggers/init | 2 +- 17 files changed, 634 insertions(+), 213 deletions(-) create mode 100644 uppsrc/Core/SplitMerge.cpp create mode 100644 uppsrc/Core/SplitMerge.h create mode 100644 uppsrc/Core/src.tpp/SplitMerge$en-us.tpp diff --git a/uppsrc/Core/AString.hpp b/uppsrc/Core/AString.hpp index dc34924ec..f1f096a5c 100644 --- a/uppsrc/Core/AString.hpp +++ b/uppsrc/Core/AString.hpp @@ -107,7 +107,7 @@ void AString::Replace(const tchar *find, int findlen, const tchar *replace, i } r.Cat(p + i, B::GetCount() - i); B::Free(); - B::Set(r); + B::Set0(r); } template @@ -276,6 +276,20 @@ inline int String0::Compare(const String0& s) const return LCompare(s); } +force_inline +void String0::Set(const char *s, int len) +{ + Clear(); + if(len < 14) { + SVO_MEMCPY(chr, s, len); + SLen() = len; + Dsyn(); + return; + } + SetL(s, len); + Dsyn(); +} + force_inline String& String::operator=(const char *s) { @@ -286,7 +300,7 @@ String& String::operator=(const char *s) force_inline String::String(const char *s) { - String0::Set(s, strlen__(s)); + String0::Set0(s, strlen__(s)); } force_inline diff --git a/uppsrc/Core/Core.h b/uppsrc/Core/Core.h index 1ce8f1178..26ff3bb8d 100644 --- a/uppsrc/Core/Core.h +++ b/uppsrc/Core/Core.h @@ -289,6 +289,8 @@ class JsonIO; #include "FixedMap.h" #include "InVector.h" +#include "SplitMerge.h" + #include "Value.h" #include "ValueUtil.h" diff --git a/uppsrc/Core/Core.upp b/uppsrc/Core/Core.upp index 073f1aa64..0a75f7401 100644 --- a/uppsrc/Core/Core.upp +++ b/uppsrc/Core/Core.upp @@ -50,6 +50,8 @@ file String.cpp optimize_speed, WString.cpp optimize_speed, StrUtil.cpp optimize_speed, + SplitMerge.h, + SplitMerge.cpp optimize_speed, CharSet.i, CharSet.h, CharSet.cpp optimize_speed, diff --git a/uppsrc/Core/SplitMerge.cpp b/uppsrc/Core/SplitMerge.cpp new file mode 100644 index 000000000..6ed2e1c0d --- /dev/null +++ b/uppsrc/Core/SplitMerge.cpp @@ -0,0 +1,313 @@ +#include "Core.h" + +NAMESPACE_UPP + +template +Vector SplitGeneric(int maxcount, const F& delim, const Char *s, bool ignoreempty = true) +{ + Vector r; + r.Reserve(min(maxcount, 8)); + const Char *t = s; + while(*t && r.GetCount() < maxcount) { + const Char *q = delim(t); + if(q) { + if(!ignoreempty || t > s) + r.Add().Set(s, t - s); // This is faster than r.Add(String(s, t))... + t = s = q; + } + else + t++; + } + if((!ignoreempty || t > s) && r.GetCount() < maxcount) + r.Add().Set(s, t - s); + return r; +} + +Vector Split(int maxcount, const char *s, const char * (*text_filter)(const char *), bool ignoreempty) +{ + return SplitGeneric(maxcount, text_filter, s, ignoreempty); +} + +Vector Split(int maxcount, const char *s, int (*filter)(int), bool ignoreempty) +{ + struct { + int (*filter)(int); + const char *operator()(const char *s) const { return (*filter)((byte)*s) ? s + 1 : NULL; } + } delim; + delim.filter = filter; + return SplitGeneric(maxcount, delim, s, ignoreempty); +} + +Vector Split(int maxcount, const char *s, int chr, bool ignoreempty) +{ + struct { + int chr; + const char *operator()(const char *s) const { return *s == chr ? s + 1 : NULL; } + } delim; + delim.chr = chr; + return SplitGeneric(maxcount, delim, s, ignoreempty); +} + +Vector Split(int maxcount, const char *s, const char *text, bool ignoreempty) +{ + struct { + const char *ds; + int l; + const char *operator()(const char *s) const { return strncmp(s, ds, l) == 0 ? s + l : NULL; } + } delim; + delim.ds = text; + delim.l = strlen(text); + return delim.l ? SplitGeneric(maxcount, delim, s, ignoreempty) : Vector(); +} + +Vector Split(const char *s, const char * (*text_filter)(const char *), bool ignoreempty) +{ + return Split(INT_MAX, s, text_filter, ignoreempty); +} + +Vector Split(const char *s, int (*filter)(int), bool ignoreempty) +{ + return Split(INT_MAX, s, filter, ignoreempty); +} + +Vector Split(const char *s, int chr, bool ignoreempty) +{ + return Split(INT_MAX, s, chr, ignoreempty); +} + +Vector Split(const char *s, const char *text, bool ignoreempty) +{ + return Split(INT_MAX, s, text, ignoreempty); +} + +Vector Split(int maxcount, const wchar *s, const wchar * (*text_filter)(const wchar *), bool ignoreempty) +{ + return SplitGeneric(maxcount, text_filter, s, ignoreempty); +} + +Vector Split(int maxcount, const wchar *s, int (*filter)(int), bool ignoreempty) +{ + struct { + int (*filter)(int); + const wchar *operator()(const wchar *s) const { return (*filter)((byte)*s) ? s + 1 : NULL; } + } delim; + delim.filter = filter; + return SplitGeneric(maxcount, delim, s, ignoreempty); +} + +Vector Split(int maxcount, const wchar *s, int chr, bool ignoreempty) +{ + struct { + int chr; + const wchar *operator()(const wchar *s) const { return *s == chr ? s + 1 : NULL; } + } delim; + delim.chr = chr; + return SplitGeneric(maxcount, delim, s, ignoreempty); +} + +int w_strncmp(const wchar *s, const wchar *t, int n) +{ + while(*s && *t && n > 0) { + int q = (int)(uint16)*s - (int)(uint16)*t; + if(q) + return q; + s++; + t++; + n--; + } + return 0; +} + +Vector Split(int maxcount, const wchar *s, const wchar *text, bool ignoreempty) +{ + struct { + const wchar *ds; + int l; + const wchar *operator()(const wchar *s) const { return w_strncmp(s, ds, l) == 0 ? s + l : NULL; } + } delim; + delim.ds = text; + delim.l = wstrlen(text); + return delim.l ? SplitGeneric(maxcount, delim, s, ignoreempty) : Vector(); +} + +Vector Split(const wchar *s, int (*filter)(int), bool ignoreempty) +{ + return Split(INT_MAX, s, filter, ignoreempty); +} + +Vector Split(const wchar *s, int chr, bool ignoreempty) +{ + return Split(INT_MAX, s, chr, ignoreempty); +} + +Vector Split(const wchar *s, const wchar *text, bool ignoreempty) +{ + return Split(INT_MAX, s, text, ignoreempty); +} + +Vector Split(const wchar *s, const wchar * (*text_filter)(const wchar *), bool ignoreempty) +{ + return SplitGeneric(INT_MAX, text_filter, s, ignoreempty); +} + +String Join(const Vector& im, const String& delim, bool ignoreempty) { + StringBuffer r; + for(int i = 0; i < im.GetCount(); i++) + if(!ignoreempty || im[i].GetCount()) { + if(r.GetCount()) + r.Cat(delim); + r.Cat(im[i]); + } + return r; +} + +WString Join(const Vector& im, const WString& delim, bool ignoreempty) { + WStringBuffer r; + for(int i = 0; i < im.GetCount(); i++) + if(!ignoreempty || im[i].GetCount()) { + if(r.GetCount()) + r.Cat(delim); + r.Cat(im[i]); + } + return r; +} + +static void sMergeWith(String& dest, const char *delim, const String& s) +{ + if(s.GetLength()) { + if(dest.GetCount()) + dest.Cat(delim); + dest.Cat(s); + } +} + +#define E__TL(I) typename COMBINE(T, I) +#define E__NFIf(I) COMBINE(p, I) = r[I - 1] +#define E__NFValue(I) String& COMBINE(p, I) +#define E__PI(I) COMBINE(p, I) +#define E__NFSValue(I) const String& COMBINE(p, I) +#define E__Merge(I) sMergeWith(dest, delim, COMBINE(p, I)) + +#define E__NFBody(I) \ +bool SplitTo(const char *s, int chr, bool ignoreempty, __List##I(E__NFValue)) \ +{ \ + Vector r = Split(I, s, chr, ignoreempty); \ + if(r.GetCount() < I) return false; \ + __List##I(E__NFIf); \ + return true; \ +} \ +bool SplitTo(const char *s, int chr, __List##I(E__NFValue)) \ +{ \ + return SplitTo(s, chr, true, __List##I(E__PI)); \ +} \ +bool SplitTo(const char *s, int (*filter)(int), bool ignoreempty, __List##I(E__NFValue)) \ +{ \ + Vector r = Split(I, s, filter, ignoreempty); \ + if(r.GetCount() < I) return false; \ + __List##I(E__NFIf); \ + return true; \ +} \ +bool SplitTo(const char *s, int (*filter)(int), __List##I(E__NFValue)) \ +{ \ + return SplitTo(s, filter, true, __List##I(E__PI)); \ +} \ +bool SplitTo(const char *s, const char *text, bool ignoreempty, __List##I(E__NFValue)) \ +{ \ + Vector r = Split(I, s, text, ignoreempty); \ + if(r.GetCount() < I) return false; \ + __List##I(E__NFIf); \ + return true; \ +} \ +bool SplitTo(const char *s, const char *text, __List##I(E__NFValue)) \ +{ \ + return SplitTo(s, text, true, __List##I(E__PI)); \ +} \ +String Merge(const char *delim, __List##I(E__NFSValue)) \ +{ \ + String dest; \ + __List##I(E__Merge); \ + return dest; \ +} \ +void MergeWith(String& dest, const char *delim, __List##I(E__NFSValue)) \ +{ \ + __List##I(E__Merge); \ +} \ + +__Expand8(E__NFBody) + +#undef E__TL +#undef E__NFIf +#undef E__NFValue +#undef E__PI +#undef E__NFBody + +static void sMergeWith(WString& dest, const wchar *delim, const WString& s) +{ + if(s.GetLength()) { + if(dest.GetCount()) + dest.Cat(delim); + dest.Cat(s); + } +} + +#define E__TL(I) typename COMBINE(T, I) +#define E__NFIf(I) COMBINE(p, I) = r[I - 1] +#define E__NFValue(I) WString& COMBINE(p, I) +#define E__PI(I) COMBINE(p, I) +#define E__NFSValue(I) const WString& COMBINE(p, I) +#define E__Merge(I) sMergeWith(dest, delim, COMBINE(p, I)) + +#define E__NFBody(I) \ +bool SplitTo(const wchar *s, int chr, bool ignoreempty, __List##I(E__NFValue)) \ +{ \ + Vector r = Split(I, s, chr, ignoreempty); \ + if(r.GetCount() < I) return false; \ + __List##I(E__NFIf); \ + return true; \ +} \ +bool SplitTo(const wchar *s, int chr, __List##I(E__NFValue)) \ +{ \ + return SplitTo(s, chr, true, __List##I(E__PI)); \ +} \ +bool SplitTo(const wchar *s, int (*filter)(int), bool ignoreempty, __List##I(E__NFValue)) \ +{ \ + Vector r = Split(I, s, filter, ignoreempty); \ + if(r.GetCount() < I) return false; \ + __List##I(E__NFIf); \ + return true; \ +} \ +bool SplitTo(const wchar *s, int (*filter)(int), __List##I(E__NFValue)) \ +{ \ + return SplitTo(s, filter, true, __List##I(E__PI)); \ +} \ +bool SplitTo(const wchar *s, const wchar *text, bool ignoreempty, __List##I(E__NFValue)) \ +{ \ + Vector r = Split(I, s, text, ignoreempty); \ + if(r.GetCount() < I) return false; \ + __List##I(E__NFIf); \ + return true; \ +} \ +bool SplitTo(const wchar *s, const wchar *text, __List##I(E__NFValue)) \ +{ \ + return SplitTo(s, text, true, __List##I(E__PI)); \ +} \ +WString Merge(const wchar *delim, __List##I(E__NFSValue)) \ +{ \ + WString dest; \ + __List##I(E__Merge); \ + return dest; \ +} \ +void MergeWith(WString& dest, const wchar *delim, __List##I(E__NFSValue)) \ +{ \ + __List##I(E__Merge); \ +} \ + +__Expand8(E__NFBody) + +#undef E__TL +#undef E__NFIf +#undef E__NFValue +#undef E__PI +#undef E__NFBody + +END_UPP_NAMESPACE diff --git a/uppsrc/Core/SplitMerge.h b/uppsrc/Core/SplitMerge.h new file mode 100644 index 000000000..a68f0639f --- /dev/null +++ b/uppsrc/Core/SplitMerge.h @@ -0,0 +1,80 @@ +Vector Split(int maxcount, const char *s, const char * (*text_filter)(const char *), bool ignoreempty = true); +Vector Split(int maxcount, const char *s, int (*filter)(int), bool ignoreempty = true); +Vector Split(int maxcount, const char *s, int chr, bool ignoreempty = true); +Vector Split(int maxcount, const char *s, const char *text, bool ignoreempty = true); +Vector Split(const char *s, const char * (*text_filter)(const char *), bool ignoreempty = true); +Vector Split(const char *s, int (*filter)(int), bool ignoreempty = true); +Vector Split(const char *s, int chr, bool ignoreempty = true); +Vector Split(const char *s, const char *text, bool ignoreempty = true); + +Vector Split(int maxcount, const wchar *s, const wchar * (*text_filter)(const wchar *), bool ignoreempty = true); +Vector Split(int maxcount, const wchar *s, int (*filter)(int), bool ignoreempty = true); +Vector Split(int maxcount, const wchar *s, int chr, bool ignoreempty = true); +Vector Split(int maxcount, const wchar *s, const wchar *text, bool ignoreempty = true); +Vector Split(const wchar *s, const wchar * (*text_filter)(const wchar *), bool ignoreempty = true); +Vector Split(const wchar *s, int (*filter)(int), bool ignoreempty = true); +Vector Split(const wchar *s, int chr, bool ignoreempty = true); +Vector Split(const wchar *s, const wchar *text, bool ignoreempty = true); + +String Join(const Vector& im, const String& delim, bool ignoreempty = false); +WString Join(const Vector& im, const WString& delim, bool ignoreempty = false); + +//$- +#define E__NFValue(I) String& COMBINE(p, I) +#define E__NFSValue(I) const String& COMBINE(p, I) + +#define E__NFBody(I) \ +bool SplitTo(const char *s, int delim, bool ignoreempty, __List##I(E__NFValue)); \ +bool SplitTo(const char *s, int delim, __List##I(E__NFValue)); \ +bool SplitTo(const char *s, int (*filter)(int), bool ignoreempty, __List##I(E__NFValue)); \ +bool SplitTo(const char *s, int (*filter)(int), __List##I(E__NFValue)); \ +bool SplitTo(const char *s, const char *delim, bool ignoreempty, __List##I(E__NFValue)); \ +bool SplitTo(const char *s, const char *delim, __List##I(E__NFValue)); \ +String Merge(const char *delim, __List##I(E__NFSValue)); \ +void MergeWith(String& dest, const char *delim, __List##I(E__NFSValue)); \ + +__Expand8(E__NFBody) + +#undef E__NFBody +#undef E__NFValue +#undef E__NFSValue + +#define E__NFValue(I) WString& COMBINE(p, I) +#define E__NFSValue(I) const WString& COMBINE(p, I) + +#define E__NFBody(I) \ +bool SplitTo(const wchar *s, int delim, bool ignoreempty, __List##I(E__NFValue)); \ +bool SplitTo(const wchar *s, int delim, __List##I(E__NFValue)); \ +bool SplitTo(const wchar *s, int (*filter)(int), bool ignoreempty, __List##I(E__NFValue)); \ +bool SplitTo(const wchar *s, int (*filter)(int), __List##I(E__NFValue)); \ +bool SplitTo(const wchar *s, const char *delim, bool ignoreempty, __List##I(E__NFValue)); \ +bool SplitTo(const wchar *s, const char *delim, __List##I(E__NFValue)); \ +WString Merge(const wchar *delim, __List##I(E__NFSValue)); \ +void MergeWith(WString& dest, const wchar *delim, __List##I(E__NFSValue)); \ + +__Expand8(E__NFBody) + +#undef E__NFBody +#undef E__NFValue +#undef E__NFSValue +//$+ + +//$ bool SplitTo(const char *s, int delim, bool ignoreempty, String& p1...); +//$ bool SplitTo(const char *s, int delim, String& p1...); +//$ bool SplitTo(const char *s, int (*filter)(int), String& p1...); +//$ bool SplitTo(const char *s, int (*filter)(int), String& p1...); +//$ bool SplitTo(const char *s, const char *delim, bool ignoreempty, String& p1...); +//$ bool SplitTo(const char *s, const char *delim, String& p1...); + +//$ bool SplitTo(const wchar *s, int delim, bool ignoreempty, WString& p1...); +//$ bool SplitTo(const wchar *s, int delim, WString& p1...); +//$ bool SplitTo(const wchar *s, int (*filter)(int), WString& p1...); +//$ bool SplitTo(const wchar *s, int (*filter)(int), WString& p1...); +//$ bool SplitTo(const wchar *s, const wchar *delim, bool ignoreempty, WString& p1...); +//$ bool SplitTo(const wchar *s, const wchar *delim, WString& p1...); + +//$ String Merge(const char *delim, String& p1...); +//$ WString Merge(const wchar *delim, WString& p1...); + +//$ void MergeWith(String& dest, const char *delim, String& p1...); +//$ void MergeWith(WString& dest, const wchar *delim, WString& p1...); diff --git a/uppsrc/Core/StrUtil.cpp b/uppsrc/Core/StrUtil.cpp index 206182578..2367929d0 100644 --- a/uppsrc/Core/StrUtil.cpp +++ b/uppsrc/Core/StrUtil.cpp @@ -1,4 +1,4 @@ -#include +#include "Core.h" NAMESPACE_UPP diff --git a/uppsrc/Core/String.cpp b/uppsrc/Core/String.cpp index 7542a711d..1705332a6 100644 --- a/uppsrc/Core/String.cpp +++ b/uppsrc/Core/String.cpp @@ -255,9 +255,19 @@ void String0::Reserve(int r) Trim(l); } -void String0::Set(const char *s, int len) +void String0::SetL(const char *s, int len) { - w[0] = w[1] = w[2] = w[3] = 0; + char *p = Alloc(len, chr[KIND]); + memcpy(p, s, len); + p[len] = 0; + ptr = p; + LLen() = len; + SLen() = 15; +} + +void String0::Set0(const char *s, int len) +{ + Zero(); switch(len) { #define MOV(x) case x: chr[x - 1] = s[x - 1]; MOV(14) MOV(13) MOV(12) MOV(11) MOV(10) MOV(9) MOV(8) @@ -266,12 +276,7 @@ void String0::Set(const char *s, int len) SLen() = len; break; default: - char *p = Alloc(len, chr[KIND]); - memcpy(p, s, len); - p[len] = 0; - ptr = p; - LLen() = len; - SLen() = 15; + SetL(s, len); }; Dsyn(); } @@ -284,7 +289,7 @@ void String::AssignLen(const char *s, int slen) *this = String(s, slen); else { String0::Free(); - String0::Set(s, slen); + String0::Set0(s, slen); } } @@ -316,7 +321,7 @@ int String::GetCharCount() const String::String(StringBuffer& b) { if(b.begin == b.buffer) { - String0::Set(b.begin, (int)(uintptr_t)(b.end - b.begin)); + String0::Set0(b.begin, (int)(uintptr_t)(b.end - b.begin)); return; } int l = b.GetLength(); diff --git a/uppsrc/Core/String.h b/uppsrc/Core/String.h index 6c3b296ce..42b4918b6 100644 --- a/uppsrc/Core/String.h +++ b/uppsrc/Core/String.h @@ -235,7 +235,7 @@ protected: void Zero() { q[0] = q[1] = 0; Dsyn(); } void Free() { if(IsLarge()) LFree(); } void SetSmall(const String0& s) { q[0] = s.q[0]; q[1] = s.q[1]; } - void Set(const String0& s) { + void Set0(const String0& s) { if(s.IsSmall()) SetSmall(s); else LSet(s); Dsyn(); } @@ -251,7 +251,8 @@ protected: } Dsyn(); } - void Set(const char *s, int len); + void Set0(const char *s, int len); + void SetL(const char *s, int len); char *Insert(int pos, int count, const char *str); public: // should be protected, bug in gcc 3.4 @@ -286,6 +287,7 @@ public: } void Cat(const char *s, int len); + void Set(const char *s, int len); void Set(int i, int chr); void Trim(int pos); @@ -307,7 +309,7 @@ public: void Reserve(int r); - String0& operator=(const String0& s) { Free(); Set(s); return *this; } + String0& operator=(const String0& s) { Free(); Set0(s); return *this; } String0() {} ~String0() { Free(); } @@ -345,19 +347,19 @@ public: String& operator=(const char *s); String& operator=(const String& s) { String0::Assign(s); return *this; } String& operator=(StringBuffer& b) { *this = String(b); return *this; } - String& operator<<=(const String& s) { if(this != &s) { String0::Free(); String0::Set(s, s.GetCount()); } return *this; } + String& operator<<=(const String& s) { if(this != &s) { String0::Free(); String0::Set0(s, s.GetCount()); } return *this; } void Shrink() { *this = String(Begin(), GetLength()); } int GetCharCount() const; String() { Zero(); } String(const Nuller&) { Zero(); } - String(const String& s) { String0::Set(s); } + String(const String& s) { String0::Set0(s); } String(const char *s); - String(const String& s, int n) { ASSERT(n >= 0 && n <= s.GetLength()); String0::Set(~s, n); } - String(const char *s, int n) { String0::Set(s, n); } - String(const byte *s, int n) { String0::Set((const char *)s, n); } - String(const char *s, const char *lim) { String0::Set(s, (int)(lim - s)); } + String(const String& s, int n) { ASSERT(n >= 0 && n <= s.GetLength()); String0::Set0(~s, n); } + String(const char *s, int n) { String0::Set0(s, n); } + String(const byte *s, int n) { String0::Set0((const char *)s, n); } + String(const char *s, const char *lim) { String0::Set0(s, (int)(lim - s)); } String(int chr, int count) { String0::Zero(); Cat(chr, count); } String(StringBuffer& b); @@ -369,7 +371,7 @@ public: friend void Swap(String& a, String& b) { a.Swap(b); } - String(const std::string& s) { String0::Set(s.c_str(), (int)s.length()); } + String(const std::string& s) { String0::Set0(s.c_str(), (int)s.length()); } operator std::string() const { return std::string(Begin(), End()); } }; @@ -643,8 +645,8 @@ public: // should be protected, bug in GCC 3.4 protected: void Zero() { static wchar e[2]; length = alloc = 0; ptr = e; Dsyn(); ASSERT(*ptr == 0); } - void Set(const wchar *s, int length); - void Set(const WString0& s); + void Set0(const wchar *s, int length); + void Set0(const WString0& s); void Free(); void Swap(WString0& b) { Upp::Swap(ptr, b.ptr); Upp::Swap(length, b.length); Upp::Swap(alloc, b.alloc); Dsyn(); b.Dsyn(); } wchar *Insert(int pos, int count, const wchar *data); @@ -659,6 +661,7 @@ public: void Cat(int c) { if(!IsRc() && length < alloc) { ptr[length++] = c; ptr[length] = 0; } else LCat(c); Dsyn(); } void Cat(const wchar *s, int length); + void Set(const wchar *s, int length); int GetCount() const { return length; } int GetLength() const { return length; } @@ -678,7 +681,7 @@ public: WString0() { Zero(); } ~WString0() { Free(); } - WString0& operator=(const WString0& s) { Free(); Set(s); return *this; } + WString0& operator=(const WString0& s) { Free(); Set0(s); return *this; } }; class WString : public Moveable > @@ -703,19 +706,19 @@ public: WString& operator<<(const wchar *s) { Cat(s); return *this; } WString& operator=(const wchar *s); - WString& operator=(const WString& s) { if(this != &s) { WString0::Free(); WString0::Set(s); } return *this; } + WString& operator=(const WString& s) { if(this != &s) { WString0::Free(); WString0::Set0(s); } return *this; } WString& operator=(WStringBuffer& b) { *this = WString(b); return *this; } - WString& operator<<=(const WString& s) { if(this != &s) { WString0::Free(); WString0::Set(s, s.GetCount()); } return *this; } + WString& operator<<=(const WString& s) { if(this != &s) { WString0::Free(); WString0::Set0(s, s.GetCount()); } return *this; } void Shrink() { *this = WString(Begin(), GetLength()); } WString() {} WString(const Nuller&) {} - WString(const WString& s) { WString0::Set(s); } - WString(const wchar *s) { WString0::Set(s, strlen__(s)); } - WString(const WString& s, int n) { ASSERT(n >= 0 && n <= s.GetLength()); WString0::Set(~s, n); } - WString(const wchar *s, int n) { WString0::Set(s, n); } - WString(const wchar *s, const wchar *lim) { WString0::Set(s, (int)(lim - s)); } + WString(const WString& s) { WString0::Set0(s); } + WString(const wchar *s) { WString0::Set0(s, strlen__(s)); } + WString(const WString& s, int n) { ASSERT(n >= 0 && n <= s.GetLength()); WString0::Set0(~s, n); } + WString(const wchar *s, int n) { WString0::Set0(s, n); } + WString(const wchar *s, const wchar *lim) { WString0::Set0(s, (int)(lim - s)); } WString(int chr, int count) { WString0::Zero(); Cat(chr, count); } WString(WStringBuffer& b); diff --git a/uppsrc/Core/Util.cpp b/uppsrc/Core/Util.cpp index ef86683ba..889a91402 100644 --- a/uppsrc/Core/Util.cpp +++ b/uppsrc/Core/Util.cpp @@ -322,120 +322,6 @@ void StringC::SetCharPtr(const char *s) { bap.Set0((void *)s); } -CharFilterTextTest::CharFilterTextTest(int (*filter)(int)) : filter(filter) {} -CharFilterTextTest::~CharFilterTextTest() {} - -const char *CharFilterTextTest::Accept(const char *s) const { - if(!(*filter)((byte)*s++)) return NULL; - return s; -} - -Vector Split(const char *s, const TextTest& delim, bool ignoreempty) { - Vector r; - const char *t = s; - while(*t) { - const char *q = delim.Accept(t); - if(q) { - if(!ignoreempty || t > s) - r.Add(String(s, t)); - t = s = q; - } - else - t++; - } - if(!ignoreempty || t > s) - r.Add(String(s, t)); - return r; -} - -Vector Split(const char *s, int (*filter)(int), bool ignoreempty) { - return Split(s, CharFilterTextTest(filter), ignoreempty); -} - -struct chrTextTest : public TextTest { - int chr; - virtual const char *Accept(const char *s) const { return chr == *s ? s + 1 : NULL; } -}; - -Vector Split(const char *s, int chr, bool ignoreempty) { - chrTextTest ct; - ct.chr = chr; - return Split(s, ct, ignoreempty); -} - -struct StringSplit : TextTest { - String test; - - virtual const char *Accept(const char *s) const { - int l = test.GetCount(); - if(l && memcmp(~test, s, l) == 0) - return s + l; - return NULL; - } -}; - -Vector Split(const char *s, const String& delim, bool ignoreempty) -{ - StringSplit ss; - ss.test = delim; - return Split(s, ss, ignoreempty); -} - -#define E__TL(I) typename COMBINE(T, I) -#define E__NFIf(I) COMBINE(p, I) = r[I - 1] -#define E__NFValue(I) String& COMBINE(p, I) -#define E__PI(I) COMBINE(p, I) - -#define E__NFBody(I) \ -bool SplitTo(const char *s, int delim, bool ignoreempty, __List##I(E__NFValue)) \ -{ \ - Vector r = Split(s, delim, ignoreempty); \ - if(r.GetCount() < I) return false; \ - __List##I(E__NFIf); \ - return true; \ -} \ -bool SplitTo(const char *s, int delim, __List##I(E__NFValue)) \ -{ \ - return SplitTo(s, delim, true, __List##I(E__PI)); \ -} \ -bool SplitTo(const char *s, const char *delim, bool ignoreempty, __List##I(E__NFValue)) \ -{ \ - Vector r = Split(s, delim, ignoreempty); \ - if(r.GetCount() < I) return false; \ - __List##I(E__NFIf); \ - return true; \ -} \ -bool SplitTo(const char *s, const char *delim, __List##I(E__NFValue)) \ -{ \ - return SplitTo(s, delim, true, __List##I(E__PI)); \ -} \ - -__Expand8(E__NFBody) - -#undef E__TL -#undef E__NFIf -#undef E__NFValue -#undef E__PI -#undef E__NFBody - -String Join(const Vector& im, const String& delim) { - String r; - for(int i = 0; i < im.GetCount(); i++) { - if(i) r.Cat(delim); - r.Cat(im[i]); - } - return r; -} - -WString Join(const Vector& im, const WString& delim) { - WString r; - for(int i = 0; i < im.GetCount(); i++) { - if(i) r.Cat(delim); - r.Cat(im[i]); - } - return r; -} - String timeFormat(double s) { if(s < 0.000001) return Sprintf("%5.2f ns", s * 1.0e9); if(s < 0.001) return Sprintf("%5.2f us", s * 1.0e6); diff --git a/uppsrc/Core/Util.h b/uppsrc/Core/Util.h index 7c22404e0..54bf8da81 100644 --- a/uppsrc/Core/Util.h +++ b/uppsrc/Core/Util.h @@ -376,48 +376,6 @@ va_list va_ptr(const T& obj) int InScListIndex(const char *s, const char *list); bool InScList(const char *s, const char *list); -struct TextTest { - virtual const char *Accept(const char *s) const = 0; - virtual ~TextTest() {} -}; - -class CharFilterTextTest : public TextTest { - int (*filter)(int); - -public: - virtual const char *Accept(const char *s) const; - CharFilterTextTest(int (*filter)(int)); - virtual ~CharFilterTextTest(); -}; - -Vector Split(const char *s, const TextTest& delim, bool ignoreempty = true); -Vector Split(const char *s, int (*filter)(int), bool ignoreempty = true); -Vector Split(const char *s, int chr, bool ignoreempty = true); -Vector Split(const char *s, const String& delim, bool ignoreempty = true); - -//$- -#define E__NFValue(I) String& COMBINE(p, I) - -#define E__NFBody(I) \ -bool SplitTo(const char *s, int delim, bool ignoreempty, __List##I(E__NFValue)); \ -bool SplitTo(const char *s, int delim, __List##I(E__NFValue)); \ -bool SplitTo(const char *s, const char *delim, bool ignoreempty, __List##I(E__NFValue)); \ -bool SplitTo(const char *s, const char *delim, __List##I(E__NFValue)); \ - -__Expand8(E__NFBody) - -#undef E__NFBody -#undef E__NFValue -//$+ - -//$ bool SplitTo(const char *s, int delim, bool ignoreempty, String& p1...); -//$ bool SplitTo(const char *s, int delim, String& p1...); -//$ bool SplitTo(const char *s, const char *delim, bool ignoreempty, String& p1...); -//$ bool SplitTo(const char *s, const char *delim, String& p1...); - -String Join(const Vector& im, const String& delim); -WString Join(const Vector& im, const WString& delim); - class StringC { BitAndPtr bap; diff --git a/uppsrc/Core/WString.cpp b/uppsrc/Core/WString.cpp index 47b4728e1..58a459972 100644 --- a/uppsrc/Core/WString.cpp +++ b/uppsrc/Core/WString.cpp @@ -70,7 +70,7 @@ wchar *WString0::Insert(int pos, int count, const wchar *s) return ptr + pos; } -void WString0::Set(const WString0& src) +void WString0::Set0(const WString0& src) { if(src.alloc <= 0) { static wchar h[2]; @@ -115,12 +115,18 @@ void WString0::Cat(const wchar *s, int l) Dsyn(); } +void WString0::Set(const wchar *s, int length) +{ + Free(); + Set0(s, length); +} + void WString0::LCat(int c) { *Insert(length, 1, NULL) = c; } -void WString0::Set(const wchar *s, int l) +void WString0::Set0(const wchar *s, int l) { alloc = length = l; memcpy(ptr = Alloc(alloc), s, l * sizeof(wchar)); @@ -194,7 +200,7 @@ WString& WString::operator=(const wchar *s) if(s >= str && s <= str + len) return *this = WString(s, strlen__(s)); WString0::Free(); - WString0::Set(s, strlen__(s)); + WString0::Set0(s, strlen__(s)); return *this; } @@ -241,7 +247,7 @@ WString WString::GetVoid() WString::WString(const std::wstring& s) { if(sizeof(std::wstring::value_type) == sizeof(wchar)) { - WString0::Set((wchar *)s.c_str(), (int)s.length()); + WString0::Set0((wchar *)s.c_str(), (int)s.length()); } else { WString0::Zero(); diff --git a/uppsrc/Core/src.tpp/SplitMerge$en-us.tpp b/uppsrc/Core/src.tpp/SplitMerge$en-us.tpp new file mode 100644 index 000000000..e07f6cf88 --- /dev/null +++ b/uppsrc/Core/src.tpp/SplitMerge$en-us.tpp @@ -0,0 +1,163 @@ +topic ""; +[2 $$0,0#00000000000000000000000000000000:Default] +[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class] +[l288;2 $$2,2#27521748481378242620020725143825:desc] +[0 $$3,0#96390100711032703541132217272105:end] +[H6;0 $$4,0#05600065144404261032431302351956:begin] +[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:item] +[l288;a4;*@5;1 $$6,6#70004532496200323422659154056402:requirement] +[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param] +[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam] +[b42;2 $$9,9#13035079074754324216151401829390:normal] +[{_} +[ {{10000@(113.42.0) [s0;%% [*@7;4 Split, Join, Merge]]}}&] +[s0;i448;a25;kKO9;@(0.0.255) &] +[s0;%% [* Utility functions for splitting and joining Strings and WStrings.]&] +[s0;*%% &] +[ {{10000F(128)G(128)@1 [s0;%% [* Function List]]}}&] +[s3; &] +[s5;:Split`(int`,const char`*`,const char`*`(`*`)`(const char`*`)`,bool`): [_^Vector^ V +ector]<[_^String^ String]>_[* Split]([@(0.0.255) int]_[*@3 maxcount], +[@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s], [@(0.0.255) const]_[@(0.0.255) char]_`*_(`* +[*@3 text`_filter])([@(0.0.255) const]_[@(0.0.255) char]_`*), [@(0.0.255) bool]_[*@3 ignore +empty]_`=_[@(0.0.255) true])&] +[s5;:Split`(int`,const char`*`,int`(`*`)`(int`)`,bool`): [_^Vector^ Vector]<[_^String^ St +ring]>_[* Split]([@(0.0.255) int]_[*@3 maxcount], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s +], [@(0.0.255) int]_(`*[*@3 filter])([@(0.0.255) int]), [@(0.0.255) bool]_[*@3 ignoreempty]_ +`=_[@(0.0.255) true])&] +[s5;:Split`(int`,const char`*`,int`,bool`): [_^Vector^ Vector]<[_^String^ String]>_[* Split +]([@(0.0.255) int]_[*@3 maxcount], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s], +[@(0.0.255) int]_[*@3 chr], [@(0.0.255) bool]_[*@3 ignoreempty]_`=_[@(0.0.255) true])&] +[s5;:Split`(int`,const char`*`,const char`*`,bool`): [_^Vector^ Vector]<[_^String^ String +]>_[* Split]([@(0.0.255) int]_[*@3 maxcount], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s], + [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 text], [@(0.0.255) bool]_[*@3 ignoreempty]_`=_ +[@(0.0.255) true])&] +[s5;:Split`(const char`*`,const char`*`(`*`)`(const char`*`)`,bool`): [_^Vector^ Vector +]<[_^String^ String]>_[* Split]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s], +[@(0.0.255) const]_[@(0.0.255) char]_`*_(`*[*@3 text`_filter])([@(0.0.255) const]_[@(0.0.255) c +har]_`*), [@(0.0.255) bool]_[*@3 ignoreempty]_`=_[@(0.0.255) true])&] +[s5;:Split`(const char`*`,int`(`*`)`(int`)`,bool`): [_^Vector^ Vector]<[_^String^ String]> +_[* Split]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s], [@(0.0.255) int]_(`*[*@3 filter])( +[@(0.0.255) int]), [@(0.0.255) bool]_[*@3 ignoreempty]_`=_[@(0.0.255) true])&] +[s5;:Split`(const char`*`,int`,bool`): [_^Vector^ Vector]<[_^String^ String]>_[* Split]([@(0.0.255) c +onst]_[@(0.0.255) char]_`*[*@3 s], [@(0.0.255) int]_[*@3 chr], [@(0.0.255) bool]_[*@3 ignoree +mpty]_`=_[@(0.0.255) true])&] +[s5;:Split`(const char`*`,const char`*`,bool`): [_^Vector^ Vector]<[_^String^ String]>_[* S +plit]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s], [@(0.0.255) const]_[@(0.0.255) char]_ +`*[*@3 text], [@(0.0.255) bool]_[*@3 ignoreempty]_`=_[@(0.0.255) true])&] +[s5;:Split`(int`,const wchar`*`,const wchar`*`(`*`)`(const wchar`*`)`,bool`): [_^Vector^ V +ector]<[_^WString^ WString]>_[* Split]([@(0.0.255) int]_[*@3 maxcount], +[@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 s], [@(0.0.255) const]_[_^wchar^ wchar]_`*_(`*[*@3 t +ext`_filter])([@(0.0.255) const]_wchar_`*), [@(0.0.255) bool]_[*@3 ignoreempty]_`=_[@(0.0.255) t +rue])&] +[s5;:Split`(int`,const wchar`*`,int`(`*`)`(int`)`,bool`): [_^Vector^ Vector]<[_^WString^ W +String]>_[* Split]([@(0.0.255) int]_[*@3 maxcount], [@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 s +], [@(0.0.255) int]_(`*[*@3 filter])([@(0.0.255) int]), [@(0.0.255) bool]_[*@3 ignoreempty]_ +`=_[@(0.0.255) true])&] +[s5;:Split`(int`,const wchar`*`,int`,bool`): [_^Vector^ Vector]<[_^WString^ WString]>_[* Sp +lit]([@(0.0.255) int]_[*@3 maxcount], [@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 s], +[@(0.0.255) int]_[*@3 chr], [@(0.0.255) bool]_[*@3 ignoreempty]_`=_[@(0.0.255) true])&] +[s5;:Split`(int`,const wchar`*`,const wchar`*`,bool`): [_^Vector^ Vector]<[_^WString^ WSt +ring]>_[* Split]([@(0.0.255) int]_[*@3 maxcount], [@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 s +], [@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 text], [@(0.0.255) bool]_[*@3 ignoreempty]_`= +_[@(0.0.255) true])&] +[s5;:Split`(const wchar`*`,const wchar`*`(`*`)`(const wchar`*`)`,bool`): [_^Vector^ Vec +tor]<[_^WString^ WString]>_[* Split]([@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 s], +[@(0.0.255) const]_[_^wchar^ wchar]_`*_(`*[*@3 text`_filter])([@(0.0.255) const]_wchar_`* +), [@(0.0.255) bool]_[*@3 ignoreempty]_`=_[@(0.0.255) true])&] +[s5;:Split`(const wchar`*`,int`(`*`)`(int`)`,bool`): [_^Vector^ Vector]<[_^WString^ WStri +ng]>_[* Split]([@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 s], [@(0.0.255) int]_(`*[*@3 filter +])([@(0.0.255) int]), [@(0.0.255) bool]_[*@3 ignoreempty]_`=_[@(0.0.255) true])&] +[s5;:Split`(const wchar`*`,int`,bool`): [_^Vector^ Vector]<[_^WString^ WString]>_[* Split]( +[@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 s], [@(0.0.255) int]_[*@3 chr], +[@(0.0.255) bool]_[*@3 ignoreempty]_`=_[@(0.0.255) true])&] +[s5;:Split`(const wchar`*`,const wchar`*`,bool`): [_^Vector^ Vector]<[_^WString^ WString]> +_[* Split]([@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 s], [@(0.0.255) const]_[_^wchar^ wchar]_ +`*[*@3 text], [@(0.0.255) bool]_[*@3 ignoreempty]_`=_[@(0.0.255) true])&] +[s2;%% Splits text [%-*@3 s] into subtexts originating between delimiters. +Delimiter can be defined as single character [%-*@3 chr], text +filter function [%-*@3 text`_filter ](returns position after delimiter +or NULL if delimiter is not at current character), character +filter function [%-*@3 filter] (returns non`-zero for delimiter +character) or as string [%-*@3 text]. If [%-*@3 ignoreempty] is true +(default), empty subtexts are ignored. [%-*@3 maxcount] can define +upper limit of number of subtexts.&] +[s3;%% &] +[s4;%% &] +[s5;:Join`(const Vector``&`,const String`&`,bool`): [_^String^ String]_[* Join]( +[@(0.0.255) const]_[_^Vector^ Vector]<[_^String^ String]>`&_[*@3 im], +[@(0.0.255) const]_[_^String^ String][@(0.0.255) `&]_[*@3 delim], [@(0.0.255) bool]_[*@3 igno +reempty]_`=_[@(0.0.255) false])&] +[s5;:Join`(const Vector``&`,const WString`&`,bool`): [_^WString^ WString]_[* Jo +in]([@(0.0.255) const]_[_^Vector^ Vector]<[_^WString^ WString]>`&_[*@3 im], +[@(0.0.255) const]_[_^WString^ WString][@(0.0.255) `&]_[*@3 delim], [@(0.0.255) bool]_[*@3 ig +noreempty]_`=_[@(0.0.255) false])&] +[s2;%% Joins texts from [%-*@3 im], inserting [%-*@3 delim] between them. +If [%-*@3 ignoreempty] is true, empty texts are ignored. Note that +the default value of [%-*@3 ignoreempty] is the opposite of one +in Split.&] +[s3;%% &] +[s4;%% &] +[s5;:SplitTo`(const char`*`,int`,bool`,String`&`.`.`.`): [@(0.0.255) bool]_[* SplitTo]([@(0.0.255) c +onst]_[@(0.0.255) char]_`*[*@3 s], [@(0.0.255) int]_[*@3 delim], [@(0.0.255) bool]_[*@3 ignor +eempty], [_^String^ String][@(0.0.255) `&]_[*@3 p1][@(0.0.255) ...])&] +[s5;:SplitTo`(const char`*`,int`,String`&`.`.`.`): [@(0.0.255) bool]_[* SplitTo]([@(0.0.255) c +onst]_[@(0.0.255) char]_`*[*@3 s], [@(0.0.255) int]_[*@3 delim], [_^String^ String][@(0.0.255) `& +]_[*@3 p1][@(0.0.255) ...])&] +[s5;:SplitTo`(const char`*`,int`(`*`)`(int`)`,String`&`.`.`.`): [@(0.0.255) bool]_[* Spli +tTo]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s], [@(0.0.255) int]_(`*[*@3 filter])([@(0.0.255) i +nt]), String[@(0.0.255) `&]_[*@3 p1][@(0.0.255) ...])&] +[s5;:SplitTo`(const char`*`,const char`*`,bool`,String`&`.`.`.`): [@(0.0.255) bool]_[* Sp +litTo]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s], [@(0.0.255) const]_[@(0.0.255) char]_ +`*[*@3 delim], [@(0.0.255) bool]_[*@3 ignoreempty], [_^String^ String][@(0.0.255) `&]_[*@3 p1 +][@(0.0.255) ...])&] +[s5;:SplitTo`(const char`*`,const char`*`,String`&`.`.`.`): [@(0.0.255) bool]_[* SplitTo]( +[@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 d +elim], [_^String^ String][@(0.0.255) `&]_[*@3 p1][@(0.0.255) ...])&] +[s5;:SplitTo`(const wchar`*`,int`,bool`,WString`&`.`.`.`): [@(0.0.255) bool]_[* SplitTo]( +[@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 s], [@(0.0.255) int]_[*@3 delim], +[@(0.0.255) bool]_[*@3 ignoreempty], [_^WString^ WString][@(0.0.255) `&]_[*@3 p1][@(0.0.255) . +..])&] +[s5;:SplitTo`(const wchar`*`,int`,WString`&`.`.`.`): [@(0.0.255) bool]_[* SplitTo]([@(0.0.255) c +onst]_[_^wchar^ wchar]_`*[*@3 s], [@(0.0.255) int]_[*@3 delim], [_^WString^ WString][@(0.0.255) `& +]_[*@3 p1][@(0.0.255) ...])&] +[s5;:SplitTo`(const wchar`*`,int`(`*`)`(int`)`,WString`&`.`.`.`): [@(0.0.255) bool]_[* Sp +litTo]([@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 s], [@(0.0.255) int]_(`*[*@3 filter])([@(0.0.255) i +nt]), WString[@(0.0.255) `&]_[*@3 p1][@(0.0.255) ...])&] +[s5;:SplitTo`(const wchar`*`,const wchar`*`,bool`,WString`&`.`.`.`): [@(0.0.255) bool]_ +[* SplitTo]([@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 s], [@(0.0.255) const]_[_^wchar^ wchar +]_`*[*@3 delim], [@(0.0.255) bool]_[*@3 ignoreempty], [_^WString^ WString][@(0.0.255) `&]_[*@3 p +1][@(0.0.255) ...])&] +[s5;:SplitTo`(const wchar`*`,const wchar`*`,WString`&`.`.`.`): [@(0.0.255) bool]_[* Split +To]([@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 s], [@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 d +elim], [_^WString^ WString][@(0.0.255) `&]_[*@3 p1][@(0.0.255) ...])&] +[s2;%% Splits text into one or more targets substrings, inserting +them into string variables (current implementation supports up +to 8 output strings). Returns true if the source text contains +enough substrings. Delimiter can be defined as single character +[%-*@3 chr], character filter function [%-*@3 filter] (returns non`-zero +for delimiter character) or as string [%-*@3 text]. If [%-*@3 ignoreempty] +is true (default), empty subtexts are ignored. [%-*@3 maxcount] +can define upper limit of number of subtexts.&] +[s3;%% &] +[s4;%% &] +[s5;:Merge`(const char`*`,String`&`.`.`.`): [_^String^ String]_[* Merge]([@(0.0.255) const]_ +[@(0.0.255) char]_`*[*@3 delim], [_^String^ String][@(0.0.255) `&]_[*@3 p1][@(0.0.255) ...])&] +[s5;:Merge`(const wchar`*`,WString`&`.`.`.`): [_^WString^ WString]_[* Merge]([@(0.0.255) co +nst]_[_^wchar^ wchar]_`*[*@3 delim], [_^WString^ WString][@(0.0.255) `&]_[*@3 p1][@(0.0.255) . +..])&] +[s2;%% Merges substrings. Returns source strings concatenated with +delimiter put between them, however empty strings are ignored +(means Merge(`";`", `"1`", `"`") results in `"1`", not `"1;`").&] +[s3;%% &] +[s4;%% &] +[s5;:MergeWith`(String`&`,const char`*`,String`&`.`.`.`): [@(0.0.255) void]_[* MergeWith]( +[_^String^ String][@(0.0.255) `&]_[*@3 dest], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 del +im], [_^String^ String][@(0.0.255) `&]_[*@3 p1][@(0.0.255) ...])&] +[s5;:MergeWith`(WString`&`,const wchar`*`,WString`&`.`.`.`): [@(0.0.255) void]_[* MergeWi +th]([_^WString^ WString][@(0.0.255) `&]_[*@3 dest], [@(0.0.255) const]_[_^wchar^ wchar]_`*[*@3 d +elim], [_^WString^ WString][@(0.0.255) `&]_[*@3 p1][@(0.0.255) ...])&] +[s2;%% Merges substrings with dest. [%-*@3 dest] and source strings +concatenated with delimiter put between them are stored, however +empty strings are ignored.&] +[s3;%% ]] \ No newline at end of file diff --git a/uppsrc/ide/Builders/CppBuilder.cpp b/uppsrc/ide/Builders/CppBuilder.cpp index e6f5d66d5..d13ccff8a 100644 --- a/uppsrc/ide/Builders/CppBuilder.cpp +++ b/uppsrc/ide/Builders/CppBuilder.cpp @@ -248,7 +248,7 @@ Vector Cuprep(const String& m, const VectorMap& mac, } else r.Cat(*s++); - return Split(r, CharFilterTextTest(CharFilterEol)); + return Split(r, CharFilterEol); } bool CppBuilder::Cd(const String& cmd) { diff --git a/uppsrc/ide/Builders/init b/uppsrc/ide/Builders/init index e549e0805..9ad9edba8 100644 --- a/uppsrc/ide/Builders/init +++ b/uppsrc/ide/Builders/init @@ -2,19 +2,19 @@ #define _ide_Builders_icpp_init_stub #include "coff\binobj/init" #include "ide\Core/init" -#define BLITZ_INDEX__ Fe88d4241691b2ace9390e0f69164d181 +#define BLITZ_INDEX__ F774b8a1ae84f2d8f255be80983d999ac #include "GccBuilder.icpp" #undef BLITZ_INDEX__ -#define BLITZ_INDEX__ F1d6ab59cb8303fabe742f0bdd97fb439 +#define BLITZ_INDEX__ F0059f6d7377da3c3eb3cac2ae785c40f #include "MscBuilder.icpp" #undef BLITZ_INDEX__ -#define BLITZ_INDEX__ Fc874dfd308e5615d301ccf8b2652e70c +#define BLITZ_INDEX__ F6d37e82e414afc35c42d6c74d0c5b4ed #include "OwcBuilder.icpp" #undef BLITZ_INDEX__ -#define BLITZ_INDEX__ F266ea208d2eb267914094a29e66b5afc +#define BLITZ_INDEX__ Ffe78d94eb9485fbb8fec961febd10712 #include "JavaBuilder.icpp" #undef BLITZ_INDEX__ -#define BLITZ_INDEX__ F8c3c407c6c733c60e20f0a2d67ae304b +#define BLITZ_INDEX__ Fdc76aa28fa51a1f2aee853343af491ef #include "ScriptBuilder.icpp" #undef BLITZ_INDEX__ #endif diff --git a/uppsrc/ide/Core/Core.h b/uppsrc/ide/Core/Core.h index e16b8644f..317b51124 100644 --- a/uppsrc/ide/Core/Core.h +++ b/uppsrc/ide/Core/Core.h @@ -154,10 +154,6 @@ void ParseUscFile(const char *filename) throw(CParser::Error); Point ReadNums(CParser& p); Point ReadPoint(CParser& p); -struct SemiTextTest : public TextTest { - virtual const char *Accept(const char *s) const; -}; - Vector SplitDirs(const char *s); class Nest { diff --git a/uppsrc/ide/Core/Workspace.cpp b/uppsrc/ide/Core/Workspace.cpp index 791db376f..54492c511 100644 --- a/uppsrc/ide/Core/Workspace.cpp +++ b/uppsrc/ide/Core/Workspace.cpp @@ -43,15 +43,8 @@ String FollowCygwinSymlink(const String& file) { } } -const char *SemiTextTest::Accept(const char *s) const { - if(*s != ';') return NULL; - s++; - while(*s == ' ') s++; - return s; -}; - Vector SplitDirs(const char *s) { - return Split(s, Single()); + return Split(s, ';'); } static String varsname = "default"; @@ -307,7 +300,7 @@ void SplitHostName(const char *hostname, String& host, int& port) { } Vector SplitFlags0(const char *flags) { - return Split(flags, CharFilterTextTest(CharFilterWhitespace)); + return Split(flags, CharFilterWhitespace); } Vector SplitFlags(const char *flags, bool main, const Vector& accepts) diff --git a/uppsrc/ide/Debuggers/init b/uppsrc/ide/Debuggers/init index f64473c93..d686fb29e 100644 --- a/uppsrc/ide/Debuggers/init +++ b/uppsrc/ide/Debuggers/init @@ -3,7 +3,7 @@ #include "ide\Common/init" #include "plugin\ndisasm/init" #include "HexView/init" -#define BLITZ_INDEX__ F2300ec0d3d2de4bde7af30102b728c5d +#define BLITZ_INDEX__ Fa2117e771964dad617cdd6a1792596ea #include "UppSimplifiers.icpp" #undef BLITZ_INDEX__ #endif