OLD | NEW |
1 #define _GNU_SOURCE | 1 #define _GNU_SOURCE |
2 #include <ctype.h> | 2 #include <ctype.h> |
3 #include <string.h> | 3 #include <string.h> |
4 | 4 |
5 int strverscmp(const char *l0, const char *r0) | 5 int strverscmp(const char* l0, const char* r0) { |
6 { | 6 const unsigned char* l = (const void*)l0; |
7 » const unsigned char *l = (const void *)l0; | 7 const unsigned char* r = (const void*)r0; |
8 » const unsigned char *r = (const void *)r0; | 8 size_t i, dp, j; |
9 » size_t i, dp, j; | 9 int z = 1; |
10 » int z = 1; | |
11 | 10 |
12 » /* Find maximal matching prefix and track its maximal digit | 11 /* Find maximal matching prefix and track its maximal digit |
13 » * suffix and whether those digits are all zeros. */ | 12 * suffix and whether those digits are all zeros. */ |
14 » for (dp=i=0; l[i]==r[i]; i++) { | 13 for (dp = i = 0; l[i] == r[i]; i++) { |
15 » » int c = l[i]; | 14 int c = l[i]; |
16 » » if (!c) return 0; | 15 if (!c) |
17 » » if (!isdigit(c)) dp=i+1, z=1; | 16 return 0; |
18 » » else if (c!='0') z=0; | 17 if (!isdigit(c)) |
19 » } | 18 dp = i + 1, z = 1; |
| 19 else if (c != '0') |
| 20 z = 0; |
| 21 } |
20 | 22 |
21 » if (l[dp]!='0' && r[dp]!='0') { | 23 if (l[dp] != '0' && r[dp] != '0') { |
22 » » /* If we're not looking at a digit sequence that began | 24 /* If we're not looking at a digit sequence that began |
23 » » * with a zero, longest digit string is greater. */ | 25 * with a zero, longest digit string is greater. */ |
24 » » for (j=i; isdigit(l[j]); j++) | 26 for (j = i; isdigit(l[j]); j++) |
25 » » » if (!isdigit(r[j])) return 1; | 27 if (!isdigit(r[j])) |
26 » » if (isdigit(r[j])) return -1; | 28 return 1; |
27 » } else if (z && dp<i && (isdigit(l[i]) || isdigit(r[i]))) { | 29 if (isdigit(r[j])) |
28 » » /* Otherwise, if common prefix of digit sequence is | 30 return -1; |
29 » » * all zeros, digits order less than non-digits. */ | 31 } else if (z && dp < i && (isdigit(l[i]) || isdigit(r[i]))) { |
30 » » return (unsigned char)(l[i]-'0') - (unsigned char)(r[i]-'0'); | 32 /* Otherwise, if common prefix of digit sequence is |
31 » } | 33 * all zeros, digits order less than non-digits. */ |
| 34 return (unsigned char)(l[i] - '0') - (unsigned char)(r[i] - '0'); |
| 35 } |
32 | 36 |
33 » return l[i] - r[i]; | 37 return l[i] - r[i]; |
34 } | 38 } |
OLD | NEW |