Skip to content

Commit

Permalink
Compare as strings holding indices/version numbers.
Browse files Browse the repository at this point in the history
  • Loading branch information
bkaradzic committed Jul 17, 2017
1 parent e95f6a0 commit 462a596
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/bx/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ namespace bx
/// Case insensitive string compare.
int32_t strCmpI(const char* _lhs, const StringView& _rhs);

// Compare as strings holding indices/version numbers.
int32_t strCmpV(const char* _lhs, const char* _rhs, int32_t _max = INT32_MAX);

// Compare as strings holding indices/version numbers.
int32_t strCmpV(const char* _lhs, const StringView& _rhs);

/// Get string length.
int32_t strLen(const char* _str, int32_t _max = INT32_MAX);

Expand Down
69 changes: 69 additions & 0 deletions src/string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,75 @@ namespace bx
return strCmpI(_lhs, _rhs.getPtr(), _rhs.getLength() );
}

int32_t strCmpV(const char* _lhs, const char* _rhs, int32_t _max)
{
int32_t ii = 0;
int32_t idx = 0;
bool zero = true;

for (
; 0 < _max && _lhs[ii] == _rhs[ii]
; ++ii, --_max
)
{
const uint8_t ch = _lhs[ii];
if ('\0' == ch
|| '\0' == _rhs[ii])
{
break;
}

if (!isNumeric(ch) )
{
idx = ii+1;
zero = true;
}
else if ('0' != ch)
{
zero = false;
}
}

if (0 == _max)
{
return 0;
}

if ('0' != _lhs[idx]
&& '0' != _rhs[idx])
{
int32_t jj = 0;
for (jj = ii
; 0 < _max && isNumeric(_lhs[jj])
; ++jj, --_max
)
{
if (!isNumeric(_rhs[jj]) )
{
return 1;
}
}

if (isNumeric(_rhs[jj]))
{
return -1;
}
}
else if (zero
&& idx < ii
&& (isNumeric(_lhs[ii]) || isNumeric(_rhs[ii]) ) )
{
return (_lhs[ii] - '0') - (_rhs[ii] - '0');
}

return 0 == _max ? 0 : _lhs[ii] - _rhs[ii];
}

int32_t strCmpV(const char* _lhs, const StringView& _rhs)
{
return strCmpV(_lhs, _rhs.getPtr(), _rhs.getLength() );
}

int32_t strLen(const char* _str, int32_t _max)
{
if (NULL == _str)
Expand Down
63 changes: 63 additions & 0 deletions tests/string_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "test.h"
#include <bx/string.h>
#include <bx/handlealloc.h>
#include <bx/sort.h>

bx::AllocatorI* g_allocator;

Expand Down Expand Up @@ -87,6 +88,68 @@ TEST_CASE("strCmpI", "")
REQUIRE(0 < bx::strCmpI(abvgd, empty) );
}

TEST_CASE("strCmpV", "")
{
REQUIRE(0 == bx::strCmpV("test", "test") );
REQUIRE(0 == bx::strCmpV("test", "testestes", 4) );
REQUIRE(0 == bx::strCmpV("testestes", "test", 4) );
REQUIRE(0 != bx::strCmpV("preprocess", "platform") );

const char* abvgd = "abvgd";
const char* abvgx = "abvgx";
const char* empty = "";
REQUIRE(0 == bx::strCmpV(abvgd, abvgd) );
REQUIRE(0 == bx::strCmpV(abvgd, abvgx, 4) );

REQUIRE(0 > bx::strCmpV(abvgd, abvgx) );
REQUIRE(0 > bx::strCmpV(empty, abvgd) );

REQUIRE(0 < bx::strCmpV(abvgx, abvgd) );
REQUIRE(0 < bx::strCmpV(abvgd, empty) );
}

static int32_t strCmpV(const void* _lhs, const void* _rhs)
{
const char* lhs = *(const char**)_lhs;
const char* rhs = *(const char**)_rhs;
int32_t result = bx::strCmpV(lhs, rhs);
return result;
}

TEST_CASE("strCmpV sort", "")
{
const char* test[] =
{
"test_1.txt",
"test_10.txt",
"test_100.txt",
"test_15.txt",
"test_11.txt",
"test_23.txt",
"test_3.txt",
};

const char* expected[] =
{
"test_1.txt",
"test_3.txt",
"test_10.txt",
"test_11.txt",
"test_15.txt",
"test_23.txt",
"test_100.txt",
};

BX_STATIC_ASSERT(BX_COUNTOF(test) == BX_COUNTOF(expected) );

bx::quickSort(test, BX_COUNTOF(test), sizeof(const char*), strCmpV);

for (uint32_t ii = 0; ii < BX_COUNTOF(test); ++ii)
{
REQUIRE(0 == bx::strCmp(test[ii], expected[ii]) );
}
}

TEST_CASE("strRFind", "")
{
const char* test = "test";
Expand Down

0 comments on commit 462a596

Please sign in to comment.