Sort non zero-padded numerical filename parts correctly.

This commit is contained in:
Michael Drake 2013-11-14 21:01:51 +00:00
parent 5e4e32923d
commit c933b0aff9
3 changed files with 50 additions and 1 deletions

View File

@ -508,7 +508,7 @@ static void fetch_file_process_dir(struct fetch_file_context *ctx,
int i; /* directory entry index */
int n; /* number of directory entries */
n = scandir(ctx->path, &listing, 0, alphasort);
n = scandir(ctx->path, &listing, 0, dir_sort_alpha);
if (n < 0) {
fetch_file_process_error(ctx,
fetch_file_errno_to_http_code(errno));

View File

@ -340,6 +340,41 @@ char *strndup(const char *s, size_t n)
#endif
/* Exported interface, documented in utils.c */
int dir_sort_alpha(const struct dirent **d1, const struct dirent **d2)
{
const char *s1 = (*d1)->d_name;
const char *s2 = (*d2)->d_name;
while (*s1 != '\0' && *s2 != '\0') {
if ((*s1 >= '0' && *s1 <= '9') &&
(*s2 >= '0' && *s2 <= '9')) {
int n1 = 0, n2 = 0;
while (*s1 >= '0' && *s1 <= '9') {
n1 = n1 * 10 + (*s1) - '0';
s1++;
}
while (*s2 >= '0' && *s2 <= '9') {
n2 = n2 * 10 + (*s2) - '0';
s2++;
}
if (n1 != n2) {
return n1 - n2;
}
if (*s1 == '\0' || *s2 == '\0')
break;
}
if (tolower(*s1) != tolower(*s2))
break;
s1++;
s2++;
}
return tolower(*s1) - tolower(*s2);
}
#ifndef HAVE_SCANDIR
int alphasort(const struct dirent **d1, const struct dirent **d2)
{

View File

@ -29,6 +29,8 @@
#include <regex.h>
#include <assert.h>
struct dirent;
#ifndef NOF_ELEMENTS
#define NOF_ELEMENTS(array) (sizeof(array)/sizeof(*(array)))
#endif
@ -157,6 +159,18 @@ char *human_friendly_bytesize(unsigned long bytesize);
const char *rfc1123_date(time_t t);
unsigned int wallclock(void);
/**
* Comparison function for sorting directories.
*
* Correctly orders non zero-padded numerical parts.
* ie. produces "file1, file2, file10" rather than "file1, file10, file2".
*
* d1 first directory entry
* d2 second directory entry
*/
int dir_sort_alpha(const struct dirent **d1, const struct dirent **d2);
/**
* Return a hex digit for the given numerical value.
*