Add str find first occurence, fix array pop logic
Array pop was incorrectly returning the last element which is now an invalid ptr to data.
This commit is contained in:
parent
2203e9b4f2
commit
116861d888
113
dqn.h
113
dqn.h
@ -70,6 +70,7 @@ typedef float f32;
|
|||||||
// DArray - Dynamic Array
|
// DArray - Dynamic Array
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// REMINDER: Dynamic Array can be used as a stack. Don't need to create one.
|
// REMINDER: Dynamic Array can be used as a stack. Don't need to create one.
|
||||||
|
// TODO(doyle): Custom allocator
|
||||||
#if 1
|
#if 1
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct DqnArray
|
struct DqnArray
|
||||||
@ -105,8 +106,7 @@ bool DqnArray_Init(DqnArray<T> *array, size_t capacity)
|
|||||||
if (!DqnArray_Free(array)) return false;
|
if (!DqnArray_Free(array)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
array->data =
|
array->data = (T *)Dqn_MemAllocInternal((size_t)capacity * sizeof(T), true);
|
||||||
(T *)Dqn_MemAllocInternal((size_t)capacity * sizeof(T), true);
|
|
||||||
if (!array->data) return false;
|
if (!array->data) return false;
|
||||||
|
|
||||||
array->count = 0;
|
array->count = 0;
|
||||||
@ -123,8 +123,8 @@ bool DqnArray_Grow(DqnArray<T> *array)
|
|||||||
size_t newCapacity = (size_t)(array->capacity * GROWTH_FACTOR);
|
size_t newCapacity = (size_t)(array->capacity * GROWTH_FACTOR);
|
||||||
if (newCapacity == array->capacity) newCapacity++;
|
if (newCapacity == array->capacity) newCapacity++;
|
||||||
|
|
||||||
T *newMem = (T *)Dqn_MemReallocInternal(
|
T *newMem = (T *)Dqn_MemReallocInternal(array->data,
|
||||||
array->data, (size_t)(newCapacity * sizeof(T)));
|
(size_t)(newCapacity * sizeof(T)));
|
||||||
if (newMem)
|
if (newMem)
|
||||||
{
|
{
|
||||||
array->data = newMem;
|
array->data = newMem;
|
||||||
@ -154,13 +154,13 @@ T *DqnArray_Push(DqnArray<T> *array, T item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T *DqnArray_Pop(DqnArray<T> *array)
|
void DqnArray_Pop(DqnArray<T> *array)
|
||||||
{
|
{
|
||||||
if (!array) return NULL;
|
if (!array) return;
|
||||||
if (array->count == 0) return NULL;
|
if (array->count == 0) return;
|
||||||
|
array->count--;
|
||||||
|
|
||||||
T *result = &array->data[--array->count];
|
return;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -441,9 +441,9 @@ DQN_FILE_SCOPE i32 Dqn_strlenDelimitWith(const char *a, const char delimiter);
|
|||||||
DQN_FILE_SCOPE char *Dqn_strncpy (char *dest, const char *src, i32 numChars);
|
DQN_FILE_SCOPE char *Dqn_strncpy (char *dest, const char *src, i32 numChars);
|
||||||
|
|
||||||
#define DQN_I32_TO_STR_MAX_BUF_SIZE 11
|
#define DQN_I32_TO_STR_MAX_BUF_SIZE 11
|
||||||
DQN_FILE_SCOPE bool Dqn_StrReverse (char *buf, const i32 bufSize);
|
DQN_FILE_SCOPE bool Dqn_StrReverse (char *buf, const i32 bufSize);
|
||||||
DQN_FILE_SCOPE bool Dqn_StrHasSubstring(const char *const a, const i32 lenA,
|
DQN_FILE_SCOPE i32 Dqn_StrFindFirstOccurence(const char *const src, const i32 srcLen, const char *const find, const i32 findLen);
|
||||||
const char *const b, const i32 lenB);
|
DQN_FILE_SCOPE bool Dqn_StrHasSubstring (const char *const src, const i32 srcLen, const char *const find, const i32 findLen);
|
||||||
|
|
||||||
DQN_FILE_SCOPE i32 Dqn_StrToI32(const char *const buf, const i32 bufSize);
|
DQN_FILE_SCOPE i32 Dqn_StrToI32(const char *const buf, const i32 bufSize);
|
||||||
// Return the len of the derived string
|
// Return the len of the derived string
|
||||||
@ -515,29 +515,20 @@ typedef struct DqnFile
|
|||||||
} DqnFile;
|
} DqnFile;
|
||||||
|
|
||||||
// Open a handle to the file
|
// Open a handle to the file
|
||||||
DQN_FILE_SCOPE bool DqnFile_Open(const char *const path, DqnFile *const file,
|
DQN_FILE_SCOPE bool DqnFile_Open (const char *const path, DqnFile *const file, const u32 permissionFlags, const enum DqnFileAction action);
|
||||||
const u32 permissionFlags,
|
DQN_FILE_SCOPE bool DqnFile_OpenW(const wchar_t *const path, DqnFile *const file, const u32 permissionFlags, const enum DqnFileAction action);
|
||||||
const enum DqnFileAction action);
|
|
||||||
DQN_FILE_SCOPE bool DqnFile_OpenW(const wchar_t *const path, DqnFile *const file,
|
|
||||||
const u32 permissionFlags,
|
|
||||||
const enum DqnFileAction action);
|
|
||||||
|
|
||||||
// File offset is the byte offset to starting writing from
|
// File offset is the byte offset to starting writing from
|
||||||
DQN_FILE_SCOPE size_t DqnFile_Write(const DqnFile *const file,
|
DQN_FILE_SCOPE size_t DqnFile_Write(const DqnFile *const file, const u8 *const buffer, const size_t numBytesToWrite, const size_t fileOffset);
|
||||||
const u8 *const buffer,
|
|
||||||
const size_t numBytesToWrite,
|
|
||||||
const size_t fileOffset);
|
|
||||||
|
|
||||||
// Return the number of bytes read
|
// Return the number of bytes read
|
||||||
DQN_FILE_SCOPE size_t DqnFile_Read(const DqnFile file, const u8 *const buffer,
|
DQN_FILE_SCOPE size_t DqnFile_Read (const DqnFile file, const u8 *const buffer, const size_t numBytesToRead);
|
||||||
const size_t numBytesToRead);
|
DQN_FILE_SCOPE void DqnFile_Close(DqnFile *const file);
|
||||||
DQN_FILE_SCOPE void DqnFile_Close(DqnFile *const file);
|
|
||||||
|
|
||||||
// Return an array of strings of the files in the directory in UTF-8. numFiles
|
// Return an array of strings of the files in the directory in UTF-8. numFiles
|
||||||
// returns the number of strings read.
|
// returns the number of strings read.
|
||||||
// This is allocated using malloc and MUST BE FREED! Can be done manually or
|
// This is allocated using malloc and MUST BE FREED! Can be done manually or
|
||||||
// using the helper function.
|
// using the helper function.
|
||||||
DQN_FILE_SCOPE char **DqnDir_Read (char *dir, u32 *numFiles);
|
DQN_FILE_SCOPE char **DqnDir_Read (char *dir, u32 *numFiles);
|
||||||
DQN_FILE_SCOPE void DqnDir_ReadFree(char **fileList, u32 numFiles);
|
DQN_FILE_SCOPE void DqnDir_ReadFree(char **fileList, u32 numFiles);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1027,7 +1018,7 @@ zero-terminated. If `length` is zero, the length is determined automatically,
|
|||||||
#ifndef STB_SPRINTF_H_INCLUDE
|
#ifndef STB_SPRINTF_H_INCLUDE
|
||||||
#define STB_SPRINTF_H_INCLUDE
|
#define STB_SPRINTF_H_INCLUDE
|
||||||
|
|
||||||
#define STB_SPRINTF_DECORATE(name) dqn_##name
|
#define STB_SPRINTF_DECORATE(name) Dqn_##name
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// STB_Sprintf renamed to Dqn_Sprintf
|
// STB_Sprintf renamed to Dqn_Sprintf
|
||||||
@ -1358,7 +1349,7 @@ DQN_FILE_SCOPE bool DqnV2_Overlaps(DqnV2 a, DqnV2 b)
|
|||||||
|
|
||||||
DQN_FILE_SCOPE DqnV2 DqnV2_Perpendicular(DqnV2 a)
|
DQN_FILE_SCOPE DqnV2 DqnV2_Perpendicular(DqnV2 a)
|
||||||
{
|
{
|
||||||
DqnV2 result = {a.y, -a.x};
|
DqnV2 result = DqnV2_2f(a.y, -a.x);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1908,53 +1899,32 @@ DQN_FILE_SCOPE bool Dqn_StrReverse(char *buf, const i32 bufSize)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE bool Dqn_StrHasSubstring(const char *const a, const i32 lenA,
|
DQN_FILE_SCOPE i32 Dqn_StrFindFirstOccurence(const char *const src, const i32 srcLen,
|
||||||
const char *const b, const i32 lenB)
|
const char *const find, const i32 findLen)
|
||||||
{
|
{
|
||||||
if (!a || !b) return false;
|
if (!src || !find) return -1;
|
||||||
if (lenA == 0 || lenB == 0) return false;
|
if (srcLen == 0 || findLen == 0) return -1;
|
||||||
|
if (srcLen < findLen) return -1;
|
||||||
|
|
||||||
const char *longStr, *shortStr;
|
for (i32 indexIntoSrc = 0; indexIntoSrc < srcLen; indexIntoSrc++)
|
||||||
i32 longLen, shortLen;
|
|
||||||
if (lenA > lenB)
|
|
||||||
{
|
{
|
||||||
longStr = a;
|
// NOTE: As we scan through, if the src string we index into becomes
|
||||||
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
|
// shorter than the substring we're checking then the substring is not
|
||||||
// contained in the long string.
|
// contained in the src string.
|
||||||
i32 remainingLenInLongStr = longLen - indexIntoLong;
|
i32 remainingLenInSrcStr = srcLen - indexIntoSrc;
|
||||||
if (remainingLenInLongStr < shortLen) break;
|
if (remainingLenInSrcStr < findLen) break;
|
||||||
|
|
||||||
const char *longSubstr = &longStr[indexIntoLong];
|
const char *srcSubStr = &src[indexIntoSrc];
|
||||||
i32 index = 0;
|
i32 index = 0;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (DqnChar_ToLower(longSubstr[index]) ==
|
if (DqnChar_ToLower(srcSubStr[index]) ==
|
||||||
DqnChar_ToLower(shortStr[index]))
|
DqnChar_ToLower(find[index]))
|
||||||
{
|
{
|
||||||
index++;
|
index++;
|
||||||
if (index >= shortLen || !shortStr[index])
|
if (index >= findLen || !find[index])
|
||||||
{
|
{
|
||||||
matchedSubstr = true;
|
return indexIntoSrc;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1964,7 +1934,18 @@ DQN_FILE_SCOPE bool Dqn_StrHasSubstring(const char *const a, const i32 lenA,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return matchedSubstr;
|
// NOTE(doyle): We have early exit, if we reach here, then the substring was
|
||||||
|
// not found.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DQN_FILE_SCOPE bool Dqn_StrHasSubstring(const char *const src, const i32 srcLen,
|
||||||
|
const char *const find, const i32 findLen)
|
||||||
|
{
|
||||||
|
if (Dqn_StrFindFirstOccurence(src, srcLen, find, findLen) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE i32 Dqn_StrToI32(const char *const buf, const i32 bufSize)
|
DQN_FILE_SCOPE i32 Dqn_StrToI32(const char *const buf, const i32 bufSize)
|
||||||
|
Loading…
Reference in New Issue
Block a user