sorry if this is not the right mail address, but i didn't find any other apart from sort author private mail.
lately i found myself in need of sorting a file on version numbers, like
1.0.1 or 1.12-27. i patched sort to use the same algorithm used by
debian's dpkg and it worked for me. yes, i know that version number
sorting is quite arbitrary but an half working algorithm is better than
nothing. patch is attached.
thank you very much for your time,
federico
--
Federico Di Gregorio
Debian GNU/Linux Developer & Italian Press Contact [EMAIL PROTECTED]
INIT.D Developer [EMAIL PROTECTED]
Don't dream it. Be it. -- Dr. Frank'n'further
80a81
> #define MAXVERSIONLENGTH 32
152a154
> int version; /* use dpkg-live version sorting */
177a180,183
> /* Translation table from ASCII values to collate values for the dpkg-like
> version sorting. */
> static int versiontab[256];
>
276a283
> -v compare according to dpkg-live version ordering\n\
499a507,514
> for (i=0; i<256; i++) versiontab[i] = 0;
> for (i='a'; i<='z'; i++) versiontab[i] = i;
> for (i='A'; i<='Z'; i++) versiontab[i] = i;
> versiontab['+'] = 256 + '+';
> versiontab['-'] = 256 + '-';
> versiontab['.'] = 256 + '.';
> versiontab[':'] = 256 + ':';
>
1083a1099,1162
> /* Compare strings A and B as dpkg-like versions */
>
> static char *
> _versioncompare_part (char *s, char *save, int max, int alpha)
> {
> int i;
>
> /* if *s is NUL, return NULL to signal end-of-string */
> if (!s || *s == '\0' || ISSPACE(*s)) return NULL;
>
> for (i=0; i<max ; i++) {
> if (*s && ((alpha && versiontab[(unsigned int)*s] > 0)
> || (!alpha && ISDIGIT(*s)))) {
> s++;
> }
> else {
> break;
> }
> }
> *save = *s;
> *s = '\0';
> return s;
> }
>
> static int
> versioncompare (register char *a, register char *b)
> {
> int res = 0, alpha = 0;
> char sa, sb, *pa, *pb;
>
> while (*a || *b) {
> pa = a; pb = b;
> a = _versioncompare_part(a, &sa, MAXVERSIONLENGTH, alpha);
> b = _versioncompare_part(b, &sb, MAXVERSIONLENGTH, alpha);
> if (a && b) {
> if (alpha) {
> while (*pa && *pb
> && versiontab[(unsigned int)*pa] > 0
> && versiontab[(unsigned int)*pb] > 0) {
> if (*pa != *pb) break;
> pa++; pb++;
> }
> res = versiontab[(unsigned int)*pb] - versiontab[(unsigned int)*pa];
> }
> else {
> res = atoi(pb) - atoi(pa);
> }
>
> }
> else if (a) res = -1;
> else if (b) res = 1;
> else res = 1000; /* very dirty trick */
>
> if (a) *a = sa;
> if (b) *b = sb;
>
> if (res != 0) return (res == 1000 ? 0 : -res);
>
> alpha = (alpha-1)*-1;
> }
>
> return -res;
> }
>
1151c1230
< if (key->numeric | key->general_numeric)
---
> if (key->numeric | key->general_numeric | key->version)
1167,1168c1246,1250
< diff = ((key->numeric ? numcompare : general_numcompare)
< (texta, textb));
---
> if (key->version)
> diff = versioncompare (texta, textb);
> else
> diff = ((key->numeric ? numcompare : general_numcompare)
> (texta, textb));
1874a1957,1959
> case 'v':
> key->version = 1;
> break;
1983a2069
> gkey.version = 0;
2242c2328
< && !key->skipeblanks && !key->month && !key->numeric
---
> && !key->skipeblanks && !key->month && !key->numeric && !key->version
2250a2337
> key->version = gkey.version;
2257c2344
< || gkey.general_numeric))
---
> || gkey.version || gkey.general_numeric))
signature.asc
Description: PGP signature
