From 3d277e5a181f7f362cbd1d627c050e771e907c2b Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Windows 11)" <rob@synchro.net>
Date: Fri, 1 Nov 2024 23:38:39 -0700
Subject: [PATCH] strListFastRemove() and strListFastDelete() now take a count
 argument

... if you're deleting more than one string, this is much more efficient.

Note we do some pointer compares (in strListFastRemove) *after* we've freed
them in strListFastDelete(). I don't suspect this to be an issue, but it does
seem suspect.
---
 src/xpdev/ini_file.c |  2 +-
 src/xpdev/str_list.c | 38 +++++++++++++++++++-------------------
 src/xpdev/str_list.h |  4 ++--
 3 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/xpdev/ini_file.c b/src/xpdev/ini_file.c
index 7e5d5a9a0e..0316088b6f 100644
--- a/src/xpdev/ini_file.c
+++ b/src/xpdev/ini_file.c
@@ -453,7 +453,7 @@ bool iniRemoveSectionFast(str_list_t list, const char* section)
 	if(list[i]==NULL)	/* not found */
 		return(false);
 	do {
-		strListFastDelete(list,i);
+		strListFastDelete(list,i, /* count: */1);
 	} while(list[i]!=NULL && *list[i]!=INI_OPEN_SECTION_CHAR);
 
 	return(true);
diff --git a/src/xpdev/str_list.c b/src/xpdev/str_list.c
index dcb92dc28d..d28aa297ea 100644
--- a/src/xpdev/str_list.c
+++ b/src/xpdev/str_list.c
@@ -152,25 +152,23 @@ char* strListRemove(str_list_t* list, size_t index)
 }
 
 // Remove without realloc
-char* strListFastRemove(str_list_t list, size_t index)
+bool strListFastRemove(str_list_t list, size_t index, size_t count)
 {
-	char*	str;
 	size_t	i;
-	size_t	count;
+	size_t	total;
 
-	count = strListCount(list);
+	total = strListCount(list);
 
-	if(index == STR_LIST_LAST_INDEX && count)
-		index = count-1;
+	if(index == STR_LIST_LAST_INDEX && total)
+		index = total-1;
 
-	if(index >= count)	/* invalid index, do nothing */
-		return NULL;
+	if(index + count > total)	/* invalid index, do nothing */
+		return false;
 
-	str = list[index];
-	for(i = index; i < count; i++)
-		list[i] = list[i + 1];
+	for(i = index; i <= total - count; ++i)
+		list[i] = list[i + count];
 
-	return str;
+	return true;
 }
 
 bool strListDelete(str_list_t* list, size_t index)
@@ -185,16 +183,18 @@ bool strListDelete(str_list_t* list, size_t index)
 	return(true);
 }
 
-bool strListFastDelete(str_list_t list, size_t index)
+bool strListFastDelete(str_list_t list, size_t index, size_t count)
 {
-	char*	str;
+	size_t	i;
 
-	if((str=strListFastRemove(list, index))==NULL)
-		return(false);
+	for(i = 0; i < count; ++i)
+		if(list[index + i] == NULL)
+			return false;
 
-	free(str);
+	for(i = 0; i < count; ++i)
+		free(list[index + i]);
 
-	return(true);
+	return strListFastRemove(list, index, count);
 }
 
 char* strListReplace(const str_list_t list, size_t index, const char* str)
@@ -917,7 +917,7 @@ int strListFastDeleteBlanks(str_list_t list)
 
 	for(i = 0; list[i] != NULL; ) {
 		if(list[i][0] == '\0')
-			strListFastDelete(list, i);
+			strListFastDelete(list, i, /* count: */1);
 		else
 			i++;
 	}
diff --git a/src/xpdev/str_list.h b/src/xpdev/str_list.h
index 7baee4c9bc..f601cc8245 100644
--- a/src/xpdev/str_list.h
+++ b/src/xpdev/str_list.h
@@ -73,11 +73,11 @@ DLLEXPORT char*			strListInsertFormat(str_list_t* list, size_t index, const char
 
 /* Remove a string at a specific index */
 DLLEXPORT char*			strListRemove(str_list_t*, size_t index);
-DLLEXPORT char*			strListFastRemove(str_list_t, size_t index);
+DLLEXPORT bool			strListFastRemove(str_list_t, size_t index, size_t count);
 
 /* Remove and free a string at a specific index */
 DLLEXPORT bool			strListDelete(str_list_t*, size_t index);
-DLLEXPORT bool			strListFastDelete(str_list_t, size_t index);
+DLLEXPORT bool			strListFastDelete(str_list_t, size_t index, size_t count);
 
 /* Replace a string at a specific index */
 DLLEXPORT char*			strListReplace(const str_list_t, size_t index, const char* str);
-- 
GitLab