summaryrefslogtreecommitdiff
path: root/firmware/common
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/common')
-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) {