(libretro-common) string_list - add string_list_initialize

and string_list_deinitialize - takes a pointer to initialize
and deinitialize a string list, but importantly does not
implicitly allocate and deallocate the string list pointer
itself. This way, string lists can be put on the stack instead
of always implicitly being put on heap - the struct itself is
small enough to fit on stack
This commit is contained in:
twinaphex 2020-08-24 00:43:55 +02:00
parent 6b3fcf79f0
commit cd6e1cf3fa
3 changed files with 73 additions and 30 deletions

View File

@ -101,6 +101,10 @@ struct string_list *string_split(const char *str, const char *delim);
*/
struct string_list *string_separate(char *str, const char *delim);
bool string_list_deinitialize(struct string_list *list);
bool string_list_initialize(struct string_list *list);
/**
* string_list_new:
*

View File

@ -29,20 +29,14 @@
#include <compat/posix_string.h>
#include <string/stdstring.h>
/**
* string_list_free
* @list : pointer to string list object
*
* Frees a string list.
*/
void string_list_free(struct string_list *list)
static bool string_list_deinitialize_internal(struct string_list *list)
{
size_t i;
if (!list)
return;
return false;
if (list->elems)
{
unsigned i;
for (i = 0; i < list->size; i++)
{
if (list->elems[i].data)
@ -57,7 +51,8 @@ void string_list_free(struct string_list *list)
}
list->elems = NULL;
free(list);
return true;
}
/**
@ -85,6 +80,38 @@ static bool string_list_capacity(struct string_list *list, size_t cap)
return true;
}
static bool string_list_initialize_internal(struct string_list *list)
{
list->elems = NULL;
list->size = 0;
list->cap = 0;
return string_list_capacity(list, 32);
}
/**
* string_list_free
* @list : pointer to string list object
*
* Frees a string list.
*/
void string_list_free(struct string_list *list)
{
if (!list)
return;
string_list_deinitialize_internal(list);
free(list);
}
bool string_list_deinitialize(struct string_list *list)
{
if (!list)
return false;
return string_list_deinitialize_internal(list);
}
/**
* string_list_new:
*
@ -100,11 +127,7 @@ struct string_list *string_list_new(void)
if (!list)
return NULL;
list->elems = NULL;
list->size = 0;
list->cap = 0;
if (!string_list_capacity(list, 32))
if (!string_list_initialize_internal(list))
{
string_list_free(list);
return NULL;
@ -113,6 +136,18 @@ struct string_list *string_list_new(void)
return list;
}
bool string_list_initialize(struct string_list *list)
{
if (!list)
return false;
if (!string_list_initialize_internal(list))
{
string_list_free(list);
return false;
}
return true;
}
/**
* string_list_append:
* @list : pointer to string list

View File

@ -1225,12 +1225,15 @@ static bool content_file_init(
if (info)
{
unsigned i;
struct string_list *additional_path_allocs = string_list_new();
ret = content_file_load(info, p_content,
content, content_ctx, error_string,
special, additional_path_allocs);
string_list_free(additional_path_allocs);
struct string_list additional_path_allocs;
if (string_list_initialize(&additional_path_allocs))
{
ret = content_file_load(info, p_content,
content, content_ctx, error_string,
special, &additional_path_allocs);
string_list_deinitialize(&additional_path_allocs);
}
for (i = 0; i < content->size; i++)
free((void*)info[i].data);
@ -2485,12 +2488,12 @@ void content_set_subsystem_info(void)
* selected libretro core. */
bool content_init(void)
{
struct string_list content;
content_information_ctx_t content_ctx;
content_state_t *p_content = content_state_get_ptr();
bool ret = true;
char *error_string = NULL;
struct string_list *content = NULL;
global_t *global = global_get_ptr();
rarch_system_info_t *sys_info = runloop_get_system_info();
settings_t *settings = config_get_ptr();
@ -2553,19 +2556,20 @@ bool content_init(void)
}
p_content->is_inited = true;
content = string_list_new();
if ( !p_content->temporary_content
|| !content_file_init(&content_ctx, p_content,
content, &error_string))
if (string_list_initialize(&content))
{
content_deinit();
if ( !p_content->temporary_content
|| !content_file_init(&content_ctx, p_content,
&content, &error_string))
{
content_deinit();
ret = false;
ret = false;
}
string_list_deinitialize(&content);
}
string_list_free(content);
if (content_ctx.name_ips)
free(content_ctx.name_ips);
if (content_ctx.name_bps)