diff --git a/include/vlc_strings.h b/include/vlc_strings.h index 1bbb82fa74..9828fbd728 100644 --- a/include/vlc_strings.h +++ b/include/vlc_strings.h @@ -148,6 +148,8 @@ static inline char *str_format( input_thread_t *input, const char *fmt ) return s2; } +VLC_API int vlc_filenamecmp(const char *, const char *); + void filename_sanitize(char *); /** diff --git a/src/input/access.c b/src/input/access.c index e32ec81abd..6852ade7d9 100644 --- a/src/input/access.c +++ b/src/input/access.c @@ -29,14 +29,12 @@ #include #include #include -#ifndef HAVE_STRCOLL -# define strcoll strcasecmp -#endif #include #include #include #include +#include #include #include "stream.h" @@ -343,37 +341,7 @@ static int compar_filename(const void *a, const void *b) if (i_ret != 0) return i_ret; - size_t i; - char ca, cb; - - /* Attempt to guess if the sorting algorithm should be alphabetic - * (i.e. collation) or numeric: - * - If the first mismatching characters are not both digits, - * then collation is the only option. - * - If one of the first mismatching characters is 0 and the other is also - * a digit, the comparands are probably left-padded numerical values. - * It does not matter which algorithm is used: the zero will be smaller - * than non-zero either way. - * - Otherwise, the comparands are numerical values, and might not be - * aligned (i.e. not same order of magnitude). If so, collation would - * fail. So numerical comparison is performed. */ - for (i = 0; (ca = ia->psz_name[i]) == (cb = ib->psz_name[i]); i++) - if (ca == '\0') - return 0; /* strings are exactly identical */ - - if ((unsigned)(ca - '0') > 9 || (unsigned)(cb - '0') > 9) - return strcoll(ia->psz_name, ib->psz_name); - - unsigned long long ua = strtoull(ia->psz_name + i, NULL, 10); - unsigned long long ub = strtoull(ib->psz_name + i, NULL, 10); - - /* The number may be identical in two cases: - * - leading zero (e.g. "012" and "12") - * - overflow on both sides (#ULLONG_MAX) */ - if (ua == ub) - return strcoll(ia->psz_name, ib->psz_name); - - return (ua > ub) ? +1 : -1; + return vlc_filenamecmp(ia->psz_name, ib->psz_name); } static void fsdir_sort(input_item_node_t *p_node) diff --git a/src/libvlccore.sym b/src/libvlccore.sym index d8649afe1b..8d9bb53d3c 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -563,6 +563,7 @@ vlc_CPU vlc_error vlc_event_attach vlc_event_detach +vlc_filenamecmp vlc_fourcc_GetCodec vlc_fourcc_GetCodecAudio vlc_fourcc_GetCodecFromString diff --git a/src/text/strings.c b/src/text/strings.c index ec68de3fc2..eae4461006 100644 --- a/src/text/strings.c +++ b/src/text/strings.c @@ -38,6 +38,10 @@ #include #include #include +#include +#ifndef HAVE_STRCOLL +# define strcoll strcasecmp +#endif /* Needed by vlc_strfinput */ #include @@ -817,6 +821,41 @@ char *vlc_strfinput(input_thread_t *input, const char *s) return stream->ptr; } +int vlc_filenamecmp(const char *a, const char *b) +{ + size_t i; + char ca, cb; + + /* Attempt to guess if the sorting algorithm should be alphabetic + * (i.e. collation) or numeric: + * - If the first mismatching characters are not both digits, + * then collation is the only option. + * - If one of the first mismatching characters is 0 and the other is also + * a digit, the comparands are probably left-padded numerical values. + * It does not matter which algorithm is used: the zero will be smaller + * than non-zero either way. + * - Otherwise, the comparands are numerical values, and might not be + * aligned (i.e. not same order of magnitude). If so, collation would + * fail. So numerical comparison is performed. */ + for (i = 0; (ca = a[i]) == (cb = b[i]); i++) + if (ca == '\0') + return 0; /* strings are exactly identical */ + + if ((unsigned)(ca - '0') > 9 || (unsigned)(cb - '0') > 9) + return strcoll(a, b); + + unsigned long long ua = strtoull(a + i, NULL, 10); + unsigned long long ub = strtoull(b + i, NULL, 10); + + /* The number may be identical in two cases: + * - leading zero (e.g. "012" and "12") + * - overflow on both sides (#ULLONG_MAX) */ + if (ua == ub) + return strcoll(a, b); + + return (ua > ub) ? +1 : -1; +} + /** * Sanitize a file name. *