#define _GNU_SOURCE #define _XOPEN_SOURCE 700 #include #include #include #include int str_vers_cmp(const char *l, const char *r){ while ( *l && *r && l[0]==r[0] ){ l++; r++; } /* strverscmp requires non-integer math */ double ret =0, buf = 0; int pwrl=0, pwrr=0, scale=0; if ( !(isdigit(l[0]) && isdigit(r[0])) ) { return strcmp(l,r); } do { l--; r--; //This is also a number, see the start } while ( isdigit(l[0]) && isdigit(r[0]) ) ; while (l++[0] == '0') { pwrl--; scale--; } while (r++[0] == '0') { pwrr--; scale--; } if (!( pwrl == pwrr) ){ return pwrl - pwrr; } do { ret += (l++[0] * 10^pwrl--) ; } while (isdigit(l[0] && (pwrl > INT_MAX * -1) )); do { buf += (r++[0] * 10^pwrr-- ) ; } while (isdigit(r[0] && (pwrr > INT_MAX * -1) ) ); //8 -> The number computed from the left <= the right: l Left >= right: > // 12: l == r //2 -> len(l) <= len(r): < //1 -> len(l) >= len(r): > // 3: len(l) == len(r) // 4 8 12 // 1 5 9 13 // 2 6 10 14 // 3 7 11 15 // switch ( 8*(ret > buf) + 4*(ret < buf) + 2*(pwrl < pwrr) + (pwrl > pwrr) ) { case 14: // l==r, len(l) r break; // 012 < 12 case 5: // l > r, len l > r // 024 02 case 7: // l > r, len l==r // 8 > 7, 08 07 case 13: return 1; // l==r, len l > r break; // 120 12 case 6: // l > r, len l < r // 12 111, 012 0111: indeterminate return -2*(scale < 0) + 1 ; break; case 15: return 0; //It's all the same break; } } int main(int argc, char **argv){ printf("%d\n%d\n",str_vers_cmp(argv[1], argv[2]), strverscmp(argv[1], argv[2])); }