Re: sort --compare-version

2008-02-20 Thread Jim Meyering
Andreas Schwab [EMAIL PROTECTED] wrote:
 Jim Meyering [EMAIL PROTECTED] writes:
 Do you feel like adding a few tests (tests/sort/Test.pm) to exercise
 the new feature, and adding to coreutils.texi and NEWS?

 Here is an updated patch.

 Andreas.

 2008-02-18  Andreas Schwab  [EMAIL PROTECTED]

   Add --sort option.
   * src/sort.c (SORT_OPTION): New enum.
   (sort_args, sort_types): Define.
   (usage, long_options, main): New option --sort.
   * tests/sort/Test.pm: Test it.

 doc/:
   * coreutils.texi (sort invocation): Document --sort option.

Thank you!
I've applied that, and modulo leading TABs in usage output
(changed to spaces) have pushed it.

  http://git.sv.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=cb3147d298601


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: sort --compare-version

2008-02-18 Thread Andreas Schwab
Jim Meyering [EMAIL PROTECTED] writes:

 Do you feel like adding a few tests (tests/sort/Test.pm) to exercise
 the new feature, and adding to coreutils.texi and NEWS?

Here is an updated patch.

Andreas.

2008-02-18  Andreas Schwab  [EMAIL PROTECTED]

Add --sort option.
* src/sort.c (SORT_OPTION): New enum.
(sort_args, sort_types): Define.
(usage, long_options, main): New option --sort.
* tests/sort/Test.pm: Test it.

doc/:
* coreutils.texi (sort invocation): Document --sort option.

diff --git a/NEWS b/NEWS
index bc1b47d..fb46361 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,13 @@ GNU coreutils NEWS-*- 
outline -*-
 
 * Noteworthy changes in release 6.?? (2008-??-??) [stable]
 
+** New features
+
+  sort accepts the new option --sort=WORD, where WORD can be one of
+  general-numeric, month, numeric or random.  These are equivalent to the
+  options --general-numeric-sort/-g, --month-sort/-M, --numeric-sort/-n
+  and --random-sort/-R, resp.
+
 ** Bug fixes
 
   configure --enable-no-install-program=groups now works.
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 016673a..7d9cbcb 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -3536,8 +3536,10 @@ The @env{LC_CTYPE} locale determines character types.
 
 @item -g
 @itemx --general-numeric-sort
[EMAIL PROTECTED] --sort=general-numeric
 @opindex -g
 @opindex --general-numeric-sort
[EMAIL PROTECTED] --sort
 @cindex general numeric sort
 @vindex LC_NUMERIC
 Sort numerically, using the standard C function @code{strtod} to convert
@@ -3580,8 +3582,10 @@ This option has no effect if the stronger 
@option{--dictionary-order}
 
 @item -M
 @itemx --month-sort
[EMAIL PROTECTED] --sort=month
 @opindex -M
 @opindex --month-sort
[EMAIL PROTECTED] --sort
 @cindex months, sorting by
 @vindex LC_TIME
 An initial string, consisting of any amount of blanks, followed
@@ -3594,8 +3598,10 @@ can change this.
 
 @item -n
 @itemx --numeric-sort
[EMAIL PROTECTED] --sort=numeric
 @opindex -n
 @opindex --numeric-sort
[EMAIL PROTECTED] --sort
 @cindex numeric sort
 @vindex LC_NUMERIC
 Sort numerically.  The number begins each line and consists
@@ -3623,8 +3629,10 @@ appear earlier in the output instead of later.
 
 @item -R
 @itemx --random-sort
[EMAIL PROTECTED] --sort=random
 @opindex -R
 @opindex --random-sort
[EMAIL PROTECTED] --sort
 @cindex random sort
 Sort by hashing the input keys and then sorting the hash values.
 Choose the hash function at random, ensuring that it is free of
diff --git a/src/sort.c b/src/sort.c
index 1183fc5..79cca18 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -329,6 +329,9 @@ Ordering options:\n\
   -n, --numeric-sort  compare according to string numerical value\n\
   -R, --random-sort   sort by random hash of keys\n\
   --random-source=FILEget random bytes from FILE (default 
/dev/urandom)\n\
+  --sort=WORD sort according to WORD:\n\
+   general-numeric -g, month -M, numeric -n,\n\
+random -R\n\
   -r, --reverse   reverse the result of comparisons\n\
 \n\
 ), stdout);
@@ -391,7 +394,8 @@ enum
 {
   CHECK_OPTION = CHAR_MAX + 1,
   COMPRESS_PROGRAM_OPTION,
-  RANDOM_SOURCE_OPTION
+  RANDOM_SOURCE_OPTION,
+  SORT_OPTION
 };
 
 static char const short_options[] = -bcCdfgik:mMno:rRsS:t:T:uy:z;
@@ -411,6 +415,7 @@ static struct option const long_options[] =
   {numeric-sort, no_argument, NULL, 'n'},
   {random-sort, no_argument, NULL, 'R'},
   {random-source, required_argument, NULL, RANDOM_SOURCE_OPTION},
+  {sort, required_argument, NULL, SORT_OPTION},
   {output, required_argument, NULL, 'o'},
   {reverse, no_argument, NULL, 'r'},
   {stable, no_argument, NULL, 's'},
@@ -434,6 +439,16 @@ static char const check_types[] =
 };
 ARGMATCH_VERIFY (check_args, check_types);
 
+static char const *const sort_args[] =
+{
+  general-numeric, month, numeric, random, NULL
+};
+static char const sort_types[] =
+{
+  'g', 'M', 'n', 'R'
+};
+ARGMATCH_VERIFY (sort_args, sort_types);
+
 /* The set of signals that are caught.  */
 static sigset_t caught_signals;
 
@@ -2902,6 +2917,9 @@ main (int argc, char **argv)
files[nfiles++] = optarg;
  break;
 
+   case SORT_OPTION:
+ c = XARGMATCH (--sort, optarg, sort_args, sort_types);
+ /* Fall through. */
case 'b':
case 'd':
case 'f':
diff --git a/tests/sort/Test.pm b/tests/sort/Test.pm
index e4d98be..0462973 100644
--- a/tests/sort/Test.pm
+++ b/tests/sort/Test.pm
@@ -274,6 +274,7 @@ my @tv = (
 [incompat4, '-c -o /dev/null', '', '', 2],
 [incompat5, '-C -o /dev/null', '', '', 2],
 [incompat6, '-cC', '', '', 2],
+[incompat7, '--sort=random -n', '', '', 2],
 
 # -t '\0' is accepted, as of coreutils-5.0.91
 ['nul-tab', -k2,2 -t '\\0', a\0z\01\nb\0y\02\n, b\0y\02\na\0z\01\n, 0],
@@ -289,6 +290,9 @@ my @tv = (
 # Exercise the code that enlarges the line buffer.  

Re: sort --compare-version

2008-02-10 Thread Jim Meyering
Andreas Schwab [EMAIL PROTECTED] wrote:
 Jim Meyering [EMAIL PROTECTED] writes:
 Andreas Schwab [EMAIL PROTECTED] wrote:
 Bruce Korb [EMAIL PROTECTED] writes:

 Yep.  That's the reason for the compare- prefix.  I didn't like
 ``--compare-version-sort'' for some sort of reason, too.  Ultimately,
 someone pick another name if compare-version is aesthetically bad.

 How about making it --sort=KEYWORD, with KEYWORD in
 {general-numeric,month,numeric,random,version}?

 I like it.

 Here's a patch to add --sort.

 Andreas.

 2008-02-09  Andreas Schwab  [EMAIL PROTECTED]

   Add --sort option.
   * src/sort.c (SORT_OPTION): New enum.
   (sort_args, sort_types): Define.
   (usage, long_options, main): New option --sort.

Thanks for writing that.
I appreciate your including a ChangeLog entry.

Do you feel like adding a few tests (tests/sort/Test.pm) to exercise
the new feature, and adding to coreutils.texi and NEWS?


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: sort --compare-version

2008-02-08 Thread Andreas Schwab
Jim Meyering [EMAIL PROTECTED] writes:

 Andreas Schwab [EMAIL PROTECTED] wrote:
 Bruce Korb [EMAIL PROTECTED] writes:

 Yep.  That's the reason for the compare- prefix.  I didn't like
 ``--compare-version-sort'' for some sort of reason, too.  Ultimately,
 someone pick another name if compare-version is aesthetically bad.

 How about making it --sort=KEYWORD, with KEYWORD in
 {general-numeric,month,numeric,random,version}?

 I like it.

Here's a patch to add --sort.

Andreas.

2008-02-09  Andreas Schwab  [EMAIL PROTECTED]

Add --sort option.
* src/sort.c (SORT_OPTION): New enum.
(sort_args, sort_types): Define.
(usage, long_options, main): New option --sort.

diff --git a/src/sort.c b/src/sort.c
index 1183fc5..1942670 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -329,6 +329,9 @@ Ordering options:\n\
   -n, --numeric-sort  compare according to string numerical value\n\
   -R, --random-sort   sort by random hash of keys\n\
   --random-source=FILEget random bytes from FILE (default 
/dev/urandom)\n\
+  --sort=WORD sort according to WORD:\n\
+   general-numeric -g, month -M, numeric -N,\n\
+random -R\n\
   -r, --reverse   reverse the result of comparisons\n\
 \n\
 ), stdout);
@@ -391,7 +394,8 @@ enum
 {
   CHECK_OPTION = CHAR_MAX + 1,
   COMPRESS_PROGRAM_OPTION,
-  RANDOM_SOURCE_OPTION
+  RANDOM_SOURCE_OPTION,
+  SORT_OPTION
 };
 
 static char const short_options[] = -bcCdfgik:mMno:rRsS:t:T:uy:z;
@@ -411,6 +415,7 @@ static struct option const long_options[] =
   {numeric-sort, no_argument, NULL, 'n'},
   {random-sort, no_argument, NULL, 'R'},
   {random-source, required_argument, NULL, RANDOM_SOURCE_OPTION},
+  {sort, required_argument, NULL, SORT_OPTION},
   {output, required_argument, NULL, 'o'},
   {reverse, no_argument, NULL, 'r'},
   {stable, no_argument, NULL, 's'},
@@ -434,6 +439,16 @@ static char const check_types[] =
 };
 ARGMATCH_VERIFY (check_args, check_types);
 
+static char const *const sort_args[] =
+{
+  general-numeric, month, numeric, random, NULL
+};
+static char const sort_types[] =
+{
+  'g', 'M', 'n', 'R'
+};
+ARGMATCH_VERIFY (sort_args, sort_types);
+
 /* The set of signals that are caught.  */
 static sigset_t caught_signals;
 
@@ -2902,6 +2917,9 @@ main (int argc, char **argv)
files[nfiles++] = optarg;
  break;
 
+   case SORT_OPTION:
+ c = XARGMATCH (--sort, optarg, sort_args, sort_types);
+ /* Fall through. */
case 'b':
case 'd':
case 'f':

-- 
Andreas Schwab, SuSE Labs, [EMAIL PROTECTED]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
And now for something completely different.


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: sort --compare-version

2008-02-06 Thread Bruce Korb
Bob Proulx wrote:
 @@ -353,6 +354,7 @@ Other options:\n\
 +  -V, --compare-version compare embedded numbers as version numbers\n\
 
 Looking at the existing options I see these:
 
 Ordering options:
   -g, --general-numeric-sort  compare according to general numerical value
   -M, --month-sortcompare (unknown)  `JAN'  ...  `DEC'
   -n, --numeric-sort  compare according to string numerical value
 
 That would mean to me that version comparison would need to be of the
 form --something-sort and would need to be in the Ordering
 options: section and not the Other options: section.  I suppose
 that this option should be called --version-sort instead in order to
 be consistent with the already existing options.
 
 But!  Using --version-sort conflicts with --version.

Yep.  That's the reason for the compare- prefix.  I didn't like
``--compare-version-sort'' for some sort of reason, too.  Ultimately,
someone pick another name if compare-version is aesthetically bad.

 I do think it needs to be moved into the Ordering options: section
 through regardless.

Yes.

 +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] = sv_a;
 +  textb[lenb] = sv_b;
 
 Pardon me for not looking but why is texta[lena] saved, zeroed, and
 then restored?  A clue left behind there would be nice.

OK.   The reason is that strverscmp works on NUL terminated strings.
The specified fields are not guaranteed to be NUL terminated, but
are guaranteed to be writable.

{
 -char opts[7];
 +char opts[sizeof short_options];
  char *p = opts;
  if (key-ignore == nondictionary)
*p++ = 'd';
 
 I don't like the magic number 7 there (and I think it should have been
 8 anyway meaning that you have also fixed a bug to be noted in the log
 entry) but using sizeof short_options I think is not correct either.

It is guaranteed to be sufficient and certain to be inconsequential.
Yes, it uses a half dozen extra bytes of memory.  That can't be
a problem.

 I think I like this following technique better.  In my mind it makes
 it much more self-documenting without using extra space.
 
   {
   char opts[sizeof dfgiMnVR];
   char *p = opts;
   if (key-ignore == nondictionary)
 *p++ = 'd';

I think this is an improvement that requires more maintenance than
simply making the buffer big enough for any conceivable list of
options.  So, marginally more intelligible and marginally more
maintenance.  Looks good to me. :)

 In general I like the feature very much.  Thank you for working on
 this.  Have you submitted the necessary copyright paperwork to the FSF
 for contribution to coreutils?

All the paperwork is in place.

  Would you also be able to work on
 other things needed to get this into coreutils such as ChangeLog
 entry, test cases, info documentation, and NEWS entry?  I would be
 willing to help with these tasks.

I'm glad you're willing to help 'cuz this isn't my day job.  :)

Cheers - Bruce


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: sort --compare-version

2008-02-06 Thread Andreas Schwab
Bruce Korb [EMAIL PROTECTED] writes:

 Yep.  That's the reason for the compare- prefix.  I didn't like
 ``--compare-version-sort'' for some sort of reason, too.  Ultimately,
 someone pick another name if compare-version is aesthetically bad.

How about making it --sort=KEYWORD, with KEYWORD in
{general-numeric,month,numeric,random,version}?

Andreas.

-- 
Andreas Schwab, SuSE Labs, [EMAIL PROTECTED]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
And now for something completely different.


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: sort --compare-version

2008-02-06 Thread Bruce Korb
On Feb 6, 2008 10:59 AM, Andreas Schwab [EMAIL PROTECTED] wrote:
 Bruce Korb [EMAIL PROTECTED] writes:

  Yep.  That's the reason for the compare- prefix.  I didn't like
  ``--compare-version-sort'' for some sort of reason, too.  Ultimately,
  someone pick another name if compare-version is aesthetically bad.

 How about making it --sort=KEYWORD, with KEYWORD in
 {general-numeric,month,numeric,random,version}?

Yep.  That's _very_ nice.  Just a little beyond the energy level I had at
the time.  :)  Thanks.


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: sort --compare-version

2008-02-06 Thread Jim Meyering
Andreas Schwab [EMAIL PROTECTED] wrote:
 Bruce Korb [EMAIL PROTECTED] writes:

 Yep.  That's the reason for the compare- prefix.  I didn't like
 ``--compare-version-sort'' for some sort of reason, too.  Ultimately,
 someone pick another name if compare-version is aesthetically bad.

 How about making it --sort=KEYWORD, with KEYWORD in
 {general-numeric,month,numeric,random,version}?

I like it.
Then it's easy to skip the short-named command-line option.


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: sort --compare-version

2008-02-06 Thread Bauke Jan Douma

Andreas Schwab wrote on 06-02-08 19:59:

Bruce Korb [EMAIL PROTECTED] writes:


Yep.  That's the reason for the compare- prefix.  I didn't like
``--compare-version-sort'' for some sort of reason, too.  Ultimately,
someone pick another name if compare-version is aesthetically bad.


How about making it --sort=KEYWORD, with KEYWORD in
{general-numeric,month,numeric,random,version}?

Andreas.



That's what I thought.  But I suppose the single-letter
options that are valid now will have to be kept also?

bjd



___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: sort --compare-version

2008-02-06 Thread Bob Proulx
Jim Meyering wrote:
 Andreas Schwab wrote:
  How about making it --sort=KEYWORD, with KEYWORD in
  {general-numeric,month,numeric,random,version}?
 
 I like it.
 Then it's easy to skip the short-named command-line option.

+1

I very much like that idea too.

Bob


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: sort --compare-version

2008-02-06 Thread Bob Proulx
Bruce Korb wrote:
 Bob Proulx wrote:
  I don't like the magic number 7 there (and I think it should have been
  8 anyway meaning that you have also fixed a bug to be noted in the log
  entry) but using sizeof short_options I think is not correct either.
 
 It is guaranteed to be sufficient and certain to be inconsequential.
 Yes, it uses a half dozen extra bytes of memory.  That can't be
 a problem.

In my mind it wasn't about the extra memory.  As you noted it was an
insignificant amount.  My concern was that it tied the size of that
string to something that strictly speaking was something different.
It would always have been larger and would have been functional.  But
it isn't really the size of the thing that we needed.  Reading the
code later there wasn't the mental tie between the two things that I
felt needed to be tied together.

  I think I like this following technique better.  In my mind it makes
  it much more self-documenting without using extra space.
  
{
  char opts[sizeof dfgiMnVR];
  char *p = opts;
  if (key-ignore == nondictionary)
*p++ = 'd';
 
 I think this is an improvement that requires more maintenance than
 simply making the buffer big enough for any conceivable list of
 options.  So, marginally more intelligible and marginally more
 maintenance.  Looks good to me. :)

Anyone looking to add option letters would definitely be drawn to that
spot because it looks very similar to the getopts string of options
and would naturally keep it up to date.  I like it better than the
bare number approach but even that wasn't bad, just something that
could be slightly better.  Obviously I like it better than using a
bounded sizeof something else that's bigger.  So I will simply
disagree that it is more maintenance because I think it would be less
maintenance.  But either way if we are agreed that it may appear more
intelligible then it is a win.

 I'm glad you're willing to help 'cuz this isn't my day job.  :)

Do you work the midnight shift?  ;-)

Bob


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: sort --compare-version

2008-02-05 Thread James Youngman
On Feb 5, 2008 1:09 AM, Bob Proulx [EMAIL PROTECTED] wrote:
 That would mean to me that version comparison would need to be of the
 form --something-sort and would need to be in the Ordering
 options: section and not the Other options: section.  I suppose
 that this option should be called --version-sort instead in order to
 be consistent with the already existing options.

 But!  Using --version-sort conflicts with --version.  Which means my
 purpose here is simply to call this up for discussion such that some
 reasonable choice can be made since this will need to be an exception
 to the rule.  Comments?

How about something synonymous, but differently spelled?   For example
--releasenumber-sort?

James.


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: sort --compare-version

2008-02-04 Thread Bob Proulx
Bruce Korb wrote:
 This works for me :)
 Either ``-V'' or ``--compare-version'' will trigger the use of
 strverscmp in lieu of memcmp as the comparison function.

That looks very interesting to me.  I have often wanted a sort that
would sort using a version compare similar to the 'ls -v' version
comparison.  Thanks for working on it.  A few comments about the patch
itself and then some proceedural things about what needs to be done to
move this forward.

 @@ -353,6 +354,7 @@ Other options:\n\
 +  -V, --compare-version compare embedded numbers as version numbers\n\

Looking at the existing options I see these:

Ordering options:
  -g, --general-numeric-sort  compare according to general numerical value
  -M, --month-sortcompare (unknown)  `JAN'  ...  `DEC'
  -n, --numeric-sort  compare according to string numerical value

That would mean to me that version comparison would need to be of the
form --something-sort and would need to be in the Ordering
options: section and not the Other options: section.  I suppose
that this option should be called --version-sort instead in order to
be consistent with the already existing options.

But!  Using --version-sort conflicts with --version.  Which means my
purpose here is simply to call this up for discussion such that some
reasonable choice can be made since this will need to be an exception
to the rule.  Comments?

I do think it needs to be moved into the Ordering options: section
through regardless.

 +/* 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;
 +}

Pardon me for not looking but why is texta[lena] saved, zeroed, and
then restored?  A clue left behind there would be nice.

 @@ -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';

I don't like the magic number 7 there (and I think it should have been
8 anyway meaning that you have also fixed a bug to be noted in the log
entry) but using sizeof short_options I think is not correct either.

I think I like this following technique better.  In my mind it makes
it much more self-documenting without using extra space.

  {
char opts[sizeof dfgiMnVR];
char *p = opts;
if (key-ignore == nondictionary)
  *p++ = 'd';
if (key-translate)
  *p++ = 'f';
if (key-general_numeric)
  *p++ = 'g';
if (key-ignore == nonprinting)
  *p++ = 'i';
if (key-month)
  *p++ = 'M';
if (key-numeric)
  *p++ = 'n';
if (key-version)
  *p++ = 'V';
if (key-random)
  *p++ = 'R';
*p = '\0';
incompatible_options (opts);
  }

In general I like the feature very much.  Thank you for working on
this.  Have you submitted the necessary copyright paperwork to the FSF
for contribution to coreutils?  Would you also be able to work on
other things needed to get this into coreutils such as ChangeLog
entry, test cases, info documentation, and NEWS entry?  I would be
willing to help with these tasks.

Bob


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


sort --compare-version

2008-01-31 Thread Bruce Korb
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.0 -0800
+++ coreutils-6.10/src/sort.c	2008-01-31 07:55:10.0 -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;
 }