WARNING: BREAKING: REDESIGNED: TextInsert(), TextReplace(), TextReplaceBetween(), using static buffers

Redesign has been conditioned by the usage of those functions on `rexm`, `rpc` and other tools; for many use cases a static buffer is enough and way more comfortable to use.
ADDED: `TextInsertAlloc()`, `TextReplaceAlloc()`, `TextReplaceBetweenAlloc()`, alternatives with internal allocations
This commit is contained in:
Ray
2026-03-27 21:56:29 +01:00
parent ba83bd33f3
commit 8a7aff509d
5 changed files with 185 additions and 50 deletions

View File

@ -1736,8 +1736,6 @@ const char *TextRemoveSpaces(const char *text)
// Get text between two strings
char *GetTextBetween(const char *text, const char *begin, const char *end)
{
#define MAX_TEXT_BETWEEN_SIZE 1024
static char buffer[MAX_TEXT_BUFFER_LENGTH] = { 0 };
memset(buffer, 0, MAX_TEXT_BUFFER_LENGTH);
@ -1752,8 +1750,8 @@ char *GetTextBetween(const char *text, const char *begin, const char *end)
{
endIndex += (beginIndex + beginLen);
int len = (endIndex - beginIndex - beginLen);
if (len < (MAX_TEXT_BETWEEN_SIZE - 1)) strncpy(buffer, text + beginIndex + beginLen, len);
else strncpy(buffer, text + beginIndex + beginLen, MAX_TEXT_BETWEEN_SIZE - 1);
if (len < (MAX_TEXT_BUFFER_LENGTH - 1)) strncpy(buffer, text + beginIndex + beginLen, len);
else strncpy(buffer, text + beginIndex + beginLen, MAX_TEXT_BUFFER_LENGTH - 1);
}
}
@ -1762,8 +1760,74 @@ char *GetTextBetween(const char *text, const char *begin, const char *end)
// Replace text string
// REQUIRES: strstr(), strncpy()
// WARNING: Allocated memory must be manually freed
// NOTE: Limited text replace functionality, using static string
char *TextReplace(const char *text, const char *search, const char *replacement)
{
static char result[MAX_TEXT_BUFFER_LENGTH] = { 0 };
memset(result, 0, MAX_TEXT_BUFFER_LENGTH);
if ((text != NULL) && (search != NULL) && (search[0] != '\0'))
{
if (replacement == NULL) replacement = "";
char *insertPoint = NULL; // Next insert point
char *tempPtr = NULL; // Temp pointer
int textLen = 0; // Text string length
int searchLen = 0; // Search string length of (the string to remove)
int replaceLen = 0; // Replacement length (the string to replace by)
int lastReplacePos = 0; // Distance between next search and end of last replace
int count = 0; // Number of replacements
textLen = TextLength(text);
searchLen = TextLength(search);
replaceLen = TextLength(replacement);
// Count the number of replacements needed
insertPoint = (char *)text;
for (count = 0; (tempPtr = strstr(insertPoint, search)); count++) insertPoint = tempPtr + searchLen;
if ((textLen + count*(replaceLen - searchLen)) < (MAX_TEXT_BUFFER_LENGTH - 1))
{
// TODO: Allow copying data replaced up to maximum buffer size and stop
tempPtr = result; // Point to result start
// First time through the loop, all the variable are set correctly from here on,
// - 'temp' points to the end of the result string
// - 'insertPoint' points to the next occurrence of replace in text
// - 'text' points to the remainder of text after "end of replace"
while (count > 0)
{
insertPoint = (char *)strstr(text, search);
lastReplacePos = (int)(insertPoint - text);
memcpy(tempPtr, text, lastReplacePos);
tempPtr += lastReplacePos;
if (replaceLen > 0)
{
memcpy(tempPtr, replacement, replaceLen);
tempPtr += replaceLen;
}
text += (lastReplacePos + searchLen); // Move to next "end of replace"
count--;
}
// Copy remaind text part after replacement to result (pointed by moving temp)
// NOTE: Text pointer internal copy has been updated along the process
strncpy(tempPtr, text, TextLength(text));
}
else TRACELOG(LOG_WARNING, "Text with replacement is longer than internal buffer, use TextReplaceAlloc()");
}
return result;
}
// Replace text string
// REQUIRES: strstr(), strncpy()
// WARNING: Allocated memory must be manually freed
char *TextReplaceAlloc(const char *text, const char *search, const char *replacement)
{
char *result = NULL;
@ -1825,11 +1889,46 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
return result;
}
// Replace text between two specific strings
// REQUIRES: strncpy()
// NOTE: If (replacement == NULL) removes "begin"[ ]"end" text
char *TextReplaceBetween(const char *text, const char *begin, const char *end, const char *replacement)
{
static char result[MAX_TEXT_BUFFER_LENGTH] = { 0 };
memset(result, 0, MAX_TEXT_BUFFER_LENGTH);
if ((text != NULL) && (begin != NULL) && (end != NULL))
{
int beginIndex = TextFindIndex(text, begin);
if (beginIndex > -1)
{
int beginLen = TextLength(begin);
int endIndex = TextFindIndex(text + beginIndex + beginLen, end);
if (endIndex > -1)
{
endIndex += (beginIndex + beginLen);
int textLen = TextLength(text);
int replaceLen = (replacement == NULL)? 0 : TextLength(replacement);
int toreplaceLen = endIndex - beginIndex - beginLen;
strncpy(result, text, beginIndex + beginLen); // Copy first text part
if (replacement != NULL) strncpy(result + beginIndex + beginLen, replacement, replaceLen); // Copy replacement (if provided)
strncpy(result + beginIndex + beginLen + replaceLen, text + endIndex, textLen - endIndex); // Copy end text part
}
}
}
return result;
}
// Replace text between two specific strings
// REQUIRES: strncpy()
// NOTE: If (replacement == NULL) remove "begin"[ ]"end" text
// WARNING: Returned string must be freed by user
char *TextReplaceBetween(const char *text, const char *begin, const char *end, const char *replacement)
char *TextReplaceBetweenAlloc(const char *text, const char *begin, const char *end, const char *replacement)
{
char *result = NULL;
@ -1864,6 +1963,34 @@ char *TextReplaceBetween(const char *text, const char *begin, const char *end, c
// Insert text in a specific position, moves all text forward
// WARNING: Allocated memory must be manually freed
char *TextInsert(const char *text, const char *insert, int position)
{
static char result[MAX_TEXT_BUFFER_LENGTH] = { 0 };
memset(result, 0, MAX_TEXT_BUFFER_LENGTH);
if ((text != NULL) && (insert != NULL))
{
int textLen = TextLength(text);
int insertLen = TextLength(insert);
if ((textLen + insertLen) < (MAX_TEXT_BUFFER_LENGTH - 1))
{
// TODO: Allow copying data inserted up to maximum buffer size and stop
for (int i = 0; i < position; i++) result[i] = text[i];
for (int i = position; i < insertLen + position; i++) result[i] = insert[i - position];
for (int i = (insertLen + position); i < (textLen + insertLen); i++) result[i] = text[i];
result[textLen + insertLen] = '\0'; // Add EOL
}
else TRACELOG(LOG_WARNING, "Text with inserted string is longer than internal buffer, use TextInserExt()");
}
return result;
}
// Insert text in a specific position, moves all text forward
// WARNING: Allocated memory must be manually freed
char *TextInsertAlloc(const char *text, const char *insert, int position)
{
char *result = NULL;