| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479 |
- /*
- * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
- */
- #include <alloca.h>
- #include <stdarg.h> // va_list
- #include <stdio.h> // vsnprintf, vsnwprintf
- #include <bx/string.h>
- #include <bx/allocator.h>
- #include <bx/hash.h>
- 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 vsnprintf(char* _str, size_t _count, const char* _format, va_list _argList)
- {
- #if BX_COMPILER_MSVC
- int32_t len = -1;
- if (NULL != _str)
- {
- va_list argListCopy;
- va_copy(argListCopy, _argList);
- len = ::vsnprintf_s(_str, _count, size_t(-1), _format, argListCopy);
- va_end(argListCopy);
- }
- return -1 == len ? ::_vscprintf(_format, _argList) : len;
- #else
- return ::vsnprintf(_str, _count, _format, _argList);
- #endif // BX_COMPILER_MSVC
- }
- int32_t vsnwprintf(wchar_t* _str, size_t _count, const wchar_t* _format, va_list _argList)
- {
- #if BX_COMPILER_MSVC
- int32_t len = -1;
- if (NULL != _str)
- {
- va_list argListCopy;
- va_copy(argListCopy, _argList);
- len = ::_vsnwprintf_s(_str, _count, size_t(-1), _format, argListCopy);
- va_end(argListCopy);
- }
- return -1 == len ? ::_vscwprintf(_format, _argList) : len;
- #elif defined(__MINGW32__)
- return ::vsnwprintf(_str, _count, _format, _argList);
- #else
- return ::vswprintf(_str, _count, _format, _argList);
- #endif // BX_COMPILER_MSVC
- }
- int32_t snprintf(char* _str, size_t _count, const char* _format, ...)
- {
- va_list argList;
- va_start(argList, _format);
- int32_t len = vsnprintf(_str, _count, _format, argList);
- va_end(argList);
- return len;
- }
- int32_t swnprintf(wchar_t* _out, size_t _count, const wchar_t* _format, ...)
- {
- va_list argList;
- va_start(argList, _format);
- int32_t len = vsnwprintf(_out, _count, _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
|