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