bug-coreutils
[Top][All Lists]
Advanced

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

Re: Human readable sort


From: Pádraig Brady
Subject: Re: Human readable sort
Date: Tue, 30 Jun 2009 10:02:06 +0100
User-agent: Thunderbird 2.0.0.6 (X11/20071008)

I was thinking that the mixed IEC/SI check
should be applied to each key separately rather
than globally. What do you think? Patch attached.

cheers,
Pádraig.
>From ef06a30d122fc9ccac51a682a3abf6868d8832d6 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?P=C3=A1draig=20Brady?= <address@hidden>
Date: Tue, 30 Jun 2009 00:52:43 +0100
Subject: [PATCH] sort: allow SI and IEC units on separate human sort fields

* src/sort.c: Store the si_present state per key rather than globally
* tests/misc/sort: Add a corresponding check that previously failed
---
 src/sort.c      |   30 ++++++++++++++++--------------
 tests/misc/sort |    2 ++
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/src/sort.c b/src/sort.c
index 6acec07..62ddd49 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -178,6 +178,7 @@ struct keyfield
                                   Handle numbers in exponential notation. */
   bool human_numeric;          /* Flag for sorting by human readable
                                   units with either SI xor IEC prefixes. */
+  int si_present;              /* Flag for checking for mixed SI and IEC. */
   bool month;                  /* Flag for comparison by month name. */
   bool reverse;                        /* Reverse the sense of comparison. */
   bool version;                        /* sort by version number */
@@ -1684,13 +1685,12 @@ numcompare (const char *a, const char *b)
 /* Exit with an error if a mixture of SI and IEC units detected.  */
 
 static void
-check_mixed_SI_IEC (char prefix)
+check_mixed_SI_IEC (char prefix, struct keyfield *key)
 {
-  static int seen_si = -1;
-  bool si_present = prefix == 'i';
-  if (seen_si != -1 && seen_si != si_present)
+  int si_present = prefix == 'i';
+  if (key->si_present != -1 && si_present != key->si_present)
     error (SORT_FAILURE, 0, _("both SI and IEC prefixes present on units"));
-  seen_si = si_present;
+  key->si_present = si_present;
 }
 
 /* Return an integer which represents the order of magnitude of
@@ -1699,7 +1699,7 @@ check_mixed_SI_IEC (char prefix)
    Negative numbers return a negative unit order.  */
 
 static int
-find_unit_order (const char *number)
+find_unit_order (const char *number, struct keyfield *key)
 {
   static const char orders [UCHAR_LIM] = {
     ['K']=1, ['M']=2, ['G']=3, ['T']=4, ['P']=5, ['E']=6, ['Z']=7, ['Y']=8,
@@ -1736,7 +1736,7 @@ find_unit_order (const char *number)
 
   /* For valid units check for MiB vs MB etc.  */
   if (order)
-    check_mixed_SI_IEC (*(p + 1));
+    check_mixed_SI_IEC (*(p + 1), key);
 
   return sign * order;
 }
@@ -1747,15 +1747,15 @@ find_unit_order (const char *number)
    i.e. input will never have both 6000K and 5M.  */
 
 static int
-human_numcompare (const char *a, const char *b)
+human_numcompare (const char *a, const char *b, struct keyfield *key)
 {
   while (blanks[to_uchar (*a)])
     a++;
   while (blanks[to_uchar (*b)])
     b++;
 
-  int order_a = find_unit_order (a);
-  int order_b = find_unit_order (b);
+  int order_a = find_unit_order (a, key);
+  int order_b = find_unit_order (b, key);
 
   return (order_a > order_b ? 1
          : order_a < order_b ? -1
@@ -1982,7 +1982,7 @@ compare_version (char *restrict texta, size_t lena,
 static int
 keycompare (const struct line *a, const struct line *b)
 {
-  struct keyfield const *key = keylist;
+  struct keyfield *key = keylist;
 
   /* For the first iteration only, the key positions have been
      precomputed for us. */
@@ -2015,9 +2015,9 @@ keycompare (const struct line *a, const struct line *b)
          char savea = *lima, saveb = *limb;
 
          *lima = *limb = '\0';
-         diff = ((key->numeric ? numcompare
-                  : key->general_numeric ? general_numcompare
-                  : human_numcompare) (texta, textb));
+         diff = (key->numeric ? numcompare (texta, textb)
+                 : key->general_numeric ? general_numcompare (texta, textb)
+                 : human_numcompare (texta, textb, key));
          *lima = savea, *limb = saveb;
        }
       else if (key->version)
@@ -3125,6 +3125,7 @@ key_init (struct keyfield *key)
 {
   memset (key, 0, sizeof *key);
   key->eword = SIZE_MAX;
+  key->si_present = -1;
   return key;
 }
 
@@ -3240,6 +3241,7 @@ main (int argc, char **argv)
   gkey.ignore = NULL;
   gkey.translate = NULL;
   gkey.numeric = gkey.general_numeric = gkey.human_numeric = false;
+  gkey.si_present = -1;
   gkey.random = gkey.version = false;
   gkey.month = gkey.reverse = false;
   gkey.skipsblanks = gkey.skipeblanks = false;
diff --git a/tests/misc/sort b/tests/misc/sort
index 21e7af8..1340500 100755
--- a/tests/misc/sort
+++ b/tests/misc/sort
@@ -71,6 +71,8 @@ my @Tests =
  {ERR=>"$prog: options `-hn' are incompatible\n"}],
 # check key processing
 ["h8", '-n -k2,2h', {IN=>"1 1E\n2 2M\n"}, {OUT=>"2 2M\n1 1E\n"}],
+# SI and IEC prefixes on separate keys allowed
+["h9", '-h -k1,1 -k2,2', {IN=>"1M 1Mi\n1M 1Mi\n"}, {OUT=>"1M 1Mi\n1M 1Mi\n"}],
 
 ["01a", '', {IN=>"A\nB\nC\n"}, {OUT=>"A\nB\nC\n"}],
 #
-- 
1.6.2.5


reply via email to

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