Index: firmware/common/strnatcmp.c =================================================================== --- firmware/common/strnatcmp.c (revision 20345) +++ firmware/common/strnatcmp.c (working copy) @@ -29,9 +29,8 @@ * negative chars in their default char type. * * - * Changes for Rockbox: - * This version is changed slightly to deal better with the datatypes, - * it does not equal to the original software. + * This version is changed to ignore leading zeros, it does not equal to the + * original software. */ #include @@ -51,7 +50,6 @@ /* These are defined as macros to make it easier to adapt this code to * different characters types or comparison functions. */ - static inline int nat_isdigit(int a) { @@ -62,7 +60,7 @@ static inline int nat_isspace(int a) { - return isspace(a); + return a == '0' || isspace(a); } @@ -106,61 +104,71 @@ return 0; } - -static int -compare_left(char const *a, char const *b) -{ - /* Compare two left-aligned numbers: the first to have a - different value wins. */ - for (;; a++, b++) { - if (!nat_isdigit(*a) && !nat_isdigit(*b)) - return 0; - else if (!nat_isdigit(*a)) - return -1; - else if (!nat_isdigit(*b)) - return +1; - else if (*a < *b) - return -1; - else if (*a > *b) - return +1; - } - - return 0; -} - static int strnatcmp0(char const *a, char const *b, int fold_case) { int ai, bi; int ca, cb; - int fractional, result; + int result; + int lza, lzb, lzbias; assert(a && b); ai = bi = 0; + lzbias = 0; while (1) { - ca = to_int(a[ai]); + + /* count leading zeros */ + lza = lzb = 0; + + ca = to_int(a[ai]); cb = to_int(b[bi]); /* skip over leading spaces or zeros */ while (nat_isspace(ca)) + { + if ('0' == ca) + lza++; + else + lza = 0; + ca = to_int(a[++ai]); + } + + /* have zero */ + if (lza && !nat_isdigit(ca)) + { + ca = to_int(a[--ai]); + } while (nat_isspace(cb)) + { + if ('0' == cb) + lzb++; + else + lzb = 0; + cb = to_int(b[++bi]); + } + + /* have zero */ + if (lzb && !nat_isdigit(cb)) + { + cb = to_int(b[--bi]); + } /* process run of digits */ if (nat_isdigit(ca) && nat_isdigit(cb)) { - fractional = (ca == '0' || cb == '0'); - - if (fractional) { - if ((result = compare_left(a+ai, b+bi)) != 0) - return result; - } else { - if ((result = compare_right(a+ai, b+bi)) != 0) - return result; - } + if ((result = compare_right(a+ai, b+bi)) != 0) + return result; } + + if (lza != lzb && 0 == lzbias) + lzbias = lzb - lza; if (!ca && !cb) { + + if (0 != lzbias) + return lzbias; + /* The strings compare the same. Call str[case]cmp() to ensure consistent results. */ if(fold_case)