diff options
author | Christian Neukirchen <chneukirchen@gmail.com> | 2015-12-27 11:10:05 +0100 |
---|---|---|
committer | Christian Neukirchen <chneukirchen@gmail.com> | 2015-12-27 11:10:05 +0100 |
commit | 509d40303734a025c0ed6c0376d04d44594f0060 (patch) | |
tree | 1e4c3a5bdcf95ecdb9e8ffb3ed49d5ee67aa5c74 /lr.c | |
parent | a7de94a2b738477c32e084ab91fc5bf17ed6c01a (diff) | |
download | lr-509d40303734a025c0ed6c0376d04d44594f0060.tar.gz lr-509d40303734a025c0ed6c0376d04d44594f0060.tar.xz lr-509d40303734a025c0ed6c0376d04d44594f0060.zip |
add sorting by version
Diffstat (limited to 'lr.c')
-rw-r--r-- | lr.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/lr.c b/lr.c index bc91f8c..b815ddd 100644 --- a/lr.c +++ b/lr.c @@ -1040,9 +1040,42 @@ dircmp(char *a, char *b) return *a - *b; } +// taken straight from musl@a593414 +int mystrverscmp(const char *l0, const char *r0) +{ + const unsigned char *l = (const void *)l0; + const unsigned char *r = (const void *)r0; + size_t i, dp, j; + int z = 1; + + /* Find maximal matching prefix and track its maximal digit + * suffix and whether those digits are all zeros. */ + for (dp=i=0; l[i]==r[i]; i++) { + int c = l[i]; + if (!c) return 0; + if (!isdigit(c)) dp=i+1, z=1; + else if (c!='0') z=0; + } + + if (l[dp]!='0' && r[dp]!='0') { + /* If we're not looking at a digit sequence that began + * with a zero, longest digit string is greater. */ + for (j=i; isdigit(l[j]); j++) + if (!isdigit(r[j])) return 1; + if (isdigit(r[j])) return -1; + } else if (z && dp<i && (isdigit(l[i]) || isdigit(r[i]))) { + /* Otherwise, if common prefix of digit sequence is + * all zeros, digits order less than non-digits. */ + return (unsigned char)(l[i]-'0') - (unsigned char)(r[i]-'0'); + } + + return l[i] - r[i]; +} + #define CMP(a, b) if ((a) == (b)) break; else if ((a) < (b)) return -1; else return 1 #define STRCMP(a, b) if (strcmp(a, b) == 0) break; else return (strcmp(a, b)); #define DIRCMP(a, b) { int r = dircmp(a, b); if (r == 0) break; else return r; }; +#define VERCMP(a, b) if (mystrverscmp(a, b) == 0) break; else return (mystrverscmp(a, b)); int order(const void *a, const void *b) @@ -1076,6 +1109,8 @@ order(const void *a, const void *b) case 'E': STRCMP(extnam(fb->fpath), extnam(fa->fpath)); case 'p': DIRCMP(fa->fpath, fb->fpath); case 'P': DIRCMP(fb->fpath, fa->fpath); + case 'v': VERCMP(fa->fpath, fb->fpath); + case 'V': VERCMP(fb->fpath, fa->fpath); default: STRCMP(fa->fpath, fb->fpath); } } |