Bug I introduced in StrHToBuf.

Remove PRINTF_EMIT_CR=1.
ReleaseDate wrongly had a \n at the end.
Bug in utf8_stringnn_from_utf16_string.
XString replaceAll(XString,XString) function.
This commit is contained in:
jief666 2020-08-16 16:21:12 +03:00
parent de45197556
commit d4b3fb9b7a
10 changed files with 193 additions and 70 deletions

View File

@ -29,7 +29,7 @@
#define PRINTF_CFUNCTION_PREFIX
#define PRINTF_CFUNCTION_SUFFIX f
#define PRINTF_EMIT_CR 1
#define PRINTF_EMIT_CR 0

View File

@ -38,7 +38,7 @@
IoLib
[BuildOptions]
XCODE:*_*_*_CC_FLAGS = -Os -fno-lto -UUSING_LTO -DMDEPKG_NDEBUG -DPRINTF_EMIT_CR=1
GCC:*_*_*_CC_FLAGS = -Os -fno-lto -DMDEPKG_NDEBUG -DPRINTF_EMIT_CR=1
MSFT:*_*_*_CC_FLAGS = /D PRINTF_EMIT_CR=1
XCODE:*_*_*_CC_FLAGS = -Os -fno-lto -UUSING_LTO -DMDEPKG_NDEBUG
GCC:*_*_*_CC_FLAGS = -Os -fno-lto -DMDEPKG_NDEBUG
MSFT:*_*_*_CC_FLAGS =

View File

@ -29,6 +29,7 @@ int vprintf(const char* format, VA_LIST va)
{
// AsciiPrint seems no to work with utf8 chars. We have to use Print instead
stdio_static_wbuf.vSWPrintf(format, va);
stdio_static_wbuf.replaceAll("\n"_XS8, "\r\n"_XS8);
int ret = (int)Print(L"%s", stdio_static_wbuf.wc_str());
return ret;
}

View File

@ -4175,7 +4175,7 @@ ParseSMBIOSSettings(
Prop = GetProperty(DictPointer, "SmUUID");
if (Prop != NULL) {
if (IsValidGuidAsciiString(Prop->string)) {
StrToGuidLE (Prop->string, &gSettings.SmUUID);
StrToGuidLE(Prop->string, &gSettings.SmUUID);
gSettings.SmUUIDConfig = TRUE;
} else {
DBG("Error: invalid SmUUID '%s' - should be in the format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n", Prop->string.c_str());

View File

@ -61,9 +61,9 @@ StrHToBuf (
//
// Two hex char make up one byte
//
StrLength = length_of_utf_string(Str);
StrLength = BufferLength * sizeof (CHAR16);
for(Index = 0; Index < StrLength; Index++, Str++) {
for(Index = 0; Index < StrLength; Index++) {
if ((Str[Index] >= (__typeof__(*Str))'a') && (Str[Index] <= (__typeof__(*Str))'f')) {
Digit = (UINT8) (Str[Index] - (__typeof__(*Str))'a' + 0x0A);

View File

@ -639,7 +639,7 @@ VOID SetDMISettingsForModel(MACHINE_TYPES Model, BOOLEAN Redefine)
while (*i != '.') {
i--;
}
gSettings.ReleaseDate.S8Printf("%c%c/%c%c/%c%c\n", i[3], i[4], i[5], i[6], i[1], i[2]);
gSettings.ReleaseDate.S8Printf("%c%c/%c%c/%c%c", i[3], i[4], i[5], i[6], i[1], i[2]);
break;
default:
@ -649,7 +649,7 @@ VOID SetDMISettingsForModel(MACHINE_TYPES Model, BOOLEAN Redefine)
while (*i != '.') {
i--;
}
gSettings.ReleaseDate.S8Printf("%c%c/%c%c/20%c%c\n", i[3], i[4], i[5], i[6], i[1], i[2]);
gSettings.ReleaseDate.S8Printf("%c%c/%c%c/20%c%c", i[3], i[4], i[5], i[6], i[1], i[2]);
break;
}

View File

@ -1118,7 +1118,7 @@ VOID PatchTableType11()
// AsciiStrnCatS(OEMString, MAX_OEM_STRING, gSettings.BoardNumber, iStrLen(gSettings.BoardNumber, 64));
// snprintf(TempRev, MAX_OEM_STRING, "\n⌘ Powered by %s\n", gRevisionStr);
// AsciiStrCatS(OEMString, MAX_OEM_STRING, TempRev);
XString8 OEMString = S8Printf("Apple ROM Version.\n Board-ID : %s\n⌘ Powered by %s\n", gSettings.BoardNumber.c_str(), gRevisionStr);
XString8 OEMString = S8Printf("Apple ROM Version.\n Board-ID : %s\r\n⌘ Powered by %s\r\n", gSettings.BoardNumber.c_str(), gRevisionStr);
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type11->StringCount, OEMString);

View File

@ -50,9 +50,6 @@
#define asciiToLower(ch) (((ch >= L'A') && (ch <= L'Z')) ? ((ch - L'A') + L'a') : ch)
#define asciiToUpper(ch) (((ch >= L'a') && (ch <= L'z')) ? ((ch - L'a') + L'A') : ch)
@ -569,6 +566,61 @@ protected:
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
///* __String + char32_t */
//template<typename CharType1, class XStringClass1>
//XStringClass1 operator + (const __String<CharType1, XStringClass1>& p1, char32_t p2) { XStringClass1 s; s.takeValueFrom(p1); s.strcat(p2); return s; }
//
///* __String + __String */
//template<typename CharType1, class XStringClass1, typename CharType2, class XStringClass2>
//XStringClass1 operator + (const __String<CharType1, XStringClass1>& p1, const __String<CharType2, XStringClass2>& p2) { XStringClass1 s; s.takeValueFrom(p1); s.strcat(p2); return s; }
//
///* char* + __String */
//template<typename CharType1, typename CharType2, class XStringClass2>
//XStringClass2 operator + (const CharType1* p1, const __String<CharType2, XStringClass2>& p2) { XStringClass2 s; s.takeValueFrom(p1); s.strcat(p2); return s; }
//
///* __String + char* */
//template<typename T1, class XStringClass1, typename CharType2>
//XStringClass1 operator + (const __String<T1, XStringClass1>& p1, const CharType2* p2) { XStringClass1 s; s.takeValueFrom(p1); s.strcat(p2); return s; }
template <typename Base> _xtools__true_type is_base_of_test_func( Base* );
template <typename Base> _xtools__false_type is_base_of_test_func( void* );
template <typename B, typename D>
auto test_pre_is_base_of(int) -> decltype(is_base_of_test_func<B>(static_cast<D*>(nullptr)));
template< class, class = _xtools__void_t<>, class = _xtools__void_t<> >
struct __string_type { typedef void type; };
template< typename T >
struct __string_type<T, _xtools__void_t<typename T::xs_t>, _xtools__void_t<typename T::char_t>> { typedef __String<typename T::char_t, typename T::xs_t> type; };
#define is___String_t(x) decltype(test_pre_is_base_of<typename __string_type<x>::type , x>(0))
#define is___String(x) is___String_t(x)::value
template< class, class = _xtools__void_t<>, class = _xtools__void_t<> >
struct __lstring_type { typedef void type; };
template< typename T >
struct __lstring_type<T, _xtools__void_t<typename T::xs_t>, _xtools__void_t<typename T::char_t>> { typedef LString<typename T::char_t, typename T::xs_t> type; };
#define is___LString_t(x) decltype(test_pre_is_base_of< typename __lstring_type<x>::type , x>(0))
#define is___LString(x) is___LString_t(x)::value
/* __string_class_or<T1, T2>::type is T1 is T1 is a subclass of __String. If T1 is not a subclass of __String, returns T2 if it's a subclass of __String */
template <typename T1, typename T2, typename Tdummy=void>
struct __string_class_or;
template <typename T1, typename T2>
struct __string_class_or<T1, T2, enable_if_t(!is___String(T1) && !is___String(T2))> { /*typedef double type;*/ };
template <typename T1, typename T2>
struct __string_class_or<T1, T2, enable_if_t(is___String(T1))> { typedef typename T1::xs_t type; };
template <typename T1, typename T2>
struct __string_class_or<T1, T2, enable_if_t(!is___String(T1) && is___String(T2))> { typedef typename T2::xs_t type; };
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#define m_data __String<T, ThisXStringClass>::m_data
template<class T, class ThisXStringClass>
@ -931,6 +983,41 @@ public:
}
return *((ThisXStringClass*)this);
}
template<typename OtherXStringClass1, class OtherXStringClass2, enable_if( is___String(OtherXStringClass1) && is___String(OtherXStringClass2))>
ThisXStringClass& replaceAll(const OtherXStringClass1& search, const OtherXStringClass2& replaceBy )
{
size_t currentSize = __String<T, ThisXStringClass>::sizeInNativeChars(); // size is number of T, not in bytes
size_t sizeLeft = currentSize; // size is number of T, not in bytes
size_t searchSize = utf_size_of_utf_string(m_data, search.s()); // size is number of T, not in bytes
size_t replaceBySize = utf_size_of_utf_string(m_data, replaceBy.s()); // size is number of T, not in bytes
// careful because 'charToReplaceBySize - charToSearchSize' overflows when charToSearchSize > charToReplaceBySize, which happens.
// size_t pos = __String<T, ThisXStringClass>::indexOf(search);
T* previousData = m_data;
T* previousP = m_data;
T* p = m_data;
size_t pos = XStringAbstract__indexOf((const T**)&p, search.s(), 0, false);
while ( pos != MAX_XSIZE ) {
if ( CheckSize(currentSize + replaceBySize - searchSize) ) {
previousP = m_data + ( previousP - previousData );
p = m_data + ( p - previousData );
previousData = m_data;
}
sizeLeft -= p-previousP;
memmove(p+replaceBySize, p+searchSize, (sizeLeft - searchSize + 1)*sizeof(T));
// memmove(m_data+pos+replaceBySize-searchSize, m_data+pos, (currentSize - pos + 1)*sizeof(T));
utf_stringnn_from_utf_string(p, replaceBySize, replaceBy.s());
p += replaceBySize;
currentSize += replaceBySize;
currentSize -= searchSize;
sizeLeft -= searchSize;
// sizeLeft is equal to utf_size_of_utf_string(p, p);
previousP = p;
pos = XStringAbstract__indexOf((const T**)&p, search.s(), 0, false);
}
return *((ThisXStringClass*)this);
}
void trim()
@ -1012,58 +1099,6 @@ template<class T, class ThisXStringClass>
T XStringAbstract<T, ThisXStringClass>::nullChar = 0;
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
///* __String + char32_t */
//template<typename CharType1, class XStringClass1>
//XStringClass1 operator + (const __String<CharType1, XStringClass1>& p1, char32_t p2) { XStringClass1 s; s.takeValueFrom(p1); s.strcat(p2); return s; }
//
///* __String + __String */
//template<typename CharType1, class XStringClass1, typename CharType2, class XStringClass2>
//XStringClass1 operator + (const __String<CharType1, XStringClass1>& p1, const __String<CharType2, XStringClass2>& p2) { XStringClass1 s; s.takeValueFrom(p1); s.strcat(p2); return s; }
//
///* char* + __String */
//template<typename CharType1, typename CharType2, class XStringClass2>
//XStringClass2 operator + (const CharType1* p1, const __String<CharType2, XStringClass2>& p2) { XStringClass2 s; s.takeValueFrom(p1); s.strcat(p2); return s; }
//
///* __String + char* */
//template<typename T1, class XStringClass1, typename CharType2>
//XStringClass1 operator + (const __String<T1, XStringClass1>& p1, const CharType2* p2) { XStringClass1 s; s.takeValueFrom(p1); s.strcat(p2); return s; }
template <typename Base> _xtools__true_type is_base_of_test_func( Base* );
template <typename Base> _xtools__false_type is_base_of_test_func( void* );
template <typename B, typename D>
auto test_pre_is_base_of(int) -> decltype(is_base_of_test_func<B>(static_cast<D*>(nullptr)));
template< class, class = _xtools__void_t<>, class = _xtools__void_t<> >
struct __string_type { typedef void type; };
template< typename T >
struct __string_type<T, _xtools__void_t<typename T::xs_t>, _xtools__void_t<typename T::char_t>> { typedef __String<typename T::char_t, typename T::xs_t> type; };
#define is___String_t(x) decltype(test_pre_is_base_of<typename __string_type<x>::type , x>(0))
#define is___String(x) is___String_t(x)::value
template< class, class = _xtools__void_t<>, class = _xtools__void_t<> >
struct __lstring_type { typedef void type; };
template< typename T >
struct __lstring_type<T, _xtools__void_t<typename T::xs_t>, _xtools__void_t<typename T::char_t>> { typedef LString<typename T::char_t, typename T::xs_t> type; };
#define is___LString_t(x) decltype(test_pre_is_base_of< typename __lstring_type<x>::type , x>(0))
#define is___LString(x) is___LString_t(x)::value
/* __string_class_or<T1, T2>::type is T1 is T1 is a subclass of __String. If T1 is not a subclass of __String, returns T2 if it's a subclass of __String */
template <typename T1, typename T2, typename Tdummy=void>
struct __string_class_or;
template <typename T1, typename T2>
struct __string_class_or<T1, T2, enable_if_t(!is___String(T1) && !is___String(T2))> { /*typedef double type;*/ };
template <typename T1, typename T2>
struct __string_class_or<T1, T2, enable_if_t(is___String(T1))> { typedef typename T1::xs_t type; };
template <typename T1, typename T2>
struct __string_class_or<T1, T2, enable_if_t(!is___String(T1) && is___String(T2))> { typedef typename T2::xs_t type; };
//------------------------------------------------------- + operator
template<typename T1, typename T2, enable_if( is___String(T1) || is___String(T2) )>

View File

@ -545,7 +545,6 @@ size_t utf8_stringnn_from_utf16_string(char* dst, size_t dst_max_size, const cha
return 0;
}
char* p = dst;
dst_max_size -= 1;
while ( *s && dst_max_size > 0 ) {
char32_t utf32_char;
s = get_char32_from_utf16_string(s, &utf32_char);

View File

@ -1592,11 +1592,99 @@ int XString_tests()
}
}
XString8 xsReplace = "babcbdeb"_XS8;
xsReplace.replaceAll(U'b', U'𐅃');
{
XString8 xsReplace = "babcbdeb"_XS8;
xsReplace.replaceAll(U'b', U'𐅃');
}
{
XString8 xsReplace2 = "𐄔a𐄔c𐄔de𐄔"_XS8;
xsReplace2.replaceAll(U'𐄔', U'x');
}
// {
// XString8 xsReplace = "𐅃𐅃ab"_XS8;
// xsReplace.replaceAll("𐅃𐅃"_XS8, "12"_XS8);
// if ( xsReplace != "12ab"_XS8 ) {
// nbTestFailed += 1;
// }
// }
// TODO proper test
// XSW XS8
{
XString8 xsReplace = "12ab12cd12ef1212"_XS8;
xsReplace.replaceAll(L"12"_XSW, L"𐅃𐅃"_XSW);
if ( xsReplace != "𐅃𐅃ab𐅃𐅃cd𐅃𐅃ef𐅃𐅃𐅃𐅃"_XS8 ) {
nbTestFailed += 1;
}
}
{
XString8 xsReplace = "𐅃𐅃ab𐅃𐅃cd𐅃𐅃ef𐅃𐅃𐅃𐅃"_XS8;
xsReplace.replaceAll(L"𐅃𐅃"_XSW, L"12"_XSW);
if ( xsReplace != "12ab12cd12ef1212"_XS8 ) {
nbTestFailed += 1;
}
}
// XS8 XSW
{
XStringW xsReplace = L"12ab12cd12ef1212"_XSW;
xsReplace.replaceAll("12"_XS8, "𐅃𐅃"_XS8);
if ( xsReplace != "𐅃𐅃ab𐅃𐅃cd𐅃𐅃ef𐅃𐅃𐅃𐅃"_XS8 ) {
nbTestFailed += 1;
}
}
{
XStringW xsReplace = L"𐅃𐅃ab𐅃𐅃cd𐅃𐅃ef𐅃𐅃𐅃𐅃"_XSW;
xsReplace.replaceAll("𐅃𐅃"_XS8, "12"_XS8);
if ( xsReplace != "12ab12cd12ef1212"_XS8 ) {
nbTestFailed += 1;
}
}
//XSW XSW
{
XStringW xsReplace = L"12ab12cd12ef1212"_XSW;
xsReplace.replaceAll(L"12"_XSW, L"𐅃𐅃"_XSW);
if ( xsReplace != L"𐅃𐅃ab𐅃𐅃cd𐅃𐅃ef𐅃𐅃𐅃𐅃"_XSW ) {
nbTestFailed += 1;
}
}
{
XStringW xsReplace = L"𐅃𐅃ab𐅃𐅃cd𐅃𐅃ef𐅃𐅃𐅃𐅃"_XSW;
xsReplace.replaceAll(L"𐅃𐅃"_XSW, L"12"_XSW);
if ( xsReplace != L"12ab12cd12ef1212"_XSW ) {
nbTestFailed += 1;
}
}
// XS8 XS8
{
XString8 xsReplace = "12ab12cd12ef1212"_XS8;
xsReplace.replaceAll("12"_XS8, "𐅃𐅃"_XS8);
if ( xsReplace != "𐅃𐅃ab𐅃𐅃cd𐅃𐅃ef𐅃𐅃𐅃𐅃"_XS8 ) {
nbTestFailed += 1;
}
}
{
XString8 xsReplace = "𐅃𐅃ab𐅃𐅃cd𐅃𐅃ef𐅃𐅃𐅃𐅃"_XS8;
xsReplace.replaceAll("𐅃𐅃"_XS8, "12"_XS8);
if ( xsReplace != "12ab12cd12ef1212"_XS8 ) {
nbTestFailed += 1;
}
}
//
{
XString8 xsReplace = "ab𐅃𐅃cd𐅃𐅃𐅃𐅃ef"_XS8;
xsReplace.replaceAll("𐅃𐅃"_XS8, "12"_XS8);
if ( xsReplace != "ab12cd1212ef"_XS8 ) {
nbTestFailed += 1;
}
}
{
XString8 xsReplace = "ab𐅃𐅃cd𐅃𐅃𐅃ef"_XS8;
xsReplace.replaceAll("𐅃𐅃"_XS8, "12"_XS8);
if ( xsReplace != "ab12cd12𐅃ef"_XS8 ) {
nbTestFailed += 1;
}
}
XString8 xsReplace2 = "𐄔a𐄔c𐄔de𐄔"_XS8;
xsReplace2.replaceAll(U'𐄔', U'x');
// Quick check of stealValueFrom. TOTO proper test
{