diff -bur t/coreutils-5.2.1/src/sort.c coreutils-5.2.1/src/sort.c --- t/coreutils-5.2.1/src/sort.c 2004-02-17 11:47:35.000000000 +0100 +++ coreutils-5.2.1/src/sort.c 2004-08-27 23:46:56.000000000 +0200 @@ -155,6 +155,8 @@ point, but no exponential notation. */ bool general_numeric; /* Flag for general, numeric comparison. Handle numbers in exponential notation. */ + bool human_readable; /* Flag for human-readable suffixes in + numerical values */ bool month; /* Flag for comparison by month name. */ bool reverse; /* Reverse the sense of comparison. */ struct keyfield *next; /* Next keyfield to try. */ @@ -207,6 +209,9 @@ {"SEP", 9} }; +/* Table of human readable suffixes. */ +static char hr_suffixes[UCHAR_LIM]; + /* During the merge phase, the number of files to merge at once. */ #define NMERGE 16 @@ -293,6 +298,7 @@ "), stdout); fputs (_("\ -g, --general-numeric-sort compare according to general numerical value\n\ + -h, --human-readable compare human-readable numerical values\n\n\ -i, --ignore-nonprinting consider only printable characters\n\ -M, --month-sort compare (unknown) < `JAN' < ... < `DEC'\n\ -n, --numeric-sort compare according to string numerical value\n\ @@ -346,7 +352,7 @@ exit (status); } -#define COMMON_SHORT_OPTIONS "-bcdfgik:mMno:rsS:t:T:uz" +#define COMMON_SHORT_OPTIONS "-bcdfghik:mMno:rsS:t:T:uz" static struct option const long_options[] = { @@ -355,6 +361,7 @@ {"dictionary-order", no_argument, NULL, 'd'}, {"ignore-case", no_argument, NULL, 'f'}, {"general-numeric-sort", no_argument, NULL, 'g'}, + {"human-readable", no_argument, NULL, 'h'}, {"ignore-nonprinting", no_argument, NULL, 'i'}, {"key", required_argument, NULL, 'k'}, {"merge", no_argument, NULL, 'm'}, @@ -546,7 +553,17 @@ nonprinting[i] = !ISPRINT (i); nondictionary[i] = !ISALNUM (i) && !ISBLANK (i); fold_toupper[i] = (ISLOWER (i) ? toupper (i) : i); + hr_suffixes[i] = 0; } + hr_suffixes['K'] = 1; + hr_suffixes['k'] = 1; + hr_suffixes['M'] = 2; + hr_suffixes['G'] = 3; + hr_suffixes['T'] = 4; + hr_suffixes['P'] = 5; + hr_suffixes['E'] = 6; + hr_suffixes['Z'] = 7; + hr_suffixes['Y'] = 8; #if HAVE_NL_LANGINFO /* If we're not in the "C" locale, read different names for months. */ @@ -1261,6 +1278,40 @@ } } +/* Compare strings A and B as numbers suffixed with human-readable + suffixes.*/ + +static int +human_readable_compare (register const char *a, register const char *b) +{ + register int tmpa, tmpb; + const char * savea = a, * saveb = b; + + tmpa = *a; + tmpb = *b; + + while (blanks[UCHAR (tmpa)]) + tmpa = *++a; + while (blanks[UCHAR (tmpb)]) + tmpb = *++b; + + while (tmpa == NEGATION_SIGN) + tmpa = *++a; + + while (tmpb == NEGATION_SIGN) + tmpb = *++b; + + while (IS_THOUSANDS_SEP(tmpa) || ISDIGIT(tmpa) || tmpa == decimal_point) + tmpa = *++a; + while (IS_THOUSANDS_SEP(tmpb) || ISDIGIT(tmpb) || tmpb == decimal_point) + tmpb = *++b; + + if (hr_suffixes[tmpa] != hr_suffixes[tmpb]) + return hr_suffixes[tmpa] < hr_suffixes[tmpb] ? -1 : 1; + else + return numcompare(savea, saveb); +} + static int general_numcompare (const char *sa, const char *sb) { @@ -1374,6 +1425,14 @@ (texta, textb)); *lima = savea, *limb = saveb; } + else if (key->human_readable) + { + char savea = *lima, saveb = *limb; + + *lima = *limb = '\0'; + diff = human_readable_compare(texta, textb); + *lima = savea, *limb = saveb; + } else if (key->month) diff = getmonth (texta, lena) - getmonth (textb, lenb); /* Sorting like this may become slow, so in a simple locale the user @@ -2177,6 +2236,9 @@ case 'g': key->general_numeric = true; break; + case 'h': + key->human_readable = true; + break; case 'i': /* Option order should not matter, so don't let -i override -d. -d implies -i, but -i does not imply -d. */ @@ -2301,7 +2363,7 @@ gkey.ignore = NULL; gkey.translate = NULL; gkey.numeric = gkey.general_numeric = gkey.month = gkey.reverse = false; - gkey.skipsblanks = gkey.skipeblanks = false; + gkey.skipsblanks = gkey.skipeblanks = gkey.human_readable = false; files = xnmalloc (argc, sizeof *files); @@ -2372,6 +2434,7 @@ case 'd': case 'f': case 'g': + case 'h': case 'i': case 'M': case 'n': @@ -2517,7 +2580,7 @@ if (! (key->ignore || key->translate || (key->skipsblanks | key->reverse | key->skipeblanks | key->month | key->numeric - | key->general_numeric))) + | key->general_numeric | key->human_readable))) { key->ignore = gkey.ignore; key->translate = gkey.translate; @@ -2526,12 +2589,14 @@ key->month = gkey.month; key->numeric = gkey.numeric; key->general_numeric = gkey.general_numeric; + key->human_readable = gkey.human_readable; key->reverse = gkey.reverse; } if (!keylist && (gkey.ignore || gkey.translate || (gkey.skipsblanks | gkey.skipeblanks | gkey.month - | gkey.numeric | gkey.general_numeric))) + | gkey.numeric | gkey.general_numeric + | gkey.human_readable))) insertkey (&gkey); reverse = gkey.reverse;