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