diff options
-rwxr-xr-x | scripts/test/sort.test | 9 | ||||
-rw-r--r-- | toys/sort.c | 59 |
2 files changed, 43 insertions, 25 deletions
diff --git a/scripts/test/sort.test b/scripts/test/sort.test index cb82dc07..6449e499 100755 --- a/scripts/test/sort.test +++ b/scripts/test/sort.test @@ -88,4 +88,13 @@ testing "sort key edge case with -t" "sort -n -k4 -t/" \ /usr/lib/prebaseconfig.d/6 " +testing "sort -x" "sort -x" "010\na0\n 0c0\n" "" "a0\n010\n 0c0\n" + +optional SORT_FLOAT + +# not numbers < NaN < -infinity < numbers < +infinity +testing "sort -g" "sort -g" \ + "bork\nNaN\n-inf\n0.4\n1.222\n01.37\n2.1\n+infinity\n" "" \ + "01.37\n1.222\n2.1\n0.4\nNaN\nbork\n-inf\n+infinity\n" + exit $FAILCOUNT diff --git a/toys/sort.c b/toys/sort.c index 3cec31af..8eb35d8b 100644 --- a/toys/sort.c +++ b/toys/sort.c @@ -6,7 +6,7 @@ * * See http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html -USE_SORT(NEWTOY(sort, USE_SORT_BIG("S:T:m" "o:k*t:xbgMcszdfi") "run", TOYFLAG_USR|TOYFLAG_BIN)) +USE_SORT(NEWTOY(sort, USE_SORT_FLOAT("g")USE_SORT_BIG("S:T:m" "o:k*t:xbMcszdfi") "run", TOYFLAG_USR|TOYFLAG_BIN)) config SORT bool "sort" @@ -21,17 +21,16 @@ config SORT -n numeric order (instead of alphabetical) config SORT_BIG - bool "all SuSv3 options (Support -ktcsbdfiozgM)" + bool "SuSv3 options (Support -ktcsbdfiozM)" default y depends on SORT help - usage: sort [-bcdfgiMsz] [-k#[,#[x]] [-t X]] [-o FILE] + usage: sort [-bcdfiMsz] [-k#[,#[x]] [-t X]] [-o FILE] -b ignore leading blanks (or trailing blanks in second part of key) -c check whether input is sorted -d dictionary order (use alphanumeric and whitespace chars only) -f force uppercase (case insensitive sort) - -g general numeric sort (double precision with nan and inf) -i ignore nonprinting characters -M month sort (jan, feb, etc). -x Hexadecimal numerical sort @@ -41,14 +40,24 @@ config SORT_BIG -t use a key separator other than whitespace -o output to FILE instead of stdout - This version of sort requires floating point. - Sorting by key looks at a subset of the words on each line. -k2 uses the second word to the end of the line, -k2,2 looks at only the second word, -k2,4 looks from the start of the second to the end of the fourth word. Specifying multiple keys uses the later keys as tie breakers, in order. A type specifier appended to a sort key (such as -2,2n) applies only to sorting that key. + +config SORT_FLOAT + bool "Floating point (-g)" + default y + depends on SORT_BIG + help + usage: sort [-g] + + This version of sort requires floating point. + + -g general numeric sort (double precision with nan and inf) + */ #include "toys.h" @@ -72,20 +81,20 @@ DEFINE_GLOBALS( // b at top level implies bb. // The remaining options can be applied to search keys. -#define FLAG_n 1 // Sort type: numeric -#define FLAG_u 2 // Unique -#define FLAG_r 4 // Reverse output order - -#define FLAG_i 8 // Ignore !isprint() -#define FLAG_f 16 // Force uppercase -#define FLAG_d 32 // Ignore !(isalnum()|isspace()) -#define FLAG_z 64 // Input is null terminated, not \n -#define FLAG_s 128 // Stable sort, no ascii fallback at end -#define FLAG_c 256 // Check only. No output, exit(!ordered) -#define FLAG_M 512 // Sort type: date -#define FLAG_g 1024 // Sort type: strtod() -#define FLAG_b 2048 // Ignore leading blanks -#define FLAG_x 4096 // Hex sort +#define FLAG_n (1<<0) // Sort type: numeric +#define FLAG_u (1<<1) // Unique +#define FLAG_r (1<<2) // Reverse output order + +#define FLAG_i (1<<3) // Ignore !isprint() +#define FLAG_f (1<<4) // Force uppercase +#define FLAG_d (1<<5) // Ignore !(isalnum()|isspace()) +#define FLAG_z (1<<6) // Input is null terminated, not \n +#define FLAG_s (1<<7) // Stable sort, no ascii fallback at end +#define FLAG_c (1<<8) // Check only. No output, exit(!ordered) +#define FLAG_M (1<<9) // Sort type: date +#define FLAG_b (1<<10) // Ignore leading blanks +#define FLAG_x (1<<11) // Hex sort +#define FLAG_g (1<<18) // Sort type: strtod() // Left off dealing with FLAG_b/FLAG_bb logic... @@ -190,17 +199,17 @@ static struct sort_key *add_key(void) // Perform actual comparison static int compare_values(int flags, char *x, char *y) { - int ff = flags & (FLAG_n|FLAG_g|FLAG_M||FLAG_x); + int ff = flags & (FLAG_n|FLAG_g|FLAG_M|FLAG_x); // Ascii sort if (!ff) return strcmp(x, y); - if (CFG_SORT_BIG && ff == FLAG_g) { + if (CFG_SORT_FLOAT && ff == FLAG_g) { char *xx,*yy; double dx = strtod(x,&xx), dy = strtod(y,&yy); int xinf, yinf; - // not numbers < NaN < -infinity < numbers < +infinity) + // not numbers < NaN < -infinity < numbers < +infinity if (x==xx) return y==yy ? 0 : -1; if (y==yy) return 1; @@ -231,12 +240,12 @@ static int compare_values(int flags, char *x, char *y) else if (!yy) return 1; else return dx==thyme.tm_mon ? 0 : dx-thyme.tm_mon; - // This has to be ff == FLAG_n } else if (CFG_SORT_BIG && ff == FLAG_x) { return strtol(x, NULL, 16)-strtol(y, NULL, 16); + // This has to be ff == FLAG_n } else { // Full floating point version of -n - if (CFG_SORT_BIG) { + if (CFG_SORT_FLOAT) { double dx = atof(x), dy = atof(y); return dx>dy ? 1 : (dx<dy ? -1 : 0); |