Add more string check functions

This commit is contained in:
Doyle Thai 2017-04-17 23:12:10 +10:00
parent 2cbb897efa
commit f42fca6350
2 changed files with 114 additions and 6 deletions

82
dqn.h
View File

@ -355,22 +355,26 @@ DQN_FILE_SCOPE bool dqn_rect_contains_p (DqnRect rect, DqnV2 p);
////////////////////////////////////////////////////////////////////////////////
// String Ops
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE char dqn_char_to_upper (char c);
DQN_FILE_SCOPE char dqn_char_to_lower (char c);
DQN_FILE_SCOPE char dqn_char_to_upper (char c);
DQN_FILE_SCOPE bool dqn_char_is_digit (char c);
DQN_FILE_SCOPE bool dqn_char_is_alpha (char c);
DQN_FILE_SCOPE bool dqn_char_is_alphanum(char c);
DQN_FILE_SCOPE i32 dqn_strcmp (const char *a, const char *b);
// Returns the length without the null terminator
DQN_FILE_SCOPE i32 dqn_strlen (const char *a);
DQN_FILE_SCOPE char *dqn_strncpy(char *dest, const char *src, i32 numChars);
DQN_FILE_SCOPE i32 dqn_strlen (const char *a);
DQN_FILE_SCOPE i32 dqn_strlen_delimit_with(const char *a, const char delimiter);
DQN_FILE_SCOPE char *dqn_strncpy (char *dest, const char *src, i32 numChars);
#define DQN_I32_TO_STR_MAX_BUF_SIZE 11
DQN_FILE_SCOPE bool dqn_str_reverse(char *buf, const i32 bufSize);
DQN_FILE_SCOPE i32 dqn_str_to_i32 (const char *const buf, const i32 bufSize);
DQN_FILE_SCOPE bool dqn_str_reverse (char *buf, const i32 bufSize);
DQN_FILE_SCOPE bool dqn_str_has_substring(const char *const a, const i32 lenA,
const char *const b, const i32 lenB);
DQN_FILE_SCOPE i32 dqn_str_to_i32(const char *const buf, const i32 bufSize);
// Return the len of the derived string
DQN_FILE_SCOPE i32 dqn_i32_to_str (i32 value, char *buf, i32 bufSize);
DQN_FILE_SCOPE i32 dqn_i32_to_str(i32 value, char *buf, i32 bufSize);
// Both return the number of bytes read, return 0 if invalid codepoint or UTF8
DQN_FILE_SCOPE u32 dqn_ucs_to_utf8(u32 *dest, u32 character);
@ -1600,6 +1604,13 @@ DQN_FILE_SCOPE i32 dqn_strlen(const char *a)
return result;
}
DQN_FILE_SCOPE i32 dqn_strlen_delimit_with(const char *a, const char delimiter)
{
i32 result = 0;
while (a && a[result] && a[result] != delimiter) result++;
return result;
}
DQN_FILE_SCOPE char *dqn_strncpy(char *dest, const char *src, i32 numChars)
{
if (!dest) return NULL;
@ -1626,6 +1637,65 @@ DQN_FILE_SCOPE bool dqn_str_reverse(char *buf, const i32 bufSize)
return true;
}
DQN_FILE_SCOPE bool dqn_str_has_substring(const char *const a, const i32 lenA,
const char *const b, const i32 lenB)
{
if (!a || !b) return false;
if (lenA == 0 || lenB == 0) return false;
const char *longStr, *shortStr;
i32 longLen, shortLen;
if (lenA > lenB)
{
longStr = a;
longLen = lenA;
shortStr = b;
shortLen = lenB;
}
else
{
longStr = b;
longLen = lenB;
shortStr = a;
shortLen = lenA;
}
bool matchedSubstr = false;
for (i32 indexIntoLong = 0; indexIntoLong < longLen && !matchedSubstr;
indexIntoLong++)
{
// NOTE: As we scan through, if the longer string we index into becomes
// shorter than the substring we're checking then the substring is not
// contained in the long string.
i32 remainingLenInLongStr = longLen - indexIntoLong;
if (remainingLenInLongStr < shortLen) break;
const char *longSubstr = &longStr[indexIntoLong];
i32 index = 0;
for (;;)
{
if (dqn_char_to_lower(longSubstr[index]) ==
dqn_char_to_lower(shortStr[index]))
{
index++;
if (index >= shortLen || !shortStr[index])
{
matchedSubstr = true;
break;
}
}
else
{
break;
}
}
}
return matchedSubstr;
}
DQN_FILE_SCOPE i32 dqn_str_to_i32(const char *const buf, const i32 bufSize)
{
if (!buf || bufSize == 0) return 0;

View File

@ -27,6 +27,14 @@ void dqn_strings_test()
DQN_ASSERT(dqn_char_is_alphanum(' ') == false);
DQN_ASSERT(dqn_char_is_alphanum('\n') == false);
DQN_ASSERT(dqn_char_to_lower(L'A') == L'a');
DQN_ASSERT(dqn_char_to_lower(L'a') == L'a');
DQN_ASSERT(dqn_char_to_lower(L' ') == L' ');
DQN_ASSERT(dqn_char_to_upper(L'A') == L'A');
DQN_ASSERT(dqn_char_to_upper(L'a') == L'A');
DQN_ASSERT(dqn_char_to_upper(L' ') == L' ');
printf("dqn_strings_test(): char_checks: Completed successfully\n");
}
@ -208,6 +216,36 @@ void dqn_strings_test()
}
}
{
{
char *a = "Microsoft";
char *b = "icro";
i32 lenA = dqn_strlen(a);
i32 lenB = dqn_strlen(b);
DQN_ASSERT(dqn_str_has_substring(a, lenA, b, lenB) == true);
DQN_ASSERT(dqn_str_has_substring(a, lenA, "iro",
dqn_strlen("iro")) == false);
DQN_ASSERT(dqn_str_has_substring(b, lenB, a, lenA) == true);
DQN_ASSERT(dqn_str_has_substring("iro", dqn_strlen("iro"), a,
lenA) == false);
DQN_ASSERT(dqn_str_has_substring("", 0, "iro", 4) == false);
DQN_ASSERT(dqn_str_has_substring("", 0, "", 0) == false);
DQN_ASSERT(dqn_str_has_substring(NULL, 0, NULL, 0) == false);
}
{
char *a = "Micro";
char *b = "irob";
i32 lenA = dqn_strlen(a);
i32 lenB = dqn_strlen(b);
DQN_ASSERT(dqn_str_has_substring(a, lenA, b, lenB) == false);
DQN_ASSERT(dqn_str_has_substring(b, lenB, a, lenA) == false);
}
printf("dqn_strings_test(): str_has_substring: Completed successfully\n");
}
// UCS <-> UTF8 Checks
{
// Test ascii characters