Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort playlists ignoring extension. #15836

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions libretro-common/include/lists/dir_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ bool dir_list_initialize(struct string_list *list,
**/
void dir_list_sort(struct string_list *list, bool dir_first);

/**
* dir_list_sort_ignore_ext:
* @list : pointer to the directory listing.
* @dir_first : move the directories in the listing to the top?
*
* Sorts a directory listing. File extensions are ignored.
**/
void dir_list_sort_ignore_ext(struct string_list *list, bool dir_first);

/**
* dir_list_free:
* @list : pointer to the directory listing
Expand Down
43 changes: 43 additions & 0 deletions libretro-common/lists/dir_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ static int qstrcmp_plain(const void *a_, const void *b_)
return strcasecmp(a->data, b->data);
}

static int qstrcmp_plain_noext(const void *a_, const void *b_)
{
const struct string_list_elem *a = (const struct string_list_elem*)a_;
const struct string_list_elem *b = (const struct string_list_elem*)b_;

const char *ext_a = path_get_extension(a->data);
size_t l_a = string_is_empty(ext_a) ? strlen(a->data) : (ext_a - a->data - 1);
const char *ext_b = path_get_extension(b->data);
size_t l_b = string_is_empty(ext_b) ? strlen(b->data) : (ext_b - b->data - 1);

int rv = strncasecmp(a->data, b->data, MIN(l_a, l_b));
if (rv == 0 && l_a != l_b)
return (int)(l_a - l_b);
return rv;
}

static int qstrcmp_dir(const void *a_, const void *b_)
{
const struct string_list_elem *a = (const struct string_list_elem*)a_;
Expand All @@ -59,6 +75,19 @@ static int qstrcmp_dir(const void *a_, const void *b_)
return strcasecmp(a->data, b->data);
}

static int qstrcmp_dir_noext(const void *a_, const void *b_)
{
const struct string_list_elem *a = (const struct string_list_elem*)a_;
const struct string_list_elem *b = (const struct string_list_elem*)b_;
int a_type = a->attr.i;
int b_type = b->attr.i;

/* Sort directories before files. */
if (a_type != b_type)
return b_type - a_type;
return qstrcmp_plain_noext(a, b);
}

/**
* dir_list_sort:
* @list : pointer to the directory listing.
Expand All @@ -73,6 +102,20 @@ void dir_list_sort(struct string_list *list, bool dir_first)
dir_first ? qstrcmp_dir : qstrcmp_plain);
}

/**
* dir_list_sort_ignore_ext:
* @list : pointer to the directory listing.
* @dir_first : move the directories in the listing to the top?
*
* Sorts a directory listing. File extensions are ignored.
**/
void dir_list_sort_ignore_ext(struct string_list *list, bool dir_first)
{
if (list)
qsort(list->elems, list->size, sizeof(struct string_list_elem),
dir_first ? qstrcmp_dir_noext : qstrcmp_plain_noext);
}

/**
* dir_list_free:
* @list : pointer to the directory listing
Expand Down
2 changes: 1 addition & 1 deletion menu/menu_displaylist.c
Original file line number Diff line number Diff line change
Expand Up @@ -4152,7 +4152,7 @@ static unsigned menu_displaylist_parse_playlists(

content_count = count;

dir_list_sort(&str_list, true);
dir_list_sort_ignore_ext(&str_list, true);

list_size = str_list.size;

Expand Down
Loading