From 7ca907824d6f8a5017c3d914d0028a3d50ea619a Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Fri, 15 Jan 2016 12:38:32 -0600 Subject: Fix sort -f, add tests, make TEST_HOST pass new tests. --- scripts/test.sh | 1 + tests/sort.test | 6 ++++++ toys/posix/sort.c | 15 ++++++++------- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/scripts/test.sh b/scripts/test.sh index 81d9f346..352c7bc3 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -20,6 +20,7 @@ fi cd generated/testdir PATH="$PWD:$PATH" cd testdir +export LC_COLLATE=c . "$TOPDIR"/scripts/runtest.sh [ -f "$TOPDIR/generated/config.h" ] && export OPTIONFLAGS=:$(echo $(sed -nr 's/^#define CFG_(.*) 1/\1/p' "$TOPDIR/generated/config.h") | sed 's/ /:/g') diff --git a/tests/sort.test b/tests/sort.test index 7bd413f7..2845e79c 100755 --- a/tests/sort.test +++ b/tests/sort.test @@ -90,6 +90,12 @@ testing "sort key edge case with -t" "sort -n -k4 -t/" \ testing "sort -x" "sort -x" "010\na0\n 0c0\n" "" "a0\n010\n 0c0\n" +# Test that -f applies to key or fallback independently + +testing "" "sort -k2,2f" "A b b\na B C\na B a\n" "" "a B a\nA b b\na B C\n" +testing "" "sort -k2,2" "a B C\na B a\nA b b\n" "" "a B a\nA b b\na B C\n" +testing "" "sort -f -k2,2" "A b b\na B C\na B a\n" "" "a B a\nA b b\na B C\n" + optional SORT_FLOAT # not numbers < NaN < -infinity < numbers < +infinity diff --git a/toys/posix/sort.c b/toys/posix/sort.c index ed7c36ce..a1722fb2 100644 --- a/toys/posix/sort.c +++ b/toys/posix/sort.c @@ -3,6 +3,9 @@ * Copyright 2004, 2008 Rob Landley * * See http://opengroup.org/onlinepubs/007904975/utilities/sort.html + * + * Deviations from POSIX: Lots. + * We invented -x USE_SORT(NEWTOY(sort, USE_SORT_FLOAT("g")USE_SORT_BIG("S:T:m" "o:k*t:xbMcszdfi") "run", TOYFLAG_USR|TOYFLAG_BIN)) @@ -92,7 +95,7 @@ static char *get_key_data(char *str, struct sort_key *key, int flags) // Special case whole string, so we don't have to make a copy if(key->range[0]==1 && !key->range[1] && !key->range[2] && !key->range[3] - && !(flags&(FLAG_b&FLAG_d&FLAG_f&FLAG_i&FLAG_bb))) return str; + && !(flags&(FLAG_b|FLAG_d|FLAG_i|FLAG_bb))) return str; // Find start of key on first pass, end on second pass @@ -155,9 +158,6 @@ static char *get_key_data(char *str, struct sort_key *key, int flags) str[start] = 0; } - // Handle -f - if (flags*FLAG_f) for(i=0; str[i]; i++) str[i] = toupper(str[i]); - return str; } @@ -178,7 +178,7 @@ static int compare_values(int flags, char *x, char *y) int ff = flags & (FLAG_n|FLAG_g|FLAG_M|FLAG_x); // Ascii sort - if (!ff) return strcmp(x, y); + if (!ff) return ((flags&FLAG_f) ? strcasecmp : strcmp)(x, y); if (CFG_SORT_FLOAT && ff == FLAG_g) { char *xx,*yy; @@ -259,10 +259,11 @@ static int compare_keys(const void *xarg, const void *yarg) } } else retval = compare_values(flags, xx, yy); - // Perform fallback sort if necessary + // Perform fallback sort if necessary (always case insensitive, no -f, + // the point is to get a stable order even for -f sorts) if (!retval && !(CFG_SORT_BIG && (toys.optflags&FLAG_s))) { - retval = strcmp(xx, yy); flags = toys.optflags; + retval = strcmp(xx, yy); } return retval * ((flags&FLAG_r) ? -1 : 1); -- cgit v1.2.3