bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Sort by version number (patch included)


From: Ian Dall
Subject: Sort by version number (patch included)
Date: Wed, 2 Nov 2005 17:20:00 +1030

I needed to sort by version number so that 1.2.12 > 1.2.3

This is pretty trivial as there is a function strverscmp() in libc,
and I have prepared a patch, including documentation and Changelog
Entries.

Ian

Changlog:

2005-11-02  Ian Dall  <address@hidden>

        * src/sort.c (usage, long_options, set_ordering, main)
        (struct keyfield, keycompare): Add support for sorting by version
        number.

doc/Changelog:

2005-11-02  Ian Dall  <address@hidden>

        * coreutils.texi (sort invocation): Document new option
        --version-sort (-v).

Patch:

diff -ru ../coreutils-5.92/doc/coreutils.texi ./doc/coreutils.texi
--- ../coreutils-5.92/doc/coreutils.texi        2005-10-16 16:56:21.000000000 
+0930
+++ ./doc/coreutils.texi        2005-11-02 16:20:04.000000000 +1030
@@ -3310,6 +3310,16 @@
 To compare such strings numerically, use the
 @option{--general-numeric-sort} (@option{-g}) option.
 
address@hidden -v
address@hidden --version-sort
address@hidden -v
address@hidden --version-sort
address@hidden version number, sorting by
address@hidden LC_TIME
+Strings are compared as version numbers so that @samp{1.2.3} <
address@hidden  Comparison is done with the @code{strverscmp} function
address@hidden/Array Comparison,,strverscmp, libc.info}
+
 @item -r
 @itemx --reverse
 @opindex -r
diff -ru ../coreutils-5.92/src/sort.c ./src/sort.c
--- ../coreutils-5.92/src/sort.c        2005-10-08 04:46:56.000000000 +0930
+++ ./src/sort.c        2005-11-02 16:59:30.000000000 +1030
@@ -150,6 +150,7 @@
   bool general_numeric;                /* Flag for general, numeric comparison.
                                   Handle numbers in exponential notation. */
   bool month;                  /* Flag for comparison by month name. */
+  bool version;                        /* Flag for version string comparison */
   bool reverse;                        /* Reverse the sense of comparison. */
   struct keyfield *next;       /* Next keyfield to try. */
 };
@@ -322,6 +323,7 @@
                               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, --version-sort          compare keys as version number according to 
strverscmp\n\
 "), DEFAULT_TMPDIR);
       fputs (_("\
   -z, --zero-terminated     end lines with 0 byte, not newline\n\
@@ -353,7 +355,7 @@
   exit (status);
 }
 
-static char const short_options[] = "-bcdfgik:mMno:rsS:t:T:uy:z";
+static char const short_options[] = "-bcdfgik:mMnvo:rsS:t:T:uy:z";
 
 static struct option const long_options[] =
 {
@@ -367,6 +369,7 @@
   {"merge", no_argument, NULL, 'm'},
   {"month-sort", no_argument, NULL, 'M'},
   {"numeric-sort", no_argument, NULL, 'n'},
+  {"version-sort", no_argument, NULL, 'v'},
   {"output", required_argument, NULL, 'o'},
   {"reverse", no_argument, NULL, 'r'},
   {"stable", no_argument, NULL, 's'},
@@ -1192,6 +1195,8 @@
        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 (key->version)
+       diff = strverscmp(texta, textb);
       else if (hard_LC_COLLATE)
        {
          if (ignore || translate)
@@ -2084,6 +2089,9 @@
        case 'r':
          key->reverse = true;
          break;
+       case 'v':
+         key->version = true;
+         break;
        default:
          return (char *) s;
        }
@@ -2187,7 +2195,8 @@
   gkey.sword = gkey.eword = SIZE_MAX;
   gkey.ignore = NULL;
   gkey.translate = NULL;
-  gkey.numeric = gkey.general_numeric = gkey.month = gkey.reverse = false;
+  gkey.numeric = gkey.general_numeric = gkey.month = gkey.reverse 
+    = gkey.version = false;
   gkey.skipsblanks = gkey.skipeblanks = false;
 
   files = xnmalloc (argc, sizeof *files);
@@ -2263,6 +2272,7 @@
        case 'M':
        case 'n':
        case 'r':
+       case 'v':
          {
            char str[2];
            str[0] = c;
@@ -2418,7 +2428,7 @@
     if (! (key->ignore || key->translate
           || (key->skipsblanks | key->reverse
               | key->skipeblanks | key->month | key->numeric
-              | key->general_numeric)))
+              | key->general_numeric | key->version)))
       {
        key->ignore = gkey.ignore;
        key->translate = gkey.translate;
@@ -2428,11 +2438,12 @@
        key->numeric = gkey.numeric;
        key->general_numeric = gkey.general_numeric;
        key->reverse = gkey.reverse;
+       key->version = gkey.version;
       }
 
   if (!keylist && (gkey.ignore || gkey.translate
                   || (gkey.skipsblanks | gkey.skipeblanks | gkey.month
-                      | gkey.numeric | gkey.general_numeric)))
+                      | gkey.numeric | gkey.general_numeric | gkey.version)))
     insertkey (&gkey);
   reverse = gkey.reverse;
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]