summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2009-03-17 18:58:47 +0000
committerThomas Martitz <kugel@rockbox.org>2009-03-17 18:58:47 +0000
commitfa2d011a551a8f1887b2db5ac156d30421066192 (patch)
treee484acc898e9d34e882e03792966414341ed0877
parent997005ece0b8b1d901a18c8d16d28ac4ad92521d (diff)
downloadrockbox-fa2d011a551a8f1887b2db5ac156d30421066192.tar.gz
rockbox-fa2d011a551a8f1887b2db5ac156d30421066192.zip
Restore behavior of the original implementation strnatcmp to not ignore leading zeros. Fixes FS#10029 (Files being sorted incorrectly in latest builds), leads to better sorting of decimal numbers. It also doesn't sort 2 before 03 (but still before 10) anymore.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20340 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/common/strnatcmp.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/firmware/common/strnatcmp.c b/firmware/common/strnatcmp.c
index d7ac60414f..96c2250f3a 100644
--- a/firmware/common/strnatcmp.c
+++ b/firmware/common/strnatcmp.c
@@ -50,6 +50,7 @@ to_int(char c)
50 50
51/* These are defined as macros to make it easier to adapt this code to 51/* These are defined as macros to make it easier to adapt this code to
52 * different characters types or comparison functions. */ 52 * different characters types or comparison functions. */
53
53static inline int 54static inline int
54nat_isdigit(int a) 55nat_isdigit(int a)
55{ 56{
@@ -60,7 +61,7 @@ nat_isdigit(int a)
60static inline int 61static inline int
61nat_isspace(int a) 62nat_isspace(int a)
62{ 63{
63 return a == '0' || isspace(a); 64 return isspace(a);
64} 65}
65 66
66 67
@@ -104,16 +105,38 @@ compare_right(char const *a, char const *b)
104 return 0; 105 return 0;
105} 106}
106 107
108
109static int
110compare_left(char const *a, char const *b)
111{
112 /* Compare two left-aligned numbers: the first to have a
113 different value wins. */
114 for (;; a++, b++) {
115 if (!nat_isdigit(*a) && !nat_isdigit(*b))
116 return 0;
117 else if (!nat_isdigit(*a))
118 return -1;
119 else if (!nat_isdigit(*b))
120 return +1;
121 else if (*a < *b)
122 return -1;
123 else if (*a > *b)
124 return +1;
125 }
126
127 return 0;
128}
129
107static int strnatcmp0(char const *a, char const *b, int fold_case) 130static int strnatcmp0(char const *a, char const *b, int fold_case)
108{ 131{
109 int ai, bi; 132 int ai, bi;
110 int ca, cb; 133 int ca, cb;
111 int result; 134 int fractional, result;
112 135
113 assert(a && b); 136 assert(a && b);
114 ai = bi = 0; 137 ai = bi = 0;
115 while (1) { 138 while (1) {
116 ca = to_int(a[ai]); 139 ca = to_int(a[ai]);
117 cb = to_int(b[bi]); 140 cb = to_int(b[bi]);
118 141
119 /* skip over leading spaces or zeros */ 142 /* skip over leading spaces or zeros */
@@ -125,8 +148,15 @@ static int strnatcmp0(char const *a, char const *b, int fold_case)
125 148
126 /* process run of digits */ 149 /* process run of digits */
127 if (nat_isdigit(ca) && nat_isdigit(cb)) { 150 if (nat_isdigit(ca) && nat_isdigit(cb)) {
128 if ((result = compare_right(a+ai, b+bi)) != 0) 151 fractional = (ca == '0' || cb == '0');
129 return result; 152
153 if (fractional) {
154 if ((result = compare_left(a+ai, b+bi)) != 0)
155 return result;
156 } else {
157 if ((result = compare_right(a+ai, b+bi)) != 0)
158 return result;
159 }
130 } 160 }
131 161
132 if (!ca && !cb) { 162 if (!ca && !cb) {