This works for me :) Either ``-V'' or ``--compare-version'' will trigger the use of strverscmp in lieu of memcmp as the comparison function.
--- coreutils-6.10-ori/src/sort.c 2007-11-25 05:23:31.000000000 -0800 +++ coreutils-6.10/src/sort.c 2008-01-31 07:55:10.000000000 -0800 @@ -172,6 +172,7 @@ struct keyfield Handle numbers in exponential notation. */ bool month; /* Flag for comparison by month name. */ bool reverse; /* Reverse the sense of comparison. */ + bool version; /* Version number comparison. */ struct keyfield *next; /* Next keyfield to try. */ }; @@ -353,6 +354,7 @@ Other options:\n\ multiple options specify multiple directories\n\ -u, --unique with -c, check for strict ordering;\n\ without -c, output only the first of an equal run\n\ + -V, --compare-version compare embedded numbers as version numbers\n\ "), DEFAULT_TMPDIR); fputs (_("\ -z, --zero-terminated end lines with 0 byte, not newline\n\ @@ -394,7 +396,7 @@ enum RANDOM_SOURCE_OPTION }; -static char const short_options[] = "-bcCdfgik:mMno:rRsS:t:T:uy:z"; +static char const short_options[] = "-bcCdfgik:mMno:rRsS:t:T:uVy:z"; static struct option const long_options[] = { @@ -418,6 +420,7 @@ static struct option const long_options[ {"field-separator", required_argument, NULL, 't'}, {"temporary-directory", required_argument, NULL, 'T'}, {"unique", no_argument, NULL, 'u'}, + {"compare-version", no_argument, NULL, 'V'}, {"zero-terminated", no_argument, NULL, 'z'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, @@ -1543,6 +1546,26 @@ general_numcompare (const char *sa, cons : memcmp ((char *) &a, (char *) &b, sizeof a)); } +/* Compare the keys TEXTA (of length LENA) and TEXTB (of length LENB) + using strverscmp. */ + +static int +compare_version (char *restrict texta, size_t lena, + char *restrict textb, size_t lenb) +{ + int diff; + char sv_a = texta[lena]; + char sv_b = textb[lenb]; + + texta[lena] = textb[lenb] = '\0'; + diff = strverscmp (texta, textb); + + texta[lena] = sv_a; + textb[lenb] = sv_b; + + return diff; +} + /* Return an integer in 1..12 of the month name MONTH with length LEN. Return 0 if the name in S is not recognized. */ @@ -1741,8 +1764,13 @@ keycompare (const struct line *a, const (texta, textb)); *lima = savea, *limb = saveb; } + + else if (key->version) + diff = compare_version (texta, lena, textb, lenb); + else if (key->month) diff = getmonth (texta, lena) - getmonth (textb, lenb); + /* Sorting like this may become slow, so in a simple locale the user can select a faster sort that is similar to ascii sort. */ else if (hard_LC_COLLATE) @@ -2587,10 +2615,10 @@ check_ordering_compatibility (void) for (key = keylist; key; key = key->next) if ((1 < (key->random + key->numeric + key->general_numeric + key->month - + !!key->ignore)) + + key->version + !!key->ignore)) || (key->random && key->translate)) { - char opts[7]; + char opts[sizeof short_options]; char *p = opts; if (key->ignore == nondictionary) *p++ = 'd'; @@ -2604,6 +2632,8 @@ check_ordering_compatibility (void) *p++ = 'M'; if (key->numeric) *p++ = 'n'; + if (key->version) + *p++ = 'V'; if (key->random) *p++ = 'R'; *p = '\0'; @@ -2705,6 +2735,9 @@ set_ordering (const char *s, struct keyf case 'r': key->reverse = true; break; + case 'V': + key->version = true; + break; default: return (char *) s; } @@ -2830,7 +2863,7 @@ main (int argc, char **argv) gkey.sword = gkey.eword = SIZE_MAX; gkey.ignore = NULL; gkey.translate = NULL; - gkey.numeric = gkey.general_numeric = gkey.random = false; + gkey.numeric = gkey.general_numeric = gkey.random = gkey.version = false; gkey.month = gkey.reverse = false; gkey.skipsblanks = gkey.skipeblanks = false; @@ -2911,6 +2944,7 @@ main (int argc, char **argv) case 'n': case 'r': case 'R': + case 'V': { char str[2]; str[0] = c; @@ -3084,9 +3118,14 @@ main (int argc, char **argv) /* Inheritance of global options to individual keys. */ for (key = keylist; key; key = key->next) { - if (! (key->ignore || key->translate - || (key->skipsblanks | key->reverse - | key->skipeblanks | key->month | key->numeric + if (! (key->ignore + || key->translate + || (key->skipsblanks + | key->reverse + | key->skipeblanks + | key->month + | key->numeric + | key->version | key->general_numeric | key->random))) { @@ -3099,6 +3138,7 @@ main (int argc, char **argv) key->general_numeric = gkey.general_numeric; key->random = gkey.random; key->reverse = gkey.reverse; + key->version = gkey.version; } need_random |= key->random; @@ -3107,7 +3147,7 @@ main (int argc, char **argv) if (!keylist && (gkey.ignore || gkey.translate || (gkey.skipsblanks | gkey.skipeblanks | gkey.month | gkey.numeric | gkey.general_numeric - | gkey.random))) + | gkey.random | gkey.version))) { insertkey (&gkey); need_random |= gkey.random;
_______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils