diff options
Diffstat (limited to 'firmware/common')
-rw-r--r-- | firmware/common/strnatcmp.c | 40 |
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 | |||
53 | static inline int | 54 | static inline int |
54 | nat_isdigit(int a) | 55 | nat_isdigit(int a) |
55 | { | 56 | { |
@@ -60,7 +61,7 @@ nat_isdigit(int a) | |||
60 | static inline int | 61 | static inline int |
61 | nat_isspace(int a) | 62 | nat_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 | |||
109 | static int | ||
110 | compare_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 | |||
107 | static int strnatcmp0(char const *a, char const *b, int fold_case) | 130 | static 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) { |