From 7046272ee449ddfa4d9be008e425250ab0d580e5 Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Debian Linux)" <rob@synchro.net>
Date: Wed, 20 Nov 2024 19:56:56 -0800
Subject: [PATCH] Add iniGet/ReadSectionListWithDupes()

For use cases were we don't want to silenty ignore duplicate (secondary)
section definitions.
---
 src/xpdev/ini_file.c | 28 ++++++++++++++++++++++++----
 src/xpdev/ini_file.h |  4 +++-
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/src/xpdev/ini_file.c b/src/xpdev/ini_file.c
index 0316088b6f..6c024da1a8 100644
--- a/src/xpdev/ini_file.c
+++ b/src/xpdev/ini_file.c
@@ -1263,7 +1263,7 @@ void* iniFreeNamedStringList(named_string_t** list)
 	return(NULL);
 }
 
-str_list_t iniReadSectionList(FILE* fp, const char* prefix)
+static str_list_t ini_read_section_list(FILE* fp, const char* prefix, bool include_dupes)
 {
 	char*	p;
 	char	str[INI_MAX_LINE_LEN];
@@ -1288,7 +1288,7 @@ str_list_t iniReadSectionList(FILE* fp, const char* prefix)
 		if(prefix!=NULL)
 			if(strnicmp(p,prefix,strlen(prefix))!=0)
 				continue;
-		if(strListFind(lp, p, /* case_sensitive */false) >= 0)
+		if(!include_dupes && strListFind(lp, p, /* case_sensitive */false) >= 0)
 			continue;
 		if(strListAppend(&lp,p,items++)==NULL)
 			break;
@@ -1297,7 +1297,17 @@ str_list_t iniReadSectionList(FILE* fp, const char* prefix)
 	return(lp);
 }
 
-str_list_t iniGetSectionList(str_list_t list, const char* prefix)
+str_list_t iniReadSectionList(FILE* fp, const char* prefix)
+{
+	return  ini_read_section_list(fp, prefix, /* include dupes: */false);
+}
+
+str_list_t iniReadSectionListWithDupes(FILE* fp, const char* prefix)
+{
+	return  ini_read_section_list(fp, prefix, /* include dupes: */true);
+}
+
+static str_list_t ini_get_section_list(str_list_t list, const char* prefix, bool include_dupes)
 {
 	char*	p;
 	char	str[INI_MAX_LINE_LEN];
@@ -1319,7 +1329,7 @@ str_list_t iniGetSectionList(str_list_t list, const char* prefix)
 		if(prefix!=NULL)
 			if(strnicmp(p,prefix,strlen(prefix))!=0)
 				continue;
-		if(strListFind(lp, p, /* case_sensitive */false) >= 0)
+		if(include_dupes && strListFind(lp, p, /* case_sensitive */false) >= 0)
 			continue;
 		if(strListAppend(&lp,p,items++)==NULL)
 			break;
@@ -1328,6 +1338,16 @@ str_list_t iniGetSectionList(str_list_t list, const char* prefix)
 	return(lp);
 }
 
+str_list_t iniGetSectionList(str_list_t list, const char* prefix)
+{
+	return ini_get_section_list(list, prefix, /* include_dupes: */false);
+}
+
+str_list_t iniGetSectionListWithDupes(str_list_t list, const char* prefix)
+{
+	return ini_get_section_list(list, prefix, /* include_dupes: */true);
+}
+
 size_t iniGetSectionCount(str_list_t list, const char* prefix)
 {
 	char*	p;
diff --git a/src/xpdev/ini_file.h b/src/xpdev/ini_file.h
index c5cb7b6bb8..a1f71b3dbf 100644
--- a/src/xpdev/ini_file.h
+++ b/src/xpdev/ini_file.h
@@ -52,6 +52,7 @@ extern "C" {
 /* Read all section names and return as an allocated string list */
 /* Optionally (if prefix!=NULL), returns a subset of section names */
 DLLEXPORT str_list_t 	iniReadSectionList(FILE*, const char* prefix);
+DLLEXPORT str_list_t 	iniReadSectionListWithDupes(FILE*, const char* prefix);
 /* Returns number (count) of sections */
 DLLEXPORT size_t 		iniReadSectionCount(FILE*, const char* prefix);
 /* Read all key names and return as an allocated string list */
@@ -137,9 +138,10 @@ DLLEXPORT bool 			iniCloseFile(FILE*);
 
 /* StringList functions */
 DLLEXPORT str_list_t 	iniGetSectionList(str_list_t list, const char* prefix);
+DLLEXPORT str_list_t 	iniGetSectionListWithDupes(str_list_t list, const char* prefix);
 DLLEXPORT size_t 		iniGetSectionCount(str_list_t list, const char* prefix);
 DLLEXPORT str_list_t 	iniGetKeyList(str_list_t list, const char* section);
-DLLEXPORT named_string_t** 
+DLLEXPORT named_string_t**
 						iniGetNamedStringList(str_list_t list, const char* section);
 
 /* Return the unparsed value (string literals not supported): */
-- 
GitLab