summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bx/src/string.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bx/src/string.cpp')
-rw-r--r--3rdparty/bx/src/string.cpp302
1 files changed, 204 insertions, 98 deletions
diff --git a/3rdparty/bx/src/string.cpp b/3rdparty/bx/src/string.cpp
index 7710028ae6d..94429ebd21d 100644
--- a/3rdparty/bx/src/string.cpp
+++ b/3rdparty/bx/src/string.cpp
@@ -1,12 +1,11 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
-#include "bx_p.h"
#include <bx/allocator.h>
+#include <bx/file.h>
#include <bx/hash.h>
-#include <bx/readerwriter.h>
#include <bx/string.h>
namespace bx
@@ -135,7 +134,7 @@ namespace bx
{
for (int32_t ii = 0; ii < _len; ++ii)
{
- *_inOutStr = toLower(*_inOutStr);
+ _inOutStr[ii] = toLower(_inOutStr[ii]);
}
}
@@ -154,7 +153,7 @@ namespace bx
{
for (int32_t ii = 0; ii < _len; ++ii)
{
- *_inOutStr = toUpper(*_inOutStr);
+ _inOutStr[ii] = toUpper(_inOutStr[ii]);
}
}
@@ -188,7 +187,12 @@ namespace bx
}
}
- return 0 == max && _lhsMax == _rhsMax ? 0 : fn(*_lhs) - fn(*_rhs);
+ if (0 == max)
+ {
+ return _lhsMax == _rhsMax ? 0 : _lhsMax > _rhsMax ? 1 : -1;
+ }
+
+ return fn(*_lhs) - fn(*_rhs);
}
int32_t strCmp(const StringView& _lhs, const StringView& _rhs, int32_t _max)
@@ -305,9 +309,9 @@ namespace bx
inline int32_t strCopy(char* _dst, int32_t _dstSize, const char* _src, int32_t _num)
{
- BX_CHECK(NULL != _dst, "_dst can't be NULL!");
- BX_CHECK(NULL != _src, "_src can't be NULL!");
- BX_CHECK(0 < _dstSize, "_dstSize can't be 0!");
+ BX_ASSERT(NULL != _dst, "_dst can't be NULL!");
+ BX_ASSERT(NULL != _src, "_src can't be NULL!");
+ BX_ASSERT(0 < _dstSize, "_dstSize can't be 0!");
const int32_t len = strLen(_src, _num);
const int32_t max = _dstSize-1;
@@ -325,9 +329,9 @@ namespace bx
inline int32_t strCat(char* _dst, int32_t _dstSize, const char* _src, int32_t _num)
{
- BX_CHECK(NULL != _dst, "_dst can't be NULL!");
- BX_CHECK(NULL != _src, "_src can't be NULL!");
- BX_CHECK(0 < _dstSize, "_dstSize can't be 0!");
+ BX_ASSERT(NULL != _dst, "_dst can't be NULL!");
+ BX_ASSERT(NULL != _src, "_src can't be NULL!");
+ BX_ASSERT(0 < _dstSize, "_dstSize can't be 0!");
const int32_t max = _dstSize;
const int32_t len = strLen(_dst, max);
@@ -370,7 +374,7 @@ namespace bx
inline const char* strRFindUnsafe(const char* _str, int32_t _len, char _ch)
{
- for (int32_t ii = _len; 0 <= ii; --ii)
+ for (int32_t ii = _len-1; 0 <= ii; --ii)
{
if (_str[ii] == _ch)
{
@@ -408,25 +412,16 @@ namespace bx
++ptr;
--stringLen;
- // Search pattern lenght can't be longer than the string.
+ // Search pattern length can't be longer than the string.
if (findLen > stringLen)
{
return NULL;
}
}
- // Set pointers.
- const char* string = ptr;
- const char* search = _find;
-
- // Start comparing.
- while (fn(*string++) == fn(*search++) )
+ if (0 == strCmp<fn>(ptr, _findMax, _find, _findMax) )
{
- // If end of the 'search' string is reached, all characters match.
- if ('\0' == *search)
- {
- return ptr;
- }
+ return ptr;
}
}
@@ -485,7 +480,7 @@ namespace bx
}
}
- return _str;
+ return StringView(_str.getTerm(), _str.getTerm() );
}
StringView strLTrimSpace(const StringView& _str)
@@ -528,7 +523,29 @@ namespace bx
{
return StringView(ptr, ii + 1);
}
+ }
+
+ return StringView(_str.getPtr(), _str.getPtr());
+ }
+
+ return _str;
+ }
+
+ StringView strRTrimSpace(const StringView& _str)
+ {
+ if (!_str.isEmpty() )
+ {
+ const char* ptr = _str.getPtr();
+
+ for (int32_t len = _str.getLength(), ii = len - 1; 0 <= ii; --ii)
+ {
+ if (!isSpace(ptr[ii]) )
+ {
+ return StringView(ptr, ii + 1);
+ }
}
+
+ return StringView(_str.getPtr(), _str.getPtr());
}
return _str;
@@ -539,29 +556,24 @@ namespace bx
return strLTrim(strRTrim(_str, _chars), _chars);
}
+ StringView strTrimSpace(const StringView& _str)
+ {
+ return strLTrimSpace(strRTrimSpace(_str) );
+ }
+
constexpr uint32_t kFindStep = 1024;
StringView strFindNl(const StringView& _str)
{
StringView str(_str);
- for (; str.getPtr() != _str.getTerm()
- ; str = StringView(min(str.getPtr() + kFindStep, _str.getTerm() ), min(str.getPtr() + kFindStep*2, _str.getTerm() ) )
- )
+ // This method returns the character past the \n, so
+ // there is no need to look for he \r which preceedes it.
+ StringView eol = strFind(str, "\n");
+ if (!eol.isEmpty() )
{
- StringView eol = strFind(str, "\r\n");
- if (!eol.isEmpty() )
- {
- return StringView(eol.getTerm(), _str.getTerm() );
- }
-
- eol = strFind(str, '\n');
- if (!eol.isEmpty() )
- {
- return StringView(eol.getTerm(), _str.getTerm() );
- }
+ return StringView(eol.getTerm(), str.getTerm() );
}
-
return StringView(_str.getTerm(), _str.getTerm() );
}
@@ -669,7 +681,7 @@ namespace bx
StringView ptr = strFind(_str, _word);
for (; !ptr.isEmpty(); ptr = strFind(StringView(ptr.getPtr() + len, _str.getTerm() ), _word) )
{
- char ch = *(ptr.getPtr() - 1);
+ char ch = ptr.getPtr() != _str.getPtr() ? *(ptr.getPtr() - 1) : ' ';
if (isAlphaNum(ch) || '_' == ch)
{
continue;
@@ -687,9 +699,10 @@ namespace bx
return StringView(_str.getTerm(), _str.getTerm() );
}
- StringView findIdentifierMatch(const StringView& _str, const char** _words)
+ StringView findIdentifierMatch(const StringView& _str, const char** _words, int32_t _num)
{
- for (StringView word = *_words; !word.isEmpty(); ++_words, word = *_words)
+ int32_t ii = 0;
+ for (StringView word = *_words; ii < _num && !word.isEmpty(); ++ii, ++_words, word = *_words)
{
StringView match = findIdentifierMatch(_str, word);
if (!match.isEmpty() )
@@ -733,13 +746,40 @@ namespace bx
{
int32_t size = 0;
int32_t len = (int32_t)strLen(_str, _len);
- int32_t padding = _param.width > len ? _param.width - len : 0;
- bool sign = _param.sign && len > 1 && _str[0] != '-';
- padding = padding > 0 ? padding - sign : 0;
+
+ if (_param.width > 0)
+ {
+ len = min(_param.width, len);
+ }
+
+ const bool hasMinus = (NULL != _str && '-' == _str[0]);
+ const bool hasSign = _param.sign || hasMinus;
+ char sign = hasSign ? hasMinus ? '-' : '+' : '\0';
+
+ const char* str = _str;
+ if (hasMinus)
+ {
+ str++;
+ len--;
+ }
+
+ int32_t padding = _param.width > len ? _param.width - len - hasSign: 0;
if (!_param.left)
{
- size += writeRep(_writer, _param.fill, padding, _err);
+ if (' ' != _param.fill
+ && '\0' != sign)
+ {
+ size += write(_writer, sign, _err);
+ sign = '\0';
+ }
+
+ size += writeRep(_writer, _param.fill, max(0, padding), _err);
+ }
+
+ if ('\0' != sign)
+ {
+ size += write(_writer, sign, _err);
}
if (NULL == _str)
@@ -750,17 +790,12 @@ namespace bx
{
for (int32_t ii = 0; ii < len; ++ii)
{
- size += write(_writer, toUpper(_str[ii]), _err);
+ size += write(_writer, toUpper(str[ii]), _err);
}
}
- else if (sign)
- {
- size += write(_writer, '+', _err);
- size += write(_writer, _str, len, _err);
- }
else
{
- size += write(_writer, _str, len, _err);
+ size += write(_writer, str, len, _err);
}
if (_param.left)
@@ -781,6 +816,11 @@ namespace bx
return write(_writer, _str, _param.prec, _param, _err);
}
+ static int32_t write(WriterI* _writer, const StringView& _str, const Param& _param, Error* _err)
+ {
+ return write(_writer, _str.getPtr(), min(_param.prec, _str.getLength() ), _param, _err);
+ }
+
static int32_t write(WriterI* _writer, int32_t _i, const Param& _param, Error* _err)
{
char str[33];
@@ -843,30 +883,39 @@ namespace bx
return 0;
}
- if (_param.upper)
- {
- toUpperUnsafe(str, len);
- }
-
const char* dot = strFind(str, INT32_MAX, '.');
if (NULL != dot)
{
- const int32_t prec = INT32_MAX == _param.prec ? 6 : _param.prec;
- const int32_t precLen = int32_t(
- dot
- + uint32_min(prec + _param.spec, 1)
- + prec
- - str
- );
- if (precLen > len)
+ const int32_t prec = INT32_MAX == _param.prec ? 6 : _param.prec;
+ const char* strEnd = str + len;
+ const char* exponent = strFind(str, INT32_MAX, 'e');
+ const char* fracEnd = NULL != exponent ? exponent : strEnd;
+
+ char* fracBegin = &str[dot - str + min(prec + _param.spec, 1)];
+ const int32_t curPrec = int32_t(fracEnd - fracBegin);
+
+ // Move exponent to its final location after trimming or adding extra 0s.
+ if (fracEnd != strEnd)
+ {
+ const int32_t exponentLen = int32_t(strEnd - fracEnd);
+ char* finalExponentPtr = &fracBegin[prec];
+ memMove(finalExponentPtr, fracEnd, exponentLen);
+
+ finalExponentPtr[exponentLen] = '\0';
+ len = int32_t(&finalExponentPtr[exponentLen] - str);
+ }
+ else
{
- for (int32_t ii = len; ii < precLen; ++ii)
+ len = (int32_t)(fracBegin + prec - str);
+ }
+
+ if (curPrec < prec)
+ {
+ for (int32_t ii = curPrec; ii < prec; ++ii)
{
- str[ii] = '0';
+ fracBegin[ii] = '0';
}
- str[precLen] = '\0';
}
- len = precLen;
}
return write(_writer, str, len, _param, _err);
@@ -907,17 +956,22 @@ namespace bx
}
else if ('%' == ch)
{
- // %[flags][width][.precision][length sub-specifier]specifier
- read(&reader, ch);
+ // %[Flags][Width][.Precision][Leegth]Type
+ read(&reader, ch, &err);
Param param;
- // flags
- while (' ' == ch
+ // Reference(s):
+ // - Flags field
+ // https://en.wikipedia.org/wiki/Printf_format_string#Flags_field
+ //
+ while (err.isOk()
+ && ( ' ' == ch
|| '-' == ch
|| '+' == ch
|| '0' == ch
|| '#' == ch)
+ )
{
switch (ch)
{
@@ -929,7 +983,7 @@ namespace bx
case '#': param.spec = true; break;
}
- read(&reader, ch);
+ read(&reader, ch, &err);
}
if (param.left)
@@ -937,10 +991,13 @@ namespace bx
param.fill = ' ';
}
- // width
+ // Reference(s):
+ // - Width field
+ // https://en.wikipedia.org/wiki/Printf_format_string#Width_field
+ //
if ('*' == ch)
{
- read(&reader, ch);
+ read(&reader, ch, &err);
param.width = va_arg(_argList, int32_t);
if (0 > param.width)
@@ -952,49 +1009,57 @@ namespace bx
}
else
{
- while (isNumeric(ch) )
+ while (err.isOk()
+ && isNumeric(ch) )
{
param.width = param.width * 10 + ch - '0';
- read(&reader, ch);
+ read(&reader, ch, &err);
}
}
- // .precision
+ // Reference(s):
+ // - Precision field
+ // https://en.wikipedia.org/wiki/Printf_format_string#Precision_field
if ('.' == ch)
{
- read(&reader, ch);
+ read(&reader, ch, &err);
if ('*' == ch)
{
- read(&reader, ch);
+ read(&reader, ch, &err);
param.prec = va_arg(_argList, int32_t);
}
else
{
param.prec = 0;
- while (isNumeric(ch) )
+ while (err.isOk()
+ && isNumeric(ch) )
{
param.prec = param.prec * 10 + ch - '0';
- read(&reader, ch);
+ read(&reader, ch, &err);
}
}
}
- // length sub-specifier
- while ('h' == ch
+ // Reference(s):
+ // - Length field
+ // https://en.wikipedia.org/wiki/Printf_format_string#Length_field
+ while (err.isOk()
+ && ( 'h' == ch
|| 'I' == ch
|| 'l' == ch
|| 'j' == ch
|| 't' == ch
|| 'z' == ch)
+ )
{
switch (ch)
{
default: break;
case 'j': param.bits = sizeof(intmax_t )*8; break;
- case 't': param.bits = sizeof(size_t )*8; break;
- case 'z': param.bits = sizeof(ptrdiff_t)*8; break;
+ case 't': param.bits = sizeof(ptrdiff_t)*8; break;
+ case 'z': param.bits = sizeof(size_t )*8; break;
case 'h': case 'I': case 'l':
switch (ch)
@@ -1004,14 +1069,14 @@ namespace bx
default: break;
}
- read(&reader, ch);
+ read(&reader, ch, &err);
switch (ch)
{
case 'h': param.bits = sizeof(signed char )*8; break;
case 'l': param.bits = sizeof(long long int)*8; break;
case '3':
case '6':
- read(&reader, ch);
+ read(&reader, ch, &err);
switch (ch)
{
case '2': param.bits = sizeof(int32_t)*8; break;
@@ -1025,11 +1090,18 @@ namespace bx
break;
}
- read(&reader, ch);
+ read(&reader, ch, &err);
+ }
+
+ if (!err.isOk() )
+ {
+ break;
}
- // specifier
- switch (toLower(ch) )
+ // Reference(s):
+ // - Type field
+ // https://en.wikipedia.org/wiki/Printf_format_string#Type_field
+ switch (ch)
{
case 'c':
size += write(_writer, char(va_arg(_argList, int32_t) ), param, _err);
@@ -1039,6 +1111,10 @@ namespace bx
size += write(_writer, va_arg(_argList, const char*), param, _err);
break;
+ case 'S':
+ size += write(_writer, *va_arg(_argList, const StringView*), param, _err);
+ break;
+
case 'o':
param.base = 8;
switch (param.bits)
@@ -1059,8 +1135,11 @@ namespace bx
break;
case 'e':
+ case 'E':
case 'f':
+ case 'F':
case 'g':
+ case 'G':
param.upper = isUpper(ch);
size += write(_writer, va_arg(_argList, double), param, _err);
break;
@@ -1070,6 +1149,7 @@ namespace bx
break;
case 'x':
+ case 'X':
param.base = 16;
param.upper = isUpper(ch);
switch (param.bits)
@@ -1088,6 +1168,10 @@ namespace bx
}
break;
+ case 'n':
+ *va_arg(_argList, int32_t*) = size;
+ break;
+
default:
size += write(_writer, ch, _err);
break;
@@ -1147,10 +1231,10 @@ namespace bx
SizerWriter sizer;
va_list argListCopy;
va_copy(argListCopy, _argList);
- int32_t size = write(&sizer, _format, argListCopy, &err);
+ int32_t total = write(&sizer, _format, argListCopy, &err);
va_end(argListCopy);
- return size;
+ return total;
}
int32_t snprintf(char* _out, int32_t _max, const char* _format, ...)
@@ -1159,6 +1243,28 @@ namespace bx
va_start(argList, _format);
int32_t total = vsnprintf(_out, _max, _format, argList);
va_end(argList);
+
+ return total;
+ }
+
+ int32_t vprintf(const char* _format, va_list _argList)
+ {
+ Error err;
+ va_list argListCopy;
+ va_copy(argListCopy, _argList);
+ int32_t total = write(getStdOut(), _format, argListCopy, &err);
+ va_end(argListCopy);
+
+ return total;
+ }
+
+ int32_t printf(const char* _format, ...)
+ {
+ va_list argList;
+ va_start(argList, _format);
+ int32_t total = vprintf(_format, argList);
+ va_end(argList);
+
return total;
}