bug-textutils
[Top][All Lists]
Advanced

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

Hex number sort....


From: Rogier Wolff
Subject: Hex number sort....
Date: Mon, 30 Jul 2001 14:12:57 +0200 (MEST)

Hi GNU folks...,

We're sorting files with columns of hex numbers regularly. 

It'd be nice if the standard utility "sort" would support that... 

Done! I've made a small patch that implements this. 

I'd appreciate a note if you guys see thisfit for general
distribution, or if not, why not. Thanks!

                        Roger. 


-------------
(I hand-edited the diff because diff also found a security patch in
there. I hope I did that right...)
--------------


--- /usr/src/packages/SOURCES/textutils-2.0.10/src/sort.c       Sat Dec  2 
22:14:29 2000
+++ textutils-2.0.10/src/sort.c Mon Jul 30 13:29:05 2001
@@ -151,6 +152,7 @@
   int numeric;                 /* Flag for numeric comparison.  Handle
                                   strings of digits with optional decimal
                                   point, but no exponential notation. */
+  int hex;
   int general_numeric;         /* Flag for general, numeric comparison.
                                   Handle numbers in exponential notation. */
   int month;                   /* Flag for comparison by month name. */
@@ -303,6 +305,7 @@
                     multiple -T options specify multiple directories\n\
   -u               with -c, check for strict ordering;\n\
                    with -m, only output the first of an equal sequence\n\
+  -x               compare numeric hex values.\n\
   -z               end lines with 0 byte, not newline, for find -print0\n\
       --help       display this help and exit\n\
       --version    output version information and exit\n\
@@ -1080,6 +1093,40 @@
          : memcmp ((char *) &a, (char *) &b, sizeof a));
 }
 
+
+
+static int
+hexcompare (const char *sa, const char *sb)
+{
+  /* FIXME: add option to warn about failed conversions.  */
+  long long a, b;
+  int na, nb;
+
+  sscanf (sa, "%llx%n", &a, &na);
+  sscanf (sb, "%llx%n", &b, &nb);
+
+#if 0
+  fprintf (stderr, "%s(%lld/%d) <?> %s(%lld/%d): %d\n", 
+          sa, a, na, sb, b, nb, 
+          a < b ? -1
+          : a > b ? 1
+          : 0);
+#endif
+  /* Put conversion errors at the start of the collating sequence.  */
+  if (na == 0)
+    return nb == 0 ? 0 : -1;
+  if (nb == 0)
+    return 1;
+
+  /* Sort numbers in the usual way, where -0 == +0.  Put NaNs after
+     conversion errors but before numbers; sort them by internal
+     bit-pattern, for lack of a more portable alternative.  */
+  return (a < b ? -1
+         : a > b ? 1
+         : 0);
+}
+
+
 /* Return an integer in 1..12 of the month name S with length LEN.
    Return 0 if the name in S is not recognized.  */
 
@@ -1161,13 +1208,21 @@
        }
 
       /* Actually compare the fields. */
-      if (key->numeric | key->general_numeric)
+      if (key->numeric | key->general_numeric | key->hex)
        {
          char savea = *lima, saveb = *limb;
 
          *lima = *limb = '\0';
-         diff = ((key->numeric ? numcompare : general_numcompare)
-                 (texta, textb));
+         if (key->numeric) 
+           diff = numcompare (texta, textb);
+         else if (key->general_numeric) 
+           diff = general_numcompare (texta, textb);
+         else if (key->hex)
+           diff = hexcompare (texta, textb);
+         else {
+           printf ("Internal sort error. \n");
+           exit (1);
+         }
          *lima = savea, *limb = saveb;
        }
       else if (key->month)
@@ -1899,6 +1954,9 @@
        case 'n':
          key->numeric = 1;
          break;
+       case 'x':
+         key->hex = 1;
+         break;
        case 'r':
          key->reverse = 1;
          break;
@@ -2007,7 +2065,7 @@
   gkey.sword = gkey.eword = -1;
   gkey.ignore = NULL;
   gkey.translate = NULL;
-  gkey.numeric = gkey.general_numeric = gkey.month = gkey.reverse = 0;
+  gkey.numeric = gkey.hex = gkey.general_numeric = gkey.month = gkey.reverse = 
0;
   gkey.skipsblanks = gkey.skipeblanks = 0;
 
   files = (char **) xmalloc (sizeof (char *) * argc);
@@ -2238,7 +2296,7 @@
   /* 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
+       && !key->skipeblanks && !key->month && !key->numeric && !key->hex 
         && !key->general_numeric)
       {
        key->ignore = gkey.ignore;
@@ -2247,13 +2305,14 @@
        key->skipeblanks = gkey.skipeblanks;
        key->month = gkey.month;
        key->numeric = gkey.numeric;
+       key->hex = gkey.hex;
        key->general_numeric = gkey.general_numeric;
        key->reverse = gkey.reverse;
       }
 
   if (!keylist && (gkey.ignore || gkey.translate || gkey.skipsblanks
-                  || gkey.skipeblanks || gkey.month || gkey.numeric
-                  || gkey.general_numeric))
+                  || gkey.skipeblanks || gkey.month || gkey.numeric 
+                  || gkey.hex || gkey.general_numeric))
     insertkey (&gkey);
   reverse = gkey.reverse;
 



-- 
** address@hidden ** http://www.BitWizard.nl/ ** +31-15-2137555 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
* There are old pilots, and there are bold pilots. 
* There are also old, bald pilots. 



reply via email to

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