summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bx/src/string.cpp
diff options
context:
space:
mode:
author Branimir Karadžić <branimirkaradzic@gmail.com>2017-02-05 13:56:35 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2017-02-05 13:56:35 +0100
commit1607745432f50099711d7aee355111111e66ff51 (patch)
treec4eaec8008f6e0283ca652cdffb55a34eca9b9bb /3rdparty/bx/src/string.cpp
parent193e8c8a89a4be5c63909cdbbcca4d9d6f8fee02 (diff)
Update BGFX and BX (nw)
Diffstat (limited to '3rdparty/bx/src/string.cpp')
-rw-r--r--3rdparty/bx/src/string.cpp515
1 files changed, 515 insertions, 0 deletions
diff --git a/3rdparty/bx/src/string.cpp b/3rdparty/bx/src/string.cpp
new file mode 100644
index 00000000000..c53a9de1155
--- /dev/null
+++ b/3rdparty/bx/src/string.cpp
@@ -0,0 +1,515 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/allocator.h>
+#include <bx/hash.h>
+#include <bx/readerwriter.h>
+#include <bx/string.h>
+
+#if !BX_CRT_NONE
+# include <stdio.h> // vsnprintf, vsnwprintf
+#endif // !BX_CRT_NONE
+
+namespace bx
+{
+ bool isSpace(char _ch)
+ {
+ return ' ' == _ch
+ || '\t' == _ch
+ || '\n' == _ch
+ || '\v' == _ch
+ || '\f' == _ch
+ || '\r' == _ch
+ ;
+ }
+
+ bool isUpper(char _ch)
+ {
+ return _ch >= 'A' && _ch <= 'Z';
+ }
+
+ bool isLower(char _ch)
+ {
+ return _ch >= 'a' && _ch <= 'z';
+ }
+
+ bool isAlpha(char _ch)
+ {
+ return isLower(_ch) || isUpper(_ch);
+ }
+
+ bool isNumeric(char _ch)
+ {
+ return _ch >= '0' && _ch <= '9';
+ }
+
+ bool isAlphaNum(char _ch)
+ {
+ return isAlpha(_ch) || isNumeric(_ch);
+ }
+
+ bool isPrint(char _ch)
+ {
+ return isAlphaNum(_ch) || isSpace(_ch);
+ }
+
+ char toLower(char _ch)
+ {
+ return _ch + (isUpper(_ch) ? 0x20 : 0);
+ }
+
+ char toUpper(char _ch)
+ {
+ return _ch - (isLower(_ch) ? 0x20 : 0);
+ }
+
+ bool toBool(const char* _str)
+ {
+ char ch = toLower(_str[0]);
+ return ch == 't' || ch == '1';
+ }
+
+ int32_t strncmp(const char* _lhs, const char* _rhs, size_t _max)
+ {
+ for (
+ ; 0 < _max && *_lhs == *_rhs
+ ; ++_lhs, ++_rhs, --_max
+ )
+ {
+ if (*_lhs == '\0'
+ || *_rhs == '\0')
+ {
+ break;
+ }
+ }
+
+ return 0 == _max ? 0 : *_lhs - *_rhs;
+ }
+
+ int32_t strincmp(const char* _lhs, const char* _rhs, size_t _max)
+ {
+ for (
+ ; 0 < _max && toLower(*_lhs) == toLower(*_rhs)
+ ; ++_lhs, ++_rhs, --_max
+ )
+ {
+ if (*_lhs == '\0'
+ || *_rhs == '\0')
+ {
+ break;
+ }
+ }
+
+ return 0 == _max ? 0 : *_lhs - *_rhs;
+ }
+
+ size_t strnlen(const char* _str, size_t _max)
+ {
+ const char* ptr;
+ for (ptr = _str; 0 < _max && *ptr != '\0'; ++ptr, --_max) {};
+ return ptr - _str;
+ }
+
+ size_t strlncpy(char* _dst, size_t _dstSize, const char* _src, size_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!");
+
+ const size_t len = strnlen(_src, _num);
+ const size_t max = _dstSize-1;
+ const size_t num = (len < max ? len : max);
+ memcpy(_dst, _src, num);
+ _dst[num] = '\0';
+
+ return num;
+ }
+
+ size_t strlncat(char* _dst, size_t _dstSize, const char* _src, size_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!");
+
+ const size_t max = _dstSize;
+ const size_t len = strnlen(_dst, max);
+ return strlncpy(&_dst[len], max-len, _src, _num);
+ }
+
+ const char* strnchr(const char* _str, char _ch, size_t _max)
+ {
+ for (size_t ii = 0, len = strnlen(_str, _max); ii < len; ++ii)
+ {
+ if (_str[ii] == _ch)
+ {
+ return &_str[ii];
+ }
+ }
+
+ return NULL;
+ }
+
+ const char* strnrchr(const char* _str, char _ch, size_t _max)
+ {
+ for (size_t ii = strnlen(_str, _max); 0 < ii; --ii)
+ {
+ if (_str[ii] == _ch)
+ {
+ return &_str[ii];
+ }
+ }
+
+ return NULL;
+ }
+
+ const char* strnstr(const char* _str, const char* _find, size_t _max)
+ {
+ const char* ptr = _str;
+
+ size_t stringLen = strnlen(_str, _max);
+ const size_t findLen = strnlen(_find);
+
+ for (; stringLen >= findLen; ++ptr, --stringLen)
+ {
+ // Find start of the string.
+ while (*ptr != *_find)
+ {
+ ++ptr;
+ --stringLen;
+
+ // Search pattern lenght 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 (*string++ == *search++)
+ {
+ // If end of the 'search' string is reached, all characters match.
+ if ('\0' == *search)
+ {
+ return ptr;
+ }
+ }
+ }
+
+ return NULL;
+ }
+
+ const char* stristr(const char* _str, const char* _find, size_t _max)
+ {
+ const char* ptr = _str;
+
+ size_t stringLen = strnlen(_str, _max);
+ const size_t findLen = strnlen(_find);
+
+ for (; stringLen >= findLen; ++ptr, --stringLen)
+ {
+ // Find start of the string.
+ while (toLower(*ptr) != toLower(*_find) )
+ {
+ ++ptr;
+ --stringLen;
+
+ // Search pattern lenght 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 (toLower(*string++) == toLower(*search++) )
+ {
+ // If end of the 'search' string is reached, all characters match.
+ if ('\0' == *search)
+ {
+ return ptr;
+ }
+ }
+ }
+
+ return NULL;
+ }
+
+ const char* strnl(const char* _str)
+ {
+ for (; '\0' != *_str; _str += strnlen(_str, 1024) )
+ {
+ const char* eol = strnstr(_str, "\r\n", 1024);
+ if (NULL != eol)
+ {
+ return eol + 2;
+ }
+
+ eol = strnstr(_str, "\n", 1024);
+ if (NULL != eol)
+ {
+ return eol + 1;
+ }
+ }
+
+ return _str;
+ }
+
+ const char* streol(const char* _str)
+ {
+ for (; '\0' != *_str; _str += strnlen(_str, 1024) )
+ {
+ const char* eol = strnstr(_str, "\r\n", 1024);
+ if (NULL != eol)
+ {
+ return eol;
+ }
+
+ eol = strnstr(_str, "\n", 1024);
+ if (NULL != eol)
+ {
+ return eol;
+ }
+ }
+
+ return _str;
+ }
+
+ const char* strws(const char* _str)
+ {
+ for (; isSpace(*_str); ++_str) {};
+ return _str;
+ }
+
+ const char* strnws(const char* _str)
+ {
+ for (; !isSpace(*_str); ++_str) {};
+ return _str;
+ }
+
+ const char* strword(const char* _str)
+ {
+ for (char ch = *_str++; isAlphaNum(ch) || '_' == ch; ch = *_str++) {};
+ return _str-1;
+ }
+
+ const char* strmb(const char* _str, char _open, char _close)
+ {
+ int count = 0;
+ for (char ch = *_str++; ch != '\0' && count >= 0; ch = *_str++)
+ {
+ if (ch == _open)
+ {
+ count++;
+ }
+ else if (ch == _close)
+ {
+ count--;
+ if (0 == count)
+ {
+ return _str-1;
+ }
+ }
+ }
+
+ return NULL;
+ }
+
+ void eolLF(char* _out, size_t _size, const char* _str)
+ {
+ if (0 < _size)
+ {
+ char* end = _out + _size - 1;
+ for (char ch = *_str++; ch != '\0' && _out < end; ch = *_str++)
+ {
+ if ('\r' != ch)
+ {
+ *_out++ = ch;
+ }
+ }
+
+ *_out = '\0';
+ }
+ }
+
+ const char* findIdentifierMatch(const char* _str, const char* _word)
+ {
+ size_t len = strnlen(_word);
+ const char* ptr = strnstr(_str, _word);
+ for (; NULL != ptr; ptr = strnstr(ptr + len, _word) )
+ {
+ if (ptr != _str)
+ {
+ char ch = *(ptr - 1);
+ if (isAlphaNum(ch) || '_' == ch)
+ {
+ continue;
+ }
+ }
+
+ char ch = ptr[len];
+ if (isAlphaNum(ch) || '_' == ch)
+ {
+ continue;
+ }
+
+ return ptr;
+ }
+
+ return ptr;
+ }
+
+ const char* findIdentifierMatch(const char* _str, const char* _words[])
+ {
+ for (const char* word = *_words; NULL != word; ++_words, word = *_words)
+ {
+ const char* match = findIdentifierMatch(_str, word);
+ if (NULL != match)
+ {
+ return match;
+ }
+ }
+
+ return NULL;
+ }
+
+ int32_t write(WriterI* _writer, const char* _format, va_list _argList, Error* _err);
+
+ int32_t vsnprintfRef(char* _out, size_t _max, const char* _format, va_list _argList)
+ {
+ if (1 < _max)
+ {
+ StaticMemoryBlockWriter writer(_out, _max-1);
+ _out[_max-1] = '\0';
+
+ Error err;
+ va_list argListCopy;
+ va_copy(argListCopy, _argList);
+ int32_t size = write(&writer, _format, argListCopy, &err);
+ va_end(argListCopy);
+
+ if (err.isOk() )
+ {
+ return size;
+ }
+ }
+
+ Error err;
+ SizerWriter sizer;
+ va_list argListCopy;
+ va_copy(argListCopy, _argList);
+ int32_t size = write(&sizer, _format, argListCopy, &err);
+ va_end(argListCopy);
+
+ return size - 1 /* size without '\0' terminator */;
+ }
+
+ int32_t vsnprintf(char* _out, size_t _max, const char* _format, va_list _argList)
+ {
+#if BX_CRT_NONE
+ return vsnprintfRef(_out, _max, _format, _argList);
+#elif BX_CRT_MSVC
+ int32_t len = -1;
+ if (NULL != _out)
+ {
+ va_list argListCopy;
+ va_copy(argListCopy, _argList);
+ len = ::vsnprintf_s(_out, _max, size_t(-1), _format, argListCopy);
+ va_end(argListCopy);
+ }
+ return -1 == len ? ::_vscprintf(_format, _argList) : len;
+#else
+ return ::vsnprintf(_out, _max, _format, _argList);
+#endif // BX_COMPILER_MSVC
+ }
+
+ int32_t snprintf(char* _out, size_t _max, const char* _format, ...)
+ {
+ va_list argList;
+ va_start(argList, _format);
+ int32_t len = vsnprintf(_out, _max, _format, argList);
+ va_end(argList);
+ return len;
+ }
+
+ int32_t vsnwprintf(wchar_t* _out, size_t _max, const wchar_t* _format, va_list _argList)
+ {
+#if BX_CRT_NONE
+ BX_UNUSED(_out, _max, _format, _argList);
+ return 0;
+#elif BX_CRT_MSVC
+ int32_t len = -1;
+ if (NULL != _out)
+ {
+ va_list argListCopy;
+ va_copy(argListCopy, _argList);
+ len = ::_vsnwprintf_s(_out, _max, size_t(-1), _format, argListCopy);
+ va_end(argListCopy);
+ }
+ return -1 == len ? ::_vscwprintf(_format, _argList) : len;
+#elif BX_CRT_MINGW
+ return ::vsnwprintf(_out, _max, _format, _argList);
+#else
+ return ::vswprintf(_out, _max, _format, _argList);
+#endif // BX_COMPILER_MSVC
+ }
+
+ int32_t swnprintf(wchar_t* _out, size_t _max, const wchar_t* _format, ...)
+ {
+ va_list argList;
+ va_start(argList, _format);
+ int32_t len = vsnwprintf(_out, _max, _format, argList);
+ va_end(argList);
+ return len;
+ }
+
+ const char* baseName(const char* _filePath)
+ {
+ const char* bs = strnrchr(_filePath, '\\');
+ const char* fs = strnrchr(_filePath, '/');
+ const char* slash = (bs > fs ? bs : fs);
+ const char* colon = strnrchr(_filePath, ':');
+ const char* basename = slash > colon ? slash : colon;
+ if (NULL != basename)
+ {
+ return basename+1;
+ }
+
+ return _filePath;
+ }
+
+ void prettify(char* _out, size_t _count, uint64_t _size)
+ {
+ uint8_t idx = 0;
+ double size = double(_size);
+ while (_size != (_size&0x7ff)
+ && idx < 9)
+ {
+ _size >>= 10;
+ size *= 1.0/1024.0;
+ ++idx;
+ }
+
+ snprintf(_out, _count, "%0.2f %c%c", size, "BkMGTPEZY"[idx], idx > 0 ? 'B' : '\0');
+ }
+
+ size_t strlcpy(char* _dst, const char* _src, size_t _max)
+ {
+ return strlncpy(_dst, _max, _src);
+ }
+
+ size_t strlcat(char* _dst, const char* _src, size_t _max)
+ {
+ return strlncat(_dst, _max, _src);
+ }
+
+} // namespace bx