diff --git a/_multibuild b/_multibuild index eb2bf3f..404121f 100644 --- a/_multibuild +++ b/_multibuild @@ -1,4 +1,5 @@ + systemd single testsuite diff --git a/coreutils-9.3.tar.xz b/coreutils-9.3.tar.xz deleted file mode 100644 index 9cb7977..0000000 --- a/coreutils-9.3.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:adbcfcfe899235b71e8768dcf07cd532520b7f54f9a8064843f8d199a904bbaa -size 5808696 diff --git a/coreutils-9.3.tar.xz.sig b/coreutils-9.3.tar.xz.sig deleted file mode 100644 index da0438d..0000000 --- a/coreutils-9.3.tar.xz.sig +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCAAdFiEEbDfcEhIaUAa8HbgE32/ZcTBgN9kFAmQ+r2YACgkQ32/ZcTBg -N9m/sRAAjHEe77ReKYJyJt5xvMY3mq8iSKL5hpKFX3onZwanElPzN+GFQdrvEEl9 -8wSR4YObmcYg3H42oqqC94Ea+qtpUAwJ1DG6JXrBM2x2kKjmV7J1MwsLqkjCprBj -9VSMS6+xy/JB23x2pu+DGCbnBwCO7FZsbmt5h1orb73rR350ty0JOx5whAD6GL6p -+EJ1wNoVRknlGQskuVJBt0mpIf59s5fMlT8mGC22YReuqjf92qO8+CnTGWgUni9n -Lj5IHXUx/AQ4q+cVKHXf3Krwg7wLLRiNaUt/xmEn9buZuVCP09aKa6K+7QfGRE/L -YXaAwcTdAmzk8E0mXr9Z/XOT2+grbPhgJn5pb4L2IVKsqKw8VtJ8btBum1zQR0lP -PzXMpaHMJ/LZPNfeLC48GQ2R+x7uef3quUmTh5EQmq7IVnmZUdP5LUb5Nw44udLv -xUbeRP8aEni0IGTes+UkfP15HXIaqNG6Ij7pQoSzJZskRYJ/hmPp+py24Dv0I20B -rBTRvu+W0Bwpge7c2OcZJSnGEMjagGAzQ1jMpFlqLh9gotUymTy01jjFe1MD/ilL -IPStptSJFV4+LETgeEOdEvPN0E5UQqk7yqUp6bc81DOT6NFnSdWGetMrBy/PJSCn -KyTsNVeKUirimtozwfejUbhIdVA9a8KcDj4/KFLUe4F4cDa+inU= -=YhvD ------END PGP SIGNATURE----- diff --git a/coreutils-9.4.tar.xz b/coreutils-9.4.tar.xz new file mode 100644 index 0000000..a108cb8 --- /dev/null +++ b/coreutils-9.4.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea613a4cf44612326e917201bbbcdfbd301de21ffc3b59b6e5c07e040b275e52 +size 5979200 diff --git a/coreutils-9.4.tar.xz.sig b/coreutils-9.4.tar.xz.sig new file mode 100644 index 0000000..c9dd31c --- /dev/null +++ b/coreutils-9.4.tar.xz.sig @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCAAdFiEEbDfcEhIaUAa8HbgE32/ZcTBgN9kFAmTuCiAACgkQ32/ZcTBg +N9ldkg//bS5pBA3f/2p6sHpZVvtgXhbLPTIczMRuANfzGfjrWqC5UMa3t2g04A2T +gCx4p2cmDv0eBF2esUGirYHq+chGP12dLWKQLdhnyB6gDQS0MTSHNtjT61UXJ2jp +L4vrggrbpDIWzprXfRZH75GbC+D/A2O/Gdm3EKRSv5Jcoe1BgDtoHR8zn4TP4dJP +PlP1QMMoyG6ta/PuTh7/KlaYFLWdBh7mS1FMEl5w2LuG65Ms4MOJZ+wXsdHDA6gk +pgjQYAPSH37dDTSJzfxGNxlEdcTztoSNcOBGGngnCAvxRr3W3KM/ktQlphbYlu3J +9JKGDn3oOnkNxX1iUJLGs4/x0v6d89pdBFhiKqe47ZyJfJ0QQVWoTn79CUc7Gv2G +/NKOoEsnk/1eh4TCxb8WHFu5JU+E1PmLRD3I5uiFFEWhDhPj4xeo6Y74R6+6KLAw +ZArS1gL35aGLfed6Pmr9Nkh7j3jGAcsHVCre7PkCCYOyQArch81iTvG+aHFzSbnM +YLnsoZtfNtmspATFryZ+y8qOyVVK2+aOrgzpXDHUTtY7S1IUJjO8cQUHuG9JpQU1 +YNkr7/w/JVe+2MvGODMiKQPP0/gKDfRQg5WIlKFVSVrEoGcX+ivA9nG6jCf7nWd9 +RdONbO/I69ZI24n0TYkGfal+P1hbt9cogGr4j5kRpstj8eXSDws= +=GOzh +-----END PGP SIGNATURE----- diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 8a9247d..68495a1 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,41 +1,41 @@ -From 01010419a6499768563e7b2f3fd56cf16edda75e Mon Sep 17 00:00:00 2001 +From 3a1b92e80708319bcc89852e3da1029c3d1ff6b3 Mon Sep 17 00:00:00 2001 From: rpm-build -Date: Mon, 4 Oct 2021 08:54:37 +0200 +Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch --- - bootstrap.conf | 1 - configure.ac | 2 - lib/linebuffer.h | 8 - lib/mbfile.c | 3 - lib/mbfile.h | 255 ++++++++++++++ - m4/mbfile.m4 | 14 - src/cut.c | 508 ++++++++++++++++++++++++++-- - src/expand-common.c | 114 ++++++ - src/expand-common.h | 12 - src/expand.c | 90 ++++ - src/fold.c | 312 +++++++++++++++-- - src/join.c | 236 +++++++++++-- - src/local.mk | 4 - src/pr.c | 443 ++++++++++++++++++++++-- - src/sort.c | 793 +++++++++++++++++++++++++++++++++++++++++--- - src/unexpand.c | 102 ++++- - src/uniq.c | 119 ++++++ - tests/Coreutils.pm | 3 - tests/expand/mb.sh | 183 ++++++++++ - tests/i18n/sort.sh | 29 + - tests/local.mk | 4 - tests/misc/expand.pl | 42 ++ - tests/misc/fold.pl | 50 ++ - tests/misc/join.pl | 50 ++ - tests/misc/sort-mb-tests.sh | 45 ++ - tests/misc/sort-merge.pl | 42 ++ - tests/misc/sort.pl | 40 ++ - tests/misc/unexpand.pl | 39 ++ - tests/misc/uniq.pl | 55 +++ - tests/pr/pr-tests.pl | 49 ++ - tests/unexpand/mb.sh | 172 +++++++++ - 31 files changed, 3600 insertions(+), 219 deletions(-) + bootstrap.conf | 1 + + configure.ac | 6 + + lib/linebuffer.h | 8 + + lib/mbfile.c | 3 + + lib/mbfile.h | 255 ++++++++++++ + m4/mbfile.m4 | 14 + + src/cut.c | 508 +++++++++++++++++++++-- + src/expand-common.c | 114 ++++++ + src/expand-common.h | 12 + + src/expand.c | 90 +++- + src/fold.c | 312 ++++++++++++-- + src/join.c | 359 ++++++++++++++-- + src/local.mk | 4 +- + src/pr.c | 443 ++++++++++++++++++-- + src/sort.c | 792 +++++++++++++++++++++++++++++++++--- + src/unexpand.c | 102 ++++- + src/uniq.c | 119 +++++- + tests/Coreutils.pm | 3 + + tests/expand/mb.sh | 183 +++++++++ + tests/i18n/sort.sh | 29 ++ + tests/local.mk | 4 + + tests/misc/expand.pl | 42 ++ + tests/misc/fold.pl | 50 ++- + tests/misc/join.pl | 50 +++ + tests/misc/sort-mb-tests.sh | 45 ++ + tests/misc/unexpand.pl | 39 ++ + tests/pr/pr-tests.pl | 49 +++ + tests/sort/sort-merge.pl | 42 ++ + tests/sort/sort.pl | 40 +- + tests/unexpand/mb.sh | 172 ++++++++ + tests/uniq/uniq.pl | 55 +++ + 31 files changed, 3703 insertions(+), 242 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 @@ -44,11 +44,11 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100755 tests/misc/sort-mb-tests.sh create mode 100755 tests/unexpand/mb.sh -Index: bootstrap.conf -=================================================================== ---- bootstrap.conf.orig -+++ bootstrap.conf -@@ -165,6 +165,7 @@ gnulib_modules=" +diff --git a/bootstrap.conf b/bootstrap.conf +index bd73ff2..0e450cd 100644 +--- a/bootstrap.conf ++++ b/bootstrap.conf +@@ -167,6 +167,7 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -56,23 +56,27 @@ Index: bootstrap.conf mbrlen mbrtowc mbsalign -Index: configure.ac -=================================================================== ---- configure.ac.orig -+++ configure.ac -@@ -477,6 +477,8 @@ fi +diff --git a/configure.ac b/configure.ac +index 8ffc0b7..ca3305d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -448,6 +448,12 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM +gl_MBFILE ++dnl Do not use gl_MODULE_INDICATOR([mbfile]) here: we don't want 'struct mbchar' ++dnl to have a different size in lib/ than in tests/. ++AC_DEFINE([GNULIB_MBFILE], [1], ++ [Define to 1 if the gnulib module 'mbfile' is in use.]) + gl_HEADER_TIOCGWINSZ_IN_TERMIOS_H if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ -Index: lib/linebuffer.h -=================================================================== ---- lib/linebuffer.h.orig -+++ lib/linebuffer.h +diff --git a/lib/linebuffer.h b/lib/linebuffer.h +index b4cc8e4..f2bbb52 100644 +--- a/lib/linebuffer.h ++++ b/lib/linebuffer.h @@ -22,6 +22,11 @@ # include "idx.h" # include @@ -95,18 +99,20 @@ Index: lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -Index: lib/mbfile.c -=================================================================== +diff --git a/lib/mbfile.c b/lib/mbfile.c +new file mode 100644 +index 0000000..b0a468e --- /dev/null -+++ lib/mbfile.c ++++ b/lib/mbfile.c @@ -0,0 +1,3 @@ +#include +#define MBFILE_INLINE _GL_EXTERN_INLINE +#include "mbfile.h" -Index: lib/mbfile.h -=================================================================== +diff --git a/lib/mbfile.h b/lib/mbfile.h +new file mode 100644 +index 0000000..11f1b12 --- /dev/null -+++ lib/mbfile.h ++++ b/lib/mbfile.h @@ -0,0 +1,255 @@ +/* Multibyte character I/O: macros for multi-byte encodings. + Copyright (C) 2001, 2005, 2009-2015 Free Software Foundation, Inc. @@ -363,10 +369,11 @@ Index: lib/mbfile.h +_GL_INLINE_HEADER_BEGIN + +#endif /* _MBFILE_H */ -Index: m4/mbfile.m4 -=================================================================== +diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 +new file mode 100644 +index 0000000..8589902 --- /dev/null -+++ m4/mbfile.m4 ++++ b/m4/mbfile.m4 @@ -0,0 +1,14 @@ +# mbfile.m4 serial 7 +dnl Copyright (C) 2005, 2008-2015 Free Software Foundation, Inc. @@ -382,12 +389,12 @@ Index: m4/mbfile.m4 + AC_REQUIRE([AC_TYPE_MBSTATE_T]) + : +]) -Index: src/cut.c -=================================================================== ---- src/cut.c.orig -+++ src/cut.c -@@ -28,6 +28,11 @@ - #include +diff --git a/src/cut.c b/src/cut.c +index b4edbab..65e4658 100644 +--- a/src/cut.c ++++ b/src/cut.c +@@ -27,6 +27,11 @@ + #include #include #include + @@ -397,8 +404,8 @@ Index: src/cut.c +#endif #include "system.h" - #include "error.h" -@@ -36,6 +41,18 @@ + #include "assure.h" +@@ -35,6 +40,18 @@ #include "set-fields.h" @@ -417,7 +424,7 @@ Index: src/cut.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "cut" -@@ -52,6 +69,52 @@ +@@ -51,6 +68,52 @@ } \ while (0) @@ -470,8 +477,8 @@ Index: src/cut.c /* Pointer inside RP. When checking if a byte or field is selected by a finite range, we check if it is between CURRENT_RP.LO -@@ -59,6 +122,9 @@ - CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ +@@ -58,6 +121,9 @@ + CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ static struct field_range_pair *current_rp; +/* Length of the delimiter given as argument to -d. */ @@ -480,7 +487,7 @@ Index: src/cut.c /* This buffer is used to support the semantics of the -s option (or lack of same) when the specified field list includes (does not include) the first field. In both of those cases, the entire -@@ -71,6 +137,29 @@ static char *field_1_buffer; +@@ -70,6 +136,29 @@ static char *field_1_buffer; /* The number of bytes allocated for FIELD_1_BUFFER. */ static size_t field_1_bufsize; @@ -507,18 +514,18 @@ Index: src/cut.c + if this program runs on multibyte locale. */ +static int force_singlebyte_mode; + - /* If true do not output lines containing no delimiter characters. + /* If true, do not output lines containing no delimiter characters. Otherwise, all such lines are printed. This option is valid only with field mode. */ -@@ -82,10 +171,16 @@ static bool complement; +@@ -81,10 +170,16 @@ static bool complement; - /* The delimiter character for field mode. */ + /* The delimiter character for field mode. */ static unsigned char delim; +#if HAVE_WCHAR_H +static wchar_t wcdelim; +#endif - /* The delimiter for each line/record. */ + /* The delimiter for each line/record. */ static unsigned char line_delim = '\n'; +/* True if the --output-delimiter=STRING option was specified. */ @@ -527,17 +534,17 @@ Index: src/cut.c /* The length of output_delimiter_string. */ static size_t output_delimiter_length; -@@ -93,9 +188,6 @@ static size_t output_delimiter_length; +@@ -92,9 +187,6 @@ static size_t output_delimiter_length; string consisting of the input delimiter. */ static char *output_delimiter_string; -/* The output delimiter string contents, if the default. */ -static char output_delimiter_default[1]; - - /* True if we have ever read standard input. */ + /* True if we have ever read standard input. */ static bool have_read_stdin; -@@ -149,7 +241,7 @@ Print selected parts of lines from each +@@ -148,7 +240,7 @@ Print selected parts of lines from each FILE to standard output.\n\ -f, --fields=LIST select only these fields; also print any line\n\ that contains no delimiter character, unless\n\ the -s option is specified\n\ @@ -546,7 +553,7 @@ Index: src/cut.c "), stdout); fputs (_("\ --complement complement the set of selected bytes, characters\n\ -@@ -249,7 +341,7 @@ cut_bytes (FILE *stream) +@@ -252,7 +344,7 @@ cut_bytes (FILE *stream) next_item (&byte_idx); if (print_kth (byte_idx)) { @@ -555,7 +562,7 @@ Index: src/cut.c { if (print_delimiter && is_range_start_index (byte_idx)) { -@@ -265,6 +357,82 @@ cut_bytes (FILE *stream) +@@ -271,6 +363,82 @@ cut_bytes (FILE *stream) } } @@ -638,7 +645,7 @@ Index: src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -410,11 +578,218 @@ cut_fields (FILE *stream) +@@ -433,11 +601,218 @@ cut_fields (FILE *stream) } } @@ -859,18 +866,18 @@ Index: src/cut.c { FILE *stream; -@@ -458,8 +833,8 @@ main (int argc, char **argv) +@@ -482,8 +857,8 @@ main (int argc, char **argv) int optc; bool ok; bool delim_specified = false; - bool byte_mode = false; -- char *spec_list_string = NULL; -+ char *spec_list_string IF_LINT ( = NULL); +- char *spec_list_string = nullptr; ++ char *spec_list_string IF_LINT ( = nullptr); + char mbdelim[MB_LEN_MAX + 1]; initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -469,6 +844,8 @@ main (int argc, char **argv) +@@ -493,6 +868,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -879,12 +886,12 @@ Index: src/cut.c /* By default, all non-delimited lines are printed. */ suppress_non_delimited = false; -@@ -480,35 +857,77 @@ main (int argc, char **argv) +@@ -505,35 +882,77 @@ main (int argc, char **argv) switch (optc) { case 'b': - case 'c': - /* Build the byte list. */ + /* Build the byte list. */ - byte_mode = true; - FALLTHROUGH; + if (operating_mode != undefined_mode) @@ -894,7 +901,7 @@ Index: src/cut.c + break; + + case 'c': -+ /* Build the character list. */ ++ /* Build the character list. */ + if (operating_mode != undefined_mode) + FATAL_ERROR (_("only one type of list may be specified")); + operating_mode = character_mode; @@ -902,7 +909,7 @@ Index: src/cut.c + break; + case 'f': - /* Build the field list. */ + /* Build the field list. */ - if (spec_list_string) - FATAL_ERROR (_("only one list may be specified")); + if (operating_mode != undefined_mode) @@ -912,7 +919,7 @@ Index: src/cut.c break; case 'd': - /* New delimiter. */ + /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ - if (optarg[0] != '\0' && optarg[1] != '\0') - FATAL_ERROR (_("the delimiter must be a single character")); @@ -967,7 +974,7 @@ Index: src/cut.c break; case 's': -@@ -532,40 +951,57 @@ main (int argc, char **argv) +@@ -555,40 +974,57 @@ main (int argc, char **argv) } } @@ -1008,7 +1015,7 @@ Index: src/cut.c +#endif + } - if (output_delimiter_string == NULL) + if (output_delimiter_string == nullptr) { - output_delimiter_default[0] = delim; - output_delimiter_string = output_delimiter_default; @@ -1042,19 +1049,19 @@ Index: src/cut.c if (have_read_stdin && fclose (stdin) == EOF) -Index: src/expand-common.c -=================================================================== ---- src/expand-common.c.orig -+++ src/expand-common.c -@@ -19,6 +19,7 @@ - #include +diff --git a/src/expand-common.c b/src/expand-common.c +index 89fa56a..c102e6e 100644 +--- a/src/expand-common.c ++++ b/src/expand-common.c +@@ -18,6 +18,7 @@ + #include #include +#include #include "system.h" - #include "die.h" - #include "error.h" -@@ -125,6 +126,119 @@ set_increment_size (uintmax_t tabval) + #include "fadvise.h" + #include "quote.h" +@@ -122,6 +123,119 @@ set_increment_size (uintmax_t tabval) return ok; } @@ -1174,10 +1181,10 @@ Index: src/expand-common.c /* Add the comma or blank separated list of tab stops STOPS to the list of tab stops. */ extern void -Index: src/expand-common.h -=================================================================== ---- src/expand-common.h.orig -+++ src/expand-common.h +diff --git a/src/expand-common.h b/src/expand-common.h +index daed31e..f6b2f68 100644 +--- a/src/expand-common.h ++++ b/src/expand-common.h @@ -25,6 +25,18 @@ extern size_t max_column_width; /* The desired exit status. */ extern int exit_status; @@ -1197,10 +1204,10 @@ Index: src/expand-common.h /* Add tab stop TABVAL to the end of 'tab_list'. */ extern void add_tab_stop (uintmax_t tabval); -Index: src/expand.c -=================================================================== ---- src/expand.c.orig -+++ src/expand.c +diff --git a/src/expand.c b/src/expand.c +index 0e74d0c..7080c51 100644 +--- a/src/expand.c ++++ b/src/expand.c @@ -37,6 +37,9 @@ #include #include @@ -1209,12 +1216,12 @@ Index: src/expand.c +#include + #include "system.h" - #include "die.h" + #include "expand-common.h" -@@ -97,19 +100,41 @@ expand (void) +@@ -95,19 +98,41 @@ expand (void) { /* Input stream. */ - FILE *fp = next_file (NULL); + FILE *fp = next_file (nullptr); + mb_file_t mbf; + mbf_char_t c; + /* True if the starting locale is utf8. */ @@ -1242,12 +1249,12 @@ Index: src/expand.c + } + } + - ++ + if (found_bom == true) + { + print_bom(); + } -+ + + while (true) + { /* If true, perform translations. */ @@ -1257,7 +1264,7 @@ Index: src/expand.c /* The following variables have valid values only when CONVERT is true: */ -@@ -119,17 +144,48 @@ expand (void) +@@ -117,17 +142,48 @@ expand (void) /* Index in TAB_LIST of next tab stop to examine. */ size_t tab_index = 0; @@ -1310,9 +1317,9 @@ Index: src/expand.c { /* Column the next input tab stop is on. */ uintmax_t next_tab_column; -@@ -148,32 +204,34 @@ expand (void) +@@ -146,32 +202,34 @@ expand (void) if (putchar (' ') < 0) - die (EXIT_FAILURE, errno, _("write error")); + write_error (); - c = ' '; + mb_setascii (&c, ' '); @@ -1332,7 +1339,7 @@ Index: src/expand.c - column++; + column += mb_width (c); if (!column) - die (EXIT_FAILURE, 0, _("input line is too long")); + error (EXIT_FAILURE, 0, _("input line is too long")); } - convert &= convert_entire_line || !! isblank (c); @@ -1346,18 +1353,18 @@ Index: src/expand.c - if (putchar (c) < 0) + mb_putc (c, stdout); + if (ferror (stdout)) - die (EXIT_FAILURE, errno, _("write error")); + write_error (); } - while (c != '\n'); + while (!mb_iseq (c, '\n')); } } -Index: src/fold.c -=================================================================== ---- src/fold.c.orig -+++ src/fold.c -@@ -22,12 +22,34 @@ +diff --git a/src/fold.c b/src/fold.c +index 5c0428d..2372047 100644 +--- a/src/fold.c ++++ b/src/fold.c +@@ -22,10 +22,32 @@ #include #include @@ -1372,8 +1379,6 @@ Index: src/fold.c +#endif + #include "system.h" - #include "die.h" - #include "error.h" #include "fadvise.h" #include "xdectoint.h" @@ -1392,7 +1397,7 @@ Index: src/fold.c #define TAB_WIDTH 8 /* The official name of this program (e.g., no 'g' prefix). */ -@@ -35,20 +57,41 @@ +@@ -33,20 +55,41 @@ #define AUTHORS proper_name ("David MacKenzie") @@ -1433,12 +1438,12 @@ Index: src/fold.c static struct option const longopts[] = { - {"bytes", no_argument, NULL, 'b'}, -+ {"characters", no_argument, NULL, 'c'}, - {"spaces", no_argument, NULL, 's'}, - {"width", required_argument, NULL, 'w'}, + {"bytes", no_argument, nullptr, 'b'}, ++ {"characters", no_argument, nullptr, 'c'}, + {"spaces", no_argument, nullptr, 's'}, + {"width", required_argument, nullptr, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -76,6 +119,7 @@ Wrap input lines in each FILE, writing t +@@ -74,6 +117,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ fputs (_("\ -b, --bytes count bytes rather than columns\n\ @@ -1446,7 +1451,7 @@ Index: src/fold.c -s, --spaces break at spaces\n\ -w, --width=WIDTH use WIDTH columns instead of 80\n\ "), stdout); -@@ -93,7 +137,7 @@ Wrap input lines in each FILE, writing t +@@ -91,7 +135,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ static size_t adjust_column (size_t column, char c) { @@ -1455,7 +1460,7 @@ Index: src/fold.c { if (c == '\b') { -@@ -116,30 +160,14 @@ adjust_column (size_t column, char c) +@@ -114,30 +158,14 @@ adjust_column (size_t column, char c) to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -1468,7 +1473,7 @@ Index: src/fold.c int c; size_t column = 0; /* Screen column where next char will go. */ size_t offset_out = 0; /* Index in 'line_out' for next char. */ - static char *line_out = NULL; + static char *line_out = nullptr; static size_t allocated_out = 0; - int saved_errno; - @@ -1480,7 +1485,7 @@ Index: src/fold.c - else - istream = fopen (filename, "r"); - -- if (istream == NULL) +- if (istream == nullptr) - { - error (0, errno, "%s", quotef (filename)); - return false; @@ -1488,7 +1493,7 @@ Index: src/fold.c fadvise (istream, FADVISE_SEQUENTIAL); -@@ -169,6 +197,15 @@ fold_file (char const *filename, size_t +@@ -167,6 +195,15 @@ fold_file (char const *filename, size_t width) bool found_blank = false; size_t logical_end = offset_out; @@ -1504,7 +1509,7 @@ Index: src/fold.c /* Look for the last blank. */ while (logical_end) { -@@ -215,13 +252,225 @@ fold_file (char const *filename, size_t +@@ -213,13 +250,225 @@ fold_file (char const *filename, size_t width) line_out[offset_out++] = c; } @@ -1732,7 +1737,7 @@ Index: src/fold.c if (STREQ (filename, "-")) clearerr (istream); else if (fclose (istream) != 0 && !saved_errno) -@@ -252,7 +501,8 @@ main (int argc, char **argv) +@@ -250,7 +499,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1740,9 +1745,9 @@ Index: src/fold.c + operating_mode = column_mode; + break_spaces = have_read_stdin = false; - while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) + while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1) { -@@ -261,7 +511,15 @@ main (int argc, char **argv) +@@ -259,7 +509,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -1759,11 +1764,11 @@ Index: src/fold.c break; case 's': /* Break at word boundaries. */ -Index: src/join.c -=================================================================== ---- src/join.c.orig -+++ src/join.c -@@ -22,19 +22,33 @@ +diff --git a/src/join.c b/src/join.c +index 0bcfa75..8a3bcf1 100644 +--- a/src/join.c ++++ b/src/join.c +@@ -21,18 +21,32 @@ #include #include @@ -1778,8 +1783,7 @@ Index: src/join.c +#endif + #include "system.h" - #include "die.h" - #include "error.h" + #include "assure.h" #include "fadvise.h" #include "hard-locale.h" #include "linebuffer.h" @@ -1798,7 +1802,7 @@ Index: src/join.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "join" -@@ -136,10 +150,12 @@ static struct outlist outlist_head; +@@ -134,10 +148,12 @@ static struct outlist outlist_head; /* Last element in 'outlist', where a new element can be added. */ static struct outlist *outlist_end = &outlist_head; @@ -1810,12 +1814,12 @@ Index: src/join.c + by any nonempty string of blanks. */ +static char *tab = NULL; + -+/* The number of bytes used for tab. */ ++/* The number of bytes used for tab. */ +static size_t tablen = 0; /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -280,13 +296,14 @@ xfields (struct line *line) +@@ -277,13 +293,14 @@ xfields (struct line *line) if (ptr == lim) return; @@ -1824,8 +1828,8 @@ Index: src/join.c { + unsigned char t = tab[0]; char *sep; -- for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1) -+ for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1) +- for (; (sep = memchr (ptr, tab, lim - ptr)) != nullptr; ptr = sep + 1) ++ for (; (sep = memchr (ptr, t, lim - ptr)) != nullptr; ptr = sep + 1) extract_field (line, ptr, sep - ptr); } - else if (tab < 0) @@ -1833,7 +1837,7 @@ Index: src/join.c { /* Skip leading blanks before the first field. */ while (field_sep (*ptr)) -@@ -310,6 +327,147 @@ xfields (struct line *line) +@@ -307,6 +324,147 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1981,7 +1985,164 @@ Index: src/join.c static void freeline (struct line *line) { -@@ -472,6 +630,11 @@ get_line (FILE *fp, struct line **linep, +@@ -328,56 +486,133 @@ keycmp (struct line const *line1, struct line const *line2, + idx_t jf_1, idx_t jf_2) + { + /* Start of field to compare in each file. */ +- char *beg1; +- char *beg2; +- +- idx_t len1; +- idx_t len2; /* Length of fields to compare. */ ++ char *beg[2]; ++ char *copy[2]; ++ idx_t len[2]; /* Length of fields to compare. */ + int diff; ++ int i, j; ++ int mallocd = 0; + + if (jf_1 < line1->nfields) + { +- beg1 = line1->fields[jf_1].beg; +- len1 = line1->fields[jf_1].len; ++ beg[0] = line1->fields[jf_1].beg; ++ len[0] = line1->fields[jf_1].len; + } + else + { +- beg1 = nullptr; +- len1 = 0; ++ beg[0] = nullptr; ++ len[0] = 0; + } + + if (jf_2 < line2->nfields) + { +- beg2 = line2->fields[jf_2].beg; +- len2 = line2->fields[jf_2].len; ++ beg[1] = line2->fields[jf_2].beg; ++ len[1] = line2->fields[jf_2].len; + } + else + { +- beg2 = nullptr; +- len2 = 0; ++ beg[1] = nullptr; ++ len[1] = 0; + } + +- if (len1 == 0) +- return len2 == 0 ? 0 : -1; +- if (len2 == 0) ++ if (len[0] == 0) ++ return len[1] == 0 ? 0 : -1; ++ if (len[1] == 0) + return 1; + + if (ignore_case) + { +- /* FIXME: ignore_case does not work with NLS (in particular, +- with multibyte chars). */ +- diff = memcasecmp (beg1, beg2, MIN (len1, len2)); ++#ifdef HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ size_t mblength; ++ wchar_t wc, uwc; ++ mbstate_t state, state_bak; ++ ++ memset (&state, '\0', sizeof (mbstate_t)); ++ ++ for (i = 0; i < 2; i++) ++ { ++ mallocd = 1; ++ copy[i] = xmalloc (len[i] + 1); ++ memset (copy[i], '\0',len[i] + 1); ++ ++ for (j = 0; j < MIN (len[0], len[1]);) ++ { ++ state_bak = state; ++ mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state); ++ ++ switch (mblength) ++ { ++ case (size_t) -1: ++ case (size_t) -2: ++ state = state_bak; ++ /* Fall through */ ++ case 0: ++ mblength = 1; ++ break; ++ ++ default: ++ uwc = towupper (wc); ++ ++ if (uwc != wc) ++ { ++ mbstate_t state_wc; ++ size_t mblen; ++ ++ memset (&state_wc, '\0', sizeof (mbstate_t)); ++ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); ++ assert (mblen != (size_t)-1); ++ } ++ else ++ memcpy (copy[i] + j, beg[i] + j, mblength); ++ } ++ j += mblength; ++ } ++ copy[i][j] = '\0'; ++ } ++ } ++ else ++#endif ++ { ++ for (i = 0; i < 2; i++) ++ { ++ mallocd = 1; ++ copy[i] = xmalloc (len[i] + 1); ++ ++ for (j = 0; j < MIN (len[0], len[1]); j++) ++ copy[i][j] = toupper (beg[i][j]); ++ ++ copy[i][j] = '\0'; ++ } ++ } + } + else + { +- if (hard_LC_COLLATE) +- return xmemcoll (beg1, len1, beg2, len2); +- diff = memcmp (beg1, beg2, MIN (len1, len2)); ++ copy[0] = beg[0]; ++ copy[1] = beg[1]; + } + ++ if (hard_LC_COLLATE) ++ { ++ diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); ++ ++ if (mallocd) ++ for (i = 0; i < 2; i++) ++ free (copy[i]); ++ ++ return diff; ++ } ++ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); ++ ++ if (mallocd) ++ for (i = 0; i < 2; i++) ++ free (copy[i]); ++ ++ + if (diff) + return diff; +- return (len1 > len2) - (len1 < len2); ++ return len[0] - len[1]; + } + + /* Check that successive input lines PREV and CURRENT from input file +@@ -469,6 +704,11 @@ get_line (FILE *fp, struct line **linep, int which) } ++line_no[which - 1]; @@ -1993,7 +2154,7 @@ Index: src/join.c xfields (line); if (prevline[which - 1]) -@@ -567,21 +730,28 @@ prfield (size_t n, struct line const *li +@@ -562,21 +802,28 @@ prfield (idx_t n, struct line const *line) /* Output all the fields in line, other than the join field. */ @@ -2006,10 +2167,10 @@ Index: src/join.c + while (0) + static void - prfields (struct line const *line, size_t join_field, size_t autocount) + prfields (struct line const *line, idx_t join_field, idx_t autocount) { - size_t i; - size_t nfields = autoformat ? autocount : line->nfields; + idx_t i; + idx_t nfields = autoformat ? autocount : line->nfields; - char output_separator = tab < 0 ? ' ' : tab; for (i = 0; i < join_field && i < nfields; ++i) @@ -2025,24 +2186,24 @@ Index: src/join.c prfield (i, line); } } -@@ -592,7 +762,6 @@ static void +@@ -587,7 +834,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; - char output_separator = tab < 0 ? ' ' : tab; - size_t field; + idx_t field; struct line const *line; -@@ -626,7 +795,7 @@ prjoin (struct line const *line1, struct +@@ -621,7 +867,7 @@ prjoin (struct line const *line1, struct line const *line2) o = o->next; - if (o == NULL) + if (o == nullptr) break; - putchar (output_separator); + PUT_TAB_CHAR; } putchar (eolchar); } -@@ -1102,20 +1271,43 @@ main (int argc, char **argv) +@@ -1086,20 +1332,43 @@ main (int argc, char **argv) case 't': { @@ -2075,8 +2236,8 @@ Index: src/join.c - if (STREQ (optarg, "\\0")) - newtab = '\0'; - else -- die (EXIT_FAILURE, 0, _("multi-character tab %s"), -- quote (optarg)); +- error (EXIT_FAILURE, 0, _("multi-character tab %s"), +- quote (optarg)); + if (newtablen == 1 && newtab[1]) + { + if (STREQ (newtab, "\\0")) @@ -2086,20 +2247,20 @@ Index: src/join.c + if (tab != NULL && strcmp (tab, newtab)) + { + free (newtab); -+ die (EXIT_FAILURE, 0, _("incompatible tabs")); ++ error (EXIT_FAILURE, 0, _("incompatible tabs")); } - if (0 <= tab && tab != newtab) -- die (EXIT_FAILURE, 0, _("incompatible tabs")); +- error (EXIT_FAILURE, 0, _("incompatible tabs")); tab = newtab; + tablen = newtablen; } break; -Index: src/local.mk -=================================================================== ---- src/local.mk.orig -+++ src/local.mk -@@ -438,8 +438,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(A +diff --git a/src/local.mk b/src/local.mk +index f45b911..6f7036a 100644 +--- a/src/local.mk ++++ b/src/local.mk +@@ -447,8 +447,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -2110,13 +2271,13 @@ Index: src/local.mk src_wc_SOURCES = src/wc.c if USE_AVX2_WC_LINECOUNT -Index: src/pr.c -=================================================================== ---- src/pr.c.orig -+++ src/pr.c -@@ -311,6 +311,24 @@ - +diff --git a/src/pr.c b/src/pr.c +index 419545c..702e025 100644 +--- a/src/pr.c ++++ b/src/pr.c +@@ -312,6 +312,24 @@ #include + #include #include + +/* Get MB_LEN_MAX. */ @@ -2137,9 +2298,9 @@ Index: src/pr.c +#endif + #include "system.h" - #include "die.h" - #include "error.h" -@@ -325,6 +343,18 @@ + #include "fadvise.h" + #include "hard-locale.h" +@@ -324,6 +342,18 @@ #include "xstrtol-error.h" #include "xdectoint.h" @@ -2158,7 +2319,7 @@ Index: src/pr.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" -@@ -417,7 +447,20 @@ struct COLUMN +@@ -416,7 +446,20 @@ struct COLUMN typedef struct COLUMN COLUMN; @@ -2180,7 +2341,7 @@ Index: src/pr.c static bool read_line (COLUMN *p); static bool print_page (void); static bool print_stored (COLUMN *p); -@@ -429,6 +472,7 @@ static void add_line_number (COLUMN *p); +@@ -428,6 +471,7 @@ static void add_line_number (COLUMN *p); static void getoptnum (char const *n_str, int min, int *num, char const *errfmt); static void getoptarg (char *arg, char switch_char, char *character, @@ -2188,7 +2349,7 @@ Index: src/pr.c int *number); static void print_files (int number_of_files, char **av); static void init_parameters (int number_of_files); -@@ -442,7 +486,6 @@ static void store_char (char c); +@@ -441,7 +485,6 @@ static void store_char (char c); static void pad_down (unsigned int lines); static void read_rest_of_line (COLUMN *p); static void skip_read (COLUMN *p, int column_number); @@ -2196,7 +2357,7 @@ Index: src/pr.c static void cleanup (void); static void print_sep_string (void); static void separator_string (char const *optarg_S); -@@ -454,7 +497,7 @@ static COLUMN *column_vector; +@@ -453,7 +496,7 @@ static COLUMN *column_vector; we store the leftmost columns contiguously in buff. To print a line from buff, get the index of the first character from line_vector[i], and print up to line_vector[i + 1]. */ @@ -2205,7 +2366,7 @@ Index: src/pr.c /* Index of the position in buff where the next character will be stored. */ -@@ -558,7 +601,7 @@ static int chars_per_column; +@@ -557,7 +600,7 @@ static int chars_per_column; static bool untabify_input = false; /* (-e) The input tab character. */ @@ -2214,7 +2375,7 @@ Index: src/pr.c /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... where the leftmost column is 1. */ -@@ -568,7 +611,10 @@ static int chars_per_input_tab = 8; +@@ -567,7 +610,10 @@ static int chars_per_input_tab = 8; static bool tabify_output = false; /* (-i) The output tab character. */ @@ -2226,7 +2387,7 @@ Index: src/pr.c /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -638,7 +684,13 @@ static int line_number; +@@ -637,7 +683,13 @@ static int line_number; static bool numbered_lines = false; /* (-n) Character which follows each line number. */ @@ -2241,7 +2402,7 @@ Index: src/pr.c /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ -@@ -691,6 +743,7 @@ static bool use_col_separator = false; +@@ -690,6 +742,7 @@ static bool use_col_separator = false; -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ static char const *col_sep_string = ""; static int col_sep_length = 0; @@ -2249,7 +2410,7 @@ Index: src/pr.c static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -853,6 +906,13 @@ separator_string (char const *optarg_S) +@@ -852,6 +905,13 @@ separator_string (char const *optarg_S) integer_overflow (); col_sep_length = len; col_sep_string = optarg_S; @@ -2263,7 +2424,7 @@ Index: src/pr.c } int -@@ -877,6 +937,21 @@ main (int argc, char **argv) +@@ -876,6 +936,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -2285,7 +2446,7 @@ Index: src/pr.c n_files = 0; file_names = (argc > 1 ? xnmalloc (argc - 1, sizeof (char *)) -@@ -953,8 +1028,12 @@ main (int argc, char **argv) +@@ -952,8 +1027,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -2300,7 +2461,7 @@ Index: src/pr.c /* Could check tab width > 0. */ untabify_input = true; break; -@@ -967,8 +1046,12 @@ main (int argc, char **argv) +@@ -966,8 +1045,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -2315,7 +2476,7 @@ Index: src/pr.c /* Could check tab width > 0. */ tabify_output = true; break; -@@ -986,8 +1069,8 @@ main (int argc, char **argv) +@@ -985,8 +1068,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -2326,7 +2487,7 @@ Index: src/pr.c break; case 'N': skip_count = false; -@@ -1012,6 +1095,7 @@ main (int argc, char **argv) +@@ -1011,6 +1094,7 @@ main (int argc, char **argv) /* Reset an additional input of -s, -S dominates -s */ col_sep_string = ""; col_sep_length = 0; @@ -2334,7 +2495,7 @@ Index: src/pr.c use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1166,10 +1250,45 @@ getoptnum (char const *n_str, int min, i +@@ -1165,7 +1249,8 @@ getoptnum (char const *n_str, int min, int *num, char const *err) a number. */ static void @@ -2342,6 +2503,11 @@ Index: src/pr.c +getoptarg (char *arg, char switch_char, char *character, int *character_length, + int *character_width, int *number) { + if (!*arg) + { +@@ -1174,7 +1259,41 @@ getoptarg (char *arg, char switch_char, char *character, int *number) + } + if (!ISDIGIT (*arg)) - *character = *arg++; + { @@ -2382,7 +2548,7 @@ Index: src/pr.c if (*arg) { long int tmp_long; -@@ -1198,6 +1317,11 @@ static void +@@ -1203,6 +1322,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -2394,7 +2560,7 @@ Index: src/pr.c lines_per_body = lines_per_page - lines_per_header - lines_per_footer; if (lines_per_body <= 0) -@@ -1235,7 +1359,7 @@ init_parameters (int number_of_files) +@@ -1240,7 +1364,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -2403,7 +2569,7 @@ Index: src/pr.c use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1267,11 +1391,11 @@ init_parameters (int number_of_files) +@@ -1272,11 +1396,11 @@ init_parameters (int number_of_files) + TAB_WIDTH (chars_per_input_tab, chars_per_number); */ /* Estimate chars_per_text without any margin and keep it constant. */ @@ -2417,16 +2583,16 @@ Index: src/pr.c /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1280,7 +1404,7 @@ init_parameters (int number_of_files) +@@ -1285,7 +1409,7 @@ init_parameters (int number_of_files) } int sep_chars, useful_chars; -- if (INT_MULTIPLY_WRAPV (columns - 1, col_sep_length, &sep_chars)) -+ if (INT_MULTIPLY_WRAPV (columns - 1, col_sep_width, &sep_chars)) +- if (ckd_mul (&sep_chars, columns - 1, col_sep_length)) ++ if (ckd_mul (&sep_chars, columns - 1, col_sep_width)) sep_chars = INT_MAX; - if (INT_SUBTRACT_WRAPV (chars_per_line - chars_used_by_number, sep_chars, - &useful_chars)) -@@ -1303,7 +1427,7 @@ init_parameters (int number_of_files) + if (ckd_sub (&useful_chars, chars_per_line - chars_used_by_number, + sep_chars)) +@@ -1308,7 +1432,7 @@ init_parameters (int number_of_files) We've to use 8 as the lower limit, if we use chars_per_default_tab = 8 to expand a tab which is not an input_tab-char. */ free (clump_buff); @@ -2435,7 +2601,7 @@ Index: src/pr.c } /* Open the necessary files, -@@ -1409,7 +1533,7 @@ init_funcs (void) +@@ -1414,7 +1538,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -2444,7 +2610,7 @@ Index: src/pr.c /* This loop takes care of all but the rightmost column. */ -@@ -1443,7 +1567,7 @@ init_funcs (void) +@@ -1448,7 +1572,7 @@ init_funcs (void) } else { @@ -2453,7 +2619,7 @@ Index: src/pr.c h_next = h + chars_per_column; } } -@@ -1740,9 +1864,9 @@ static void +@@ -1745,9 +1869,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -2465,7 +2631,7 @@ Index: src/pr.c padding_not_printed = ANYWHERE; } -@@ -2017,13 +2141,13 @@ store_char (char c) +@@ -2021,13 +2145,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -2481,7 +2647,7 @@ Index: src/pr.c char *s; int num_width; -@@ -2040,22 +2164,24 @@ add_line_number (COLUMN *p) +@@ -2044,22 +2168,24 @@ add_line_number (COLUMN *p) /* Tabification is assumed for multiple columns, also for n-separators, but 'default n-separator = TAB' hasn't been given priority over equal column_width also specified by POSIX. */ @@ -2510,7 +2676,7 @@ Index: src/pr.c output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2214,7 +2340,7 @@ print_white_space (void) +@@ -2218,7 +2344,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2519,7 +2685,7 @@ Index: src/pr.c h_old = h_new; } while (++h_old <= goal) -@@ -2234,6 +2360,7 @@ print_sep_string (void) +@@ -2238,6 +2364,7 @@ print_sep_string (void) { char const *s = col_sep_string; int l = col_sep_length; @@ -2527,7 +2693,7 @@ Index: src/pr.c if (separators_not_printed <= 0) { -@@ -2245,6 +2372,7 @@ print_sep_string (void) +@@ -2249,6 +2376,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2535,7 +2701,7 @@ Index: src/pr.c while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2258,12 +2386,15 @@ print_sep_string (void) +@@ -2262,12 +2390,15 @@ print_sep_string (void) } else { @@ -2552,7 +2718,7 @@ Index: src/pr.c /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2291,7 +2422,7 @@ print_clump (COLUMN *p, int n, char *clu +@@ -2295,7 +2426,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -2561,7 +2727,7 @@ Index: src/pr.c { if (tabify_output) { -@@ -2315,6 +2446,74 @@ print_char (char c) +@@ -2319,6 +2450,74 @@ print_char (char c) putchar (c); } @@ -2636,7 +2802,7 @@ Index: src/pr.c /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2492,9 +2691,9 @@ read_line (COLUMN *p) +@@ -2496,9 +2695,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2648,7 +2814,7 @@ Index: src/pr.c padding_not_printed = ANYWHERE; } -@@ -2563,7 +2762,7 @@ print_stored (COLUMN *p) +@@ -2567,7 +2766,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -2657,7 +2823,7 @@ Index: src/pr.c /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2575,7 +2774,7 @@ print_stored (COLUMN *p) +@@ -2579,7 +2778,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -2666,7 +2832,7 @@ Index: src/pr.c pad_vertically = true; -@@ -2595,9 +2794,9 @@ print_stored (COLUMN *p) +@@ -2599,9 +2798,9 @@ print_stored (COLUMN *p) } } @@ -2678,7 +2844,7 @@ Index: src/pr.c padding_not_printed = ANYWHERE; } -@@ -2610,8 +2809,8 @@ print_stored (COLUMN *p) +@@ -2614,8 +2813,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2689,7 +2855,7 @@ Index: src/pr.c } return true; -@@ -2630,7 +2829,7 @@ print_stored (COLUMN *p) +@@ -2634,7 +2833,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2698,7 +2864,7 @@ Index: src/pr.c { unsigned char uc = c; char *s = clump_buff; -@@ -2640,10 +2839,10 @@ char_to_clump (char c) +@@ -2644,10 +2843,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2711,7 +2877,7 @@ Index: src/pr.c { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2724,6 +2923,164 @@ char_to_clump (char c) +@@ -2728,6 +2927,164 @@ char_to_clump (char c) return chars; } @@ -2876,14 +3042,14 @@ Index: src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -Index: src/sort.c -=================================================================== ---- src/sort.c.orig -+++ src/sort.c -@@ -29,6 +29,14 @@ +diff --git a/src/sort.c b/src/sort.c +index e779845..1f5c337 100644 +--- a/src/sort.c ++++ b/src/sort.c +@@ -28,6 +28,14 @@ + #include #include #include - #include +#if HAVE_WCHAR_H +# include +#endif @@ -2894,8 +3060,8 @@ Index: src/sort.c + #include "system.h" #include "argmatch.h" - #include "die.h" -@@ -159,14 +167,39 @@ static int thousands_sep; + #include "assure.h" +@@ -157,14 +165,39 @@ static int thousands_sep; /* We currently ignore multi-byte grouping chars. */ static bool thousands_sep_ignored; @@ -2936,7 +3102,7 @@ Index: src/sort.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -343,13 +376,11 @@ static bool stable; +@@ -341,13 +374,11 @@ static bool stable; /* An int value outside char range. */ enum { NON_CHAR = CHAR_MAX + 1 }; @@ -2953,7 +3119,7 @@ Index: src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -805,6 +836,46 @@ reap_all (void) +@@ -803,6 +834,46 @@ reap_all (void) reap (-1); } @@ -3000,7 +3166,7 @@ Index: src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1272,7 +1343,7 @@ zaptemp (char const *name) +@@ -1270,7 +1341,7 @@ zaptemp (char const *name) free (node); } @@ -3009,7 +3175,7 @@ Index: src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1287,7 +1358,7 @@ struct_month_cmp (void const *m1, void c +@@ -1285,7 +1356,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -3018,7 +3184,7 @@ Index: src/sort.c { size_t i; -@@ -1299,7 +1370,7 @@ inittables (void) +@@ -1297,7 +1368,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -3027,7 +3193,7 @@ Index: src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1381,6 +1452,84 @@ specify_nmerge (int oi, char c, char con +@@ -1379,6 +1450,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -3112,7 +3278,7 @@ Index: src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1612,7 +1761,7 @@ buffer_linelim (struct buffer const *buf +@@ -1610,7 +1759,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -3121,7 +3287,7 @@ Index: src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1621,10 +1770,10 @@ begfield (struct line const *line, struc +@@ -1619,10 +1768,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -3134,7 +3300,7 @@ Index: src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1650,12 +1799,71 @@ begfield (struct line const *line, struc +@@ -1648,12 +1797,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3207,7 +3373,7 @@ Index: src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1670,10 +1878,10 @@ limfield (struct line const *line, struc +@@ -1668,10 +1876,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -3220,7 +3386,7 @@ Index: src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1719,10 +1927,10 @@ limfield (struct line const *line, struc +@@ -1717,10 +1925,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3233,7 +3399,7 @@ Index: src/sort.c if (newlim) lim = newlim; } -@@ -1753,6 +1961,130 @@ limfield (struct line const *line, struc +@@ -1751,6 +1959,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3364,7 +3530,7 @@ Index: src/sort.c /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1839,8 +2171,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1837,8 +2169,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3389,7 +3555,7 @@ Index: src/sort.c line->keybeg = line_start; } } -@@ -1978,24 +2324,42 @@ find_unit_order (char const *number) +@@ -1976,12 +2322,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3405,10 +3571,20 @@ Index: src/sort.c int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); +@@ -1993,7 +2337,7 @@ human_numcompare (char const *a, char const *b) + + ATTRIBUTE_PURE + static int +-numcompare (char const *a, char const *b) ++numcompare_uni (const char *a, const char *b) + { + while (blanks[to_uchar (*a)]) + a++; +@@ -2003,6 +2347,25 @@ numcompare (char const *a, char const *b) + return strnumcmp (a, b, decimal_point, thousands_sep); } +#if HAVE_MBRTOWC -+ATTRIBUTE_PURE +static int +numcompare_mb (const char *a, const char *b) +{ @@ -3427,18 +3603,10 @@ Index: src/sort.c +} +#endif /* HAV_EMBRTOWC */ + - /* Compare strings A and B as numbers without explicitly converting them to - machine numbers. Comparatively slow for short strings, but asymptotically - hideously fast. */ - - ATTRIBUTE_PURE static int --numcompare (char const *a, char const *b) -+numcompare_uni (const char *a, const char *b) + nan_compare (long double a, long double b) { - while (blanks[to_uchar (*a)]) - a++; -@@ -2046,7 +2410,7 @@ general_numcompare (char const *sa, char +@@ -2044,7 +2407,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3447,7 +3615,7 @@ Index: src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2322,15 +2686,14 @@ debug_key (struct line const *line, stru +@@ -2320,15 +2683,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3465,7 +3633,7 @@ Index: src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2476,7 +2839,7 @@ key_warnings (struct keyfield const *gke +@@ -2474,7 +2836,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3474,7 +3642,7 @@ Index: src/sort.c && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2524,9 +2887,9 @@ key_warnings (struct keyfield const *gke +@@ -2522,9 +2884,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3487,7 +3655,7 @@ Index: src/sort.c { error (0, 0, _("field separator %s is treated as a " -@@ -2537,9 +2900,9 @@ key_warnings (struct keyfield const *gke +@@ -2535,9 +2897,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3500,7 +3668,7 @@ Index: src/sort.c { error (0, 0, _("field separator %s is treated as a " -@@ -2547,19 +2910,19 @@ key_warnings (struct keyfield const *gke +@@ -2545,19 +2907,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3524,7 +3692,7 @@ Index: src/sort.c } } -@@ -2570,7 +2933,7 @@ key_warnings (struct keyfield const *gke +@@ -2568,7 +2930,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) { error (0, 0, _("%snumbers use %s as a decimal point in this locale"), @@ -3533,7 +3701,7 @@ Index: src/sort.c quote (((char []) {decimal_point, 0}))); } -@@ -2612,11 +2975,87 @@ diff_reversed (int diff, bool reversed) +@@ -2610,11 +2972,87 @@ diff_reversed (int diff, bool reversed) return reversed ? (diff < 0) - (diff > 0) : diff; } @@ -3622,16 +3790,16 @@ Index: src/sort.c { struct keyfield *key = keylist; -@@ -2697,7 +3136,7 @@ keycompare (struct line const *a, struct +@@ -2695,7 +3133,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) -- diff = getmonth (ta, NULL) - getmonth (tb, NULL); -+ diff = getmonth (ta, tlena, NULL) - getmonth (tb, tlenb, NULL); +- diff = getmonth (ta, nullptr) - getmonth (tb, nullptr); ++ diff = getmonth (ta, tlena, nullptr) - getmonth (tb, tlenb, nullptr); else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2807,6 +3246,211 @@ keycompare (struct line const *a, struct +@@ -2805,6 +3243,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -3843,7 +4011,7 @@ Index: src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2834,7 +3478,7 @@ compare (struct line const *a, struct li +@@ -2832,7 +3475,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3852,7 +4020,7 @@ Index: src/sort.c { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4222,6 +4866,7 @@ set_ordering (char const *s, struct keyf +@@ -4220,6 +4863,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -3860,7 +4028,7 @@ Index: src/sort.c break; case 'g': key->general_numeric = true; -@@ -4301,7 +4946,7 @@ main (int argc, char **argv) +@@ -4299,7 +4943,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3869,7 +4037,7 @@ Index: src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4324,6 +4969,29 @@ main (int argc, char **argv) +@@ -4322,6 +4966,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -3899,7 +4067,7 @@ Index: src/sort.c have_read_stdin = false; inittables (); -@@ -4598,13 +5266,34 @@ main (int argc, char **argv) +@@ -4592,13 +5259,34 @@ main (int argc, char **argv) case 't': { @@ -3909,7 +4077,7 @@ Index: src/sort.c + size_t newtab_length = 1; + strncpy (newtab, optarg, MB_LEN_MAX); + if (! newtab[0]) - die (SORT_FAILURE, 0, _("empty tab")); + error (SORT_FAILURE, 0, _("empty tab")); - if (optarg[1]) +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) @@ -3938,24 +4106,24 @@ Index: src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4615,9 +5304,11 @@ main (int argc, char **argv) - quote (optarg)); +@@ -4609,9 +5297,11 @@ main (int argc, char **argv) + quote (optarg)); } } - if (tab != TAB_DEFAULT && tab != newtab) + if (tab_length && (tab_length != newtab_length + || memcmp (tab, newtab, tab_length) != 0)) - die (SORT_FAILURE, 0, _("incompatible tabs")); + error (SORT_FAILURE, 0, _("incompatible tabs")); - tab = newtab; + memcpy (tab, newtab, newtab_length); + tab_length = newtab_length; } break; -Index: src/unexpand.c -=================================================================== ---- src/unexpand.c.orig -+++ src/unexpand.c +diff --git a/src/unexpand.c b/src/unexpand.c +index 5a2283f..f24ef76 100644 +--- a/src/unexpand.c ++++ b/src/unexpand.c @@ -38,6 +38,9 @@ #include #include @@ -3964,12 +4132,12 @@ Index: src/unexpand.c +#include + #include "system.h" - #include "die.h" + #include "expand-common.h" -@@ -106,24 +109,47 @@ unexpand (void) +@@ -104,24 +107,47 @@ unexpand (void) { /* Input stream. */ - FILE *fp = next_file (NULL); + FILE *fp = next_file (nullptr); + mb_file_t mbf; /* The array of pending blanks. In non-POSIX locales, blanks can @@ -3988,11 +4156,11 @@ Index: src/unexpand.c return; + mbf_init (mbf, fp); + found_bom=check_bom(fp,&mbf); - ++ + if (using_utf_locale == false && found_bom == true) + { + /*try using some predefined locale */ -+ + + if (set_utf_locale () != 0) + { + error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); @@ -4017,7 +4185,7 @@ Index: src/unexpand.c /* If true, perform translations. */ bool convert = true; -@@ -157,12 +183,44 @@ unexpand (void) +@@ -155,12 +181,44 @@ unexpand (void) do { @@ -4065,9 +4233,9 @@ Index: src/unexpand.c if (blank) { -@@ -179,16 +237,16 @@ unexpand (void) +@@ -177,16 +235,16 @@ unexpand (void) if (next_tab_column < column) - die (EXIT_FAILURE, 0, _("input line is too long")); + error (EXIT_FAILURE, 0, _("input line is too long")); - if (c == '\t') + if (mb_iseq (c, '\t')) @@ -4085,7 +4253,7 @@ Index: src/unexpand.c if (! (prev_blank && column == next_tab_column)) { -@@ -196,13 +254,14 @@ unexpand (void) +@@ -194,13 +252,14 @@ unexpand (void) will be replaced by tabs. */ if (column == next_tab_column) one_blank_before_tab_stop = true; @@ -4102,7 +4270,7 @@ Index: src/unexpand.c } /* Discard pending blanks, unless it was a single -@@ -210,7 +269,7 @@ unexpand (void) +@@ -208,7 +267,7 @@ unexpand (void) pending = one_blank_before_tab_stop; } } @@ -4111,7 +4279,7 @@ Index: src/unexpand.c { /* Go back one column, and force recalculation of the next tab stop. */ -@@ -220,16 +279,20 @@ unexpand (void) +@@ -218,16 +277,20 @@ unexpand (void) } else { @@ -4120,7 +4288,7 @@ Index: src/unexpand.c + const uintmax_t orig_column = column; + column += mb_width (c); + if (column < orig_column) - die (EXIT_FAILURE, 0, _("input line is too long")); + error (EXIT_FAILURE, 0, _("input line is too long")); } if (pending) @@ -4133,10 +4301,10 @@ Index: src/unexpand.c + for (int n = 0; n < pending; ++n) + mb_putc (pending_blank[n], stdout); + if (ferror (stdout)) - die (EXIT_FAILURE, errno, _("write error")); + write_error (); pending = 0; one_blank_before_tab_stop = false; -@@ -239,16 +302,17 @@ unexpand (void) +@@ -237,16 +300,17 @@ unexpand (void) convert &= convert_entire_line || blank; } @@ -4150,17 +4318,17 @@ Index: src/unexpand.c - if (putchar (c) < 0) + mb_putc (c, stdout); + if (ferror (stdout)) - die (EXIT_FAILURE, errno, _("write error")); + write_error (); } - while (c != '\n'); + while (!mb_iseq (c, '\n')); } } -Index: src/uniq.c -=================================================================== ---- src/uniq.c.orig -+++ src/uniq.c +diff --git a/src/uniq.c b/src/uniq.c +index fab04de..2e96dcb 100644 +--- a/src/uniq.c ++++ b/src/uniq.c @@ -21,6 +21,17 @@ #include #include @@ -4179,7 +4347,7 @@ Index: src/uniq.c #include "system.h" #include "argmatch.h" #include "linebuffer.h" -@@ -33,6 +44,18 @@ +@@ -31,6 +42,18 @@ #include "memcasecmp.h" #include "quote.h" @@ -4198,7 +4366,7 @@ Index: src/uniq.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "uniq" -@@ -139,6 +162,10 @@ enum +@@ -137,6 +160,10 @@ enum GROUP_OPTION = CHAR_MAX + 1 }; @@ -4208,8 +4376,8 @@ Index: src/uniq.c + static struct option const longopts[] = { - {"count", no_argument, NULL, 'c'}, -@@ -254,7 +281,7 @@ size_opt (char const *opt, char const *m + {"count", no_argument, nullptr, 'c'}, +@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *msgid) ATTRIBUTE_PURE static char * @@ -4218,7 +4386,7 @@ Index: src/uniq.c { size_t count; char const *lp = line->buffer; -@@ -274,6 +301,83 @@ find_field (struct linebuffer const *lin +@@ -272,6 +299,83 @@ find_field (struct linebuffer const *line) return line->buffer + i; } @@ -4302,7 +4470,7 @@ Index: src/uniq.c /* Return false if two strings OLD and NEW match, true if not. OLD and NEW point not to the beginnings of the lines but rather to the beginnings of the fields to compare. -@@ -494,6 +598,19 @@ main (int argc, char **argv) +@@ -495,6 +599,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -4322,10 +4490,10 @@ Index: src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -Index: tests/Coreutils.pm -=================================================================== ---- tests/Coreutils.pm.orig -+++ tests/Coreutils.pm +diff --git a/tests/Coreutils.pm b/tests/Coreutils.pm +index f147401..3ce5da9 100644 +--- a/tests/Coreutils.pm ++++ b/tests/Coreutils.pm @@ -269,6 +269,9 @@ sub run_tests ($$$$$) # Yes, this is an arbitrary limit. If it causes trouble, # consider removing it. @@ -4336,10 +4504,11 @@ Index: tests/Coreutils.pm if ($max < length $test_name) { warn "$program_name: $test_name: test name is too long (> $max)\n"; -Index: tests/expand/mb.sh -=================================================================== +diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh +new file mode 100755 +index 0000000..dd6007c --- /dev/null -+++ tests/expand/mb.sh ++++ b/tests/expand/mb.sh @@ -0,0 +1,183 @@ +#!/bin/sh + @@ -4524,10 +4693,11 @@ Index: tests/expand/mb.sh +compare exp out > /dev/null 2>&1 || fail=1 + +exit $fail -Index: tests/i18n/sort.sh -=================================================================== +diff --git a/tests/i18n/sort.sh b/tests/i18n/sort.sh +new file mode 100755 +index 0000000..26c95de --- /dev/null -+++ tests/i18n/sort.sh ++++ b/tests/i18n/sort.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# Verify sort's multi-byte support. @@ -4558,20 +4728,20 @@ Index: tests/i18n/sort.sh + + +Exit $fail -Index: tests/local.mk -=================================================================== ---- tests/local.mk.orig -+++ tests/local.mk -@@ -383,6 +383,8 @@ all_tests = \ - tests/misc/sort-discrim.sh \ - tests/misc/sort-files0-from.pl \ - tests/misc/sort-float.sh \ +diff --git a/tests/local.mk b/tests/local.mk +index b74a4a2..fe6e557 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -384,6 +384,8 @@ all_tests = \ + tests/sort/sort-discrim.sh \ + tests/sort/sort-files0-from.pl \ + tests/sort/sort-float.sh \ + tests/misc/sort-mb-tests.sh \ + tests/i18n/sort.sh \ - tests/misc/sort-h-thousands-sep.sh \ - tests/misc/sort-merge.pl \ - tests/misc/sort-merge-fdlimit.sh \ -@@ -584,6 +586,7 @@ all_tests = \ + tests/sort/sort-h-thousands-sep.sh \ + tests/sort/sort-merge.pl \ + tests/sort/sort-merge-fdlimit.sh \ +@@ -585,6 +587,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4579,7 +4749,7 @@ Index: tests/local.mk tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -736,6 +739,7 @@ all_tests = \ +@@ -738,6 +741,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4587,10 +4757,10 @@ Index: tests/local.mk $(all_root_tests) # See tests/factor/create-test.sh. -Index: tests/misc/expand.pl -=================================================================== ---- tests/misc/expand.pl.orig -+++ tests/misc/expand.pl +diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl +index 06261ac..7dd813e 100755 +--- a/tests/misc/expand.pl ++++ b/tests/misc/expand.pl @@ -27,6 +27,15 @@ my $prog = 'expand'; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4654,10 +4824,10 @@ Index: tests/misc/expand.pl my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -Index: tests/misc/fold.pl -=================================================================== ---- tests/misc/fold.pl.orig -+++ tests/misc/fold.pl +diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl +index a94072f..136a82e 100755 +--- a/tests/misc/fold.pl ++++ b/tests/misc/fold.pl @@ -20,9 +20,18 @@ use strict; (my $program_name = $0) =~ s|.*/||; @@ -4727,10 +4897,10 @@ Index: tests/misc/fold.pl -my $prog = 'fold'; my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); exit $fail; -Index: tests/misc/join.pl -=================================================================== ---- tests/misc/join.pl.orig -+++ tests/misc/join.pl +diff --git a/tests/misc/join.pl b/tests/misc/join.pl +index 2ca8567..1d01a3d 100755 +--- a/tests/misc/join.pl ++++ b/tests/misc/join.pl @@ -25,6 +25,15 @@ my $limits = getlimits (); my $prog = 'join'; @@ -4797,10 +4967,11 @@ Index: tests/misc/join.pl my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -Index: tests/misc/sort-mb-tests.sh -=================================================================== +diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh +new file mode 100755 +index 0000000..11836ba --- /dev/null -+++ tests/misc/sort-mb-tests.sh ++++ b/tests/misc/sort-mb-tests.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# Verify sort's multi-byte support. @@ -4847,10 +5018,136 @@ Index: tests/misc/sort-mb-tests.sh +compare exp out || { fail=1; cat out; } + +Exit $fail -Index: tests/misc/sort-merge.pl -=================================================================== ---- tests/misc/sort-merge.pl.orig -+++ tests/misc/sort-merge.pl +diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl +index d78a1bc..2b9137d 100755 +--- a/tests/misc/unexpand.pl ++++ b/tests/misc/unexpand.pl +@@ -27,6 +27,14 @@ my $limits = getlimits (); + + my $prog = 'unexpand'; + ++# comment out next line to disable multibyte tests ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; ++! defined $mb_locale || $mb_locale eq 'none' ++ and $mb_locale = 'C'; ++ ++my $try = "Try \`$prog --help' for more information.\n"; ++my $inval = "$prog: invalid byte, character or field list\n$try"; ++ + my @Tests = + ( + ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], +@@ -128,6 +136,37 @@ my @Tests = + ['ts2', '-t5,8', {IN=>"x\t \t y\n"}, {OUT=>"x\t\t y\n"}], + ); + ++if ($mb_locale ne 'C') ++ { ++ # Duplicate each test vector, appending "-mb" to the test name and ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we ++ # provide coverage for the distro-added multi-byte code paths. ++ my @new; ++ foreach my $t (@Tests) ++ { ++ my @new_t = @$t; ++ my $test_name = shift @new_t; ++ ++ # Depending on whether unexpand is multi-byte-patched, ++ # it emits different diagnostics: ++ # non-MB: invalid byte or field list ++ # MB: invalid byte, character or field list ++ # Adjust the expected error output accordingly. ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} ++ (@new_t)) ++ { ++ my $sub = {ERR_SUBST => 's/, character//'}; ++ push @new_t, $sub; ++ push @$t, $sub; ++ } ++ next if ($test_name =~ 'b-1'); ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; ++ } ++ push @Tests, @new; ++ } ++ ++@Tests = triple_test \@Tests; ++ + my $save_temps = $ENV{DEBUG}; + my $verbose = $ENV{VERBOSE}; + +diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl +index eafc13d..c1eca2a 100755 +--- a/tests/pr/pr-tests.pl ++++ b/tests/pr/pr-tests.pl +@@ -24,6 +24,15 @@ use strict; + my $prog = 'pr'; + my $normalize_strerror = "s/': .*/'/"; + ++my $mb_locale; ++#Uncomment the following line to enable multibyte tests ++$mb_locale = $ENV{LOCALE_FR_UTF8}; ++! defined $mb_locale || $mb_locale eq 'none' ++ and $mb_locale = 'C'; ++ ++my $try = "Try \`$prog --help' for more information.\n"; ++my $inval = "$prog: invalid byte, character or field list\n$try"; ++ + my @tv = ( + + # -b option is no longer an official option. But it's still working to +@@ -515,8 +524,48 @@ push @Tests, + {IN=>"x\tx\tx\tx\tx\nx\tx\tx\tx\tx\n"}, + {OUT=>"x\tx\tx\tx\tx\tx\tx\tx\tx\tx\n"} ]; + ++# Add _POSIX2_VERSION=199209 to the environment of each test ++# that uses an old-style option like +1. ++if ($mb_locale ne 'C') ++ { ++ # Duplicate each test vector, appending "-mb" to the test name and ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we ++ # provide coverage for the distro-added multi-byte code paths. ++ my @new; ++ foreach my $t (@Tests) ++ { ++ my @new_t = @$t; ++ my $test_name = shift @new_t; ++ ++ # Depending on whether pr is multi-byte-patched, ++ # it emits different diagnostics: ++ # non-MB: invalid byte or field list ++ # MB: invalid byte, character or field list ++ # Adjust the expected error output accordingly. ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} ++ (@new_t)) ++ { ++ my $sub = {ERR_SUBST => 's/, character//'}; ++ push @new_t, $sub; ++ push @$t, $sub; ++ } ++ #temporarily skip some failing tests ++ next if ($test_name =~ "col-0" or $test_name =~ "col-inval" or $test_name =~ "asan1"); ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; ++ } ++ push @Tests, @new; ++ } ++ + @Tests = triple_test \@Tests; + ++# Remember that triple_test creates from each test with exactly one "IN" ++# file two more tests (.p and .r suffix on name) corresponding to reading ++# input from a file and from a pipe. The pipe-reading test would fail ++# due to a race condition about 1 in 20 times. ++# Remove the IN_PIPE version of the "output-is-input" test above. ++# The others aren't susceptible because they have three inputs each. ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; ++ + my $save_temps = $ENV{DEBUG}; + my $verbose = $ENV{VERBOSE}; + +diff --git a/tests/sort/sort-merge.pl b/tests/sort/sort-merge.pl +index bd439ef..2ccdf87 100755 +--- a/tests/sort/sort-merge.pl ++++ b/tests/sort/sort-merge.pl @@ -26,6 +26,15 @@ my $prog = 'sort'; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4907,10 +5204,10 @@ Index: tests/misc/sort-merge.pl my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -Index: tests/misc/sort.pl -=================================================================== ---- tests/misc/sort.pl.orig -+++ tests/misc/sort.pl +diff --git a/tests/sort/sort.pl b/tests/sort/sort.pl +index 46f1d7a..bb38f5b 100755 +--- a/tests/sort/sort.pl ++++ b/tests/sort/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4975,212 +5272,11 @@ Index: tests/misc/sort.pl my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -Index: tests/misc/unexpand.pl -=================================================================== ---- tests/misc/unexpand.pl.orig -+++ tests/misc/unexpand.pl -@@ -27,6 +27,14 @@ my $limits = getlimits (); - - my $prog = 'unexpand'; - -+# comment out next line to disable multibyte tests -+my $mb_locale = $ENV{LOCALE_FR_UTF8}; -+! defined $mb_locale || $mb_locale eq 'none' -+ and $mb_locale = 'C'; -+ -+my $try = "Try \`$prog --help' for more information.\n"; -+my $inval = "$prog: invalid byte, character or field list\n$try"; -+ - my @Tests = - ( - ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], -@@ -128,6 +136,37 @@ my @Tests = - ['ts2', '-t5,8', {IN=>"x\t \t y\n"}, {OUT=>"x\t\t y\n"}], - ); - -+if ($mb_locale ne 'C') -+ { -+ # Duplicate each test vector, appending "-mb" to the test name and -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we -+ # provide coverage for the distro-added multi-byte code paths. -+ my @new; -+ foreach my $t (@Tests) -+ { -+ my @new_t = @$t; -+ my $test_name = shift @new_t; -+ -+ # Depending on whether unexpand is multi-byte-patched, -+ # it emits different diagnostics: -+ # non-MB: invalid byte or field list -+ # MB: invalid byte, character or field list -+ # Adjust the expected error output accordingly. -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} -+ (@new_t)) -+ { -+ my $sub = {ERR_SUBST => 's/, character//'}; -+ push @new_t, $sub; -+ push @$t, $sub; -+ } -+ next if ($test_name =~ 'b-1'); -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; -+ } -+ push @Tests, @new; -+ } -+ -+@Tests = triple_test \@Tests; -+ - my $save_temps = $ENV{DEBUG}; - my $verbose = $ENV{VERBOSE}; - -Index: tests/misc/uniq.pl -=================================================================== ---- tests/misc/uniq.pl.orig -+++ tests/misc/uniq.pl -@@ -23,9 +23,17 @@ my $limits = getlimits (); - my $prog = 'uniq'; - my $try = "Try '$prog --help' for more information.\n"; - -+my $inval = "$prog: invalid byte, character or field list\n$try"; -+ - # Turn off localization of executable's output. - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; - -+my $mb_locale; -+#Comment out next line to disable multibyte tests -+$mb_locale = $ENV{LOCALE_FR_UTF8}; -+! defined $mb_locale || $mb_locale eq 'none' -+ and $mb_locale = 'C'; -+ - # When possible, create a "-z"-testing variant of each test. - sub add_z_variants($) - { -@@ -262,6 +270,53 @@ foreach my $t (@Tests) - and push @$t, {ENV=>'_POSIX2_VERSION=199209'}; - } - -+if ($mb_locale ne 'C') -+ { -+ # Duplicate each test vector, appending "-mb" to the test name and -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we -+ # provide coverage for the distro-added multi-byte code paths. -+ my @new; -+ foreach my $t (@Tests) -+ { -+ my @new_t = @$t; -+ my $test_name = shift @new_t; -+ -+ # Depending on whether uniq is multi-byte-patched, -+ # it emits different diagnostics: -+ # non-MB: invalid byte or field list -+ # MB: invalid byte, character or field list -+ # Adjust the expected error output accordingly. -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} -+ (@new_t)) -+ { -+ my $sub = {ERR_SUBST => 's/, character//'}; -+ push @new_t, $sub; -+ push @$t, $sub; -+ } -+ # In test #145, replace the each ‘...’ by '...'. -+ if ($test_name =~ "145") -+ { -+ my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"}; -+ push @new_t, $sub; -+ push @$t, $sub; -+ } -+ next if ( $test_name =~ "schar" -+ or $test_name =~ "^obs-plus" -+ or $test_name =~ "119"); -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; -+ } -+ push @Tests, @new; -+ } -+ -+# Remember that triple_test creates from each test with exactly one "IN" -+# file two more tests (.p and .r suffix on name) corresponding to reading -+# input from a file and from a pipe. The pipe-reading test would fail -+# due to a race condition about 1 in 20 times. -+# Remove the IN_PIPE version of the "output-is-input" test above. -+# The others aren't susceptible because they have three inputs each. -+ -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; -+ - @Tests = add_z_variants \@Tests; - @Tests = triple_test \@Tests; - -Index: tests/pr/pr-tests.pl -=================================================================== ---- tests/pr/pr-tests.pl.orig -+++ tests/pr/pr-tests.pl -@@ -24,6 +24,15 @@ use strict; - my $prog = 'pr'; - my $normalize_strerror = "s/': .*/'/"; - -+my $mb_locale; -+#Uncomment the following line to enable multibyte tests -+$mb_locale = $ENV{LOCALE_FR_UTF8}; -+! defined $mb_locale || $mb_locale eq 'none' -+ and $mb_locale = 'C'; -+ -+my $try = "Try \`$prog --help' for more information.\n"; -+my $inval = "$prog: invalid byte, character or field list\n$try"; -+ - my @tv = ( - - # -b option is no longer an official option. But it's still working to -@@ -512,8 +521,48 @@ push @Tests, - {IN=>"x\tx\tx\tx\tx\nx\tx\tx\tx\tx\n"}, - {OUT=>"x\tx\tx\tx\tx\tx\tx\tx\tx\tx\n"} ]; - -+# Add _POSIX2_VERSION=199209 to the environment of each test -+# that uses an old-style option like +1. -+if ($mb_locale ne 'C') -+ { -+ # Duplicate each test vector, appending "-mb" to the test name and -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we -+ # provide coverage for the distro-added multi-byte code paths. -+ my @new; -+ foreach my $t (@Tests) -+ { -+ my @new_t = @$t; -+ my $test_name = shift @new_t; -+ -+ # Depending on whether pr is multi-byte-patched, -+ # it emits different diagnostics: -+ # non-MB: invalid byte or field list -+ # MB: invalid byte, character or field list -+ # Adjust the expected error output accordingly. -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} -+ (@new_t)) -+ { -+ my $sub = {ERR_SUBST => 's/, character//'}; -+ push @new_t, $sub; -+ push @$t, $sub; -+ } -+ #temporarily skip some failing tests -+ next if ($test_name =~ "col-0" or $test_name =~ "col-inval" or $test_name =~ "asan1"); -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; -+ } -+ push @Tests, @new; -+ } -+ - @Tests = triple_test \@Tests; - -+# Remember that triple_test creates from each test with exactly one "IN" -+# file two more tests (.p and .r suffix on name) corresponding to reading -+# input from a file and from a pipe. The pipe-reading test would fail -+# due to a race condition about 1 in 20 times. -+# Remove the IN_PIPE version of the "output-is-input" test above. -+# The others aren't susceptible because they have three inputs each. -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; -+ - my $save_temps = $ENV{DEBUG}; - my $verbose = $ENV{VERBOSE}; - -Index: tests/unexpand/mb.sh -=================================================================== +diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh +new file mode 100755 +index 0000000..8a82d74 --- /dev/null -+++ tests/unexpand/mb.sh ++++ b/tests/unexpand/mb.sh @@ -0,0 +1,172 @@ +#!/bin/sh + @@ -5354,3 +5450,82 @@ Index: tests/unexpand/mb.sh + +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 +diff --git a/tests/uniq/uniq.pl b/tests/uniq/uniq.pl +index a6354dc..e43cd6e 100755 +--- a/tests/uniq/uniq.pl ++++ b/tests/uniq/uniq.pl +@@ -23,9 +23,17 @@ my $limits = getlimits (); + my $prog = 'uniq'; + my $try = "Try '$prog --help' for more information.\n"; + ++my $inval = "$prog: invalid byte, character or field list\n$try"; ++ + # Turn off localization of executable's output. + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + ++my $mb_locale; ++#Comment out next line to disable multibyte tests ++$mb_locale = $ENV{LOCALE_FR_UTF8}; ++! defined $mb_locale || $mb_locale eq 'none' ++ and $mb_locale = 'C'; ++ + # When possible, create a "-z"-testing variant of each test. + sub add_z_variants($) + { +@@ -262,6 +270,53 @@ foreach my $t (@Tests) + and push @$t, {ENV=>'_POSIX2_VERSION=199209'}; + } + ++if ($mb_locale ne 'C') ++ { ++ # Duplicate each test vector, appending "-mb" to the test name and ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we ++ # provide coverage for the distro-added multi-byte code paths. ++ my @new; ++ foreach my $t (@Tests) ++ { ++ my @new_t = @$t; ++ my $test_name = shift @new_t; ++ ++ # Depending on whether uniq is multi-byte-patched, ++ # it emits different diagnostics: ++ # non-MB: invalid byte or field list ++ # MB: invalid byte, character or field list ++ # Adjust the expected error output accordingly. ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} ++ (@new_t)) ++ { ++ my $sub = {ERR_SUBST => 's/, character//'}; ++ push @new_t, $sub; ++ push @$t, $sub; ++ } ++ # In test #145, replace the each ‘...’ by '...'. ++ if ($test_name =~ "145") ++ { ++ my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"}; ++ push @new_t, $sub; ++ push @$t, $sub; ++ } ++ next if ( $test_name =~ "schar" ++ or $test_name =~ "^obs-plus" ++ or $test_name =~ "119"); ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; ++ } ++ push @Tests, @new; ++ } ++ ++# Remember that triple_test creates from each test with exactly one "IN" ++# file two more tests (.p and .r suffix on name) corresponding to reading ++# input from a file and from a pipe. The pipe-reading test would fail ++# due to a race condition about 1 in 20 times. ++# Remove the IN_PIPE version of the "output-is-input" test above. ++# The others aren't susceptible because they have three inputs each. ++ ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; ++ + @Tests = add_z_variants \@Tests; + @Tests = triple_test \@Tests; + +-- +2.41.0 + diff --git a/coreutils-invalid-ids.patch b/coreutils-invalid-ids.patch deleted file mode 100644 index f01f7f3..0000000 --- a/coreutils-invalid-ids.patch +++ /dev/null @@ -1,30 +0,0 @@ -While uid_t and gid_t are both unsigned, the values (uid_t) -1 and -(gid_t) -1 are reserved. A uid or gid argument of -1 to the chown(2) -system call means to leave the uid/gid unchanged. Catch this case -so that trying to set a uid or gid to -1 will result in an error. - -Test cases: - - chown 4294967295 file - chown :4294967295 file - chgrp 4294967295 file - -Andreas Gruenbacher - ---- - src/chgrp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -Index: src/chgrp.c -=================================================================== ---- src/chgrp.c.orig -+++ src/chgrp.c -@@ -89,7 +89,7 @@ parse_group (char const *name) - { - uintmax_t tmp; - if (! (xstrtoumax (name, NULL, 10, &tmp, "") == LONGINT_OK -- && tmp <= GID_T_MAX)) -+ && tmp <= GID_T_MAX && (gid_t) tmp != (gid_t) -1)) - die (EXIT_FAILURE, 0, _("invalid group: %s"), - quote (name)); - gid = tmp; diff --git a/coreutils-misc.patch b/coreutils-misc.patch index e0ca2ca..37bd99e 100644 --- a/coreutils-misc.patch +++ b/coreutils-misc.patch @@ -1,6 +1,6 @@ --- gnulib-tests/test-isnanl.h | 5 +++-- - tests/misc/help-version.sh | 1 + + tests/help/help-version.sh | 1 + tests/other-fs-tmpdir | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) @@ -33,10 +33,10 @@ Index: gnulib-tests/test-isnanl.h +#endif return 0; } -Index: tests/misc/help-version.sh +Index: tests/help/help-version.sh =================================================================== ---- tests/misc/help-version.sh.orig -+++ tests/misc/help-version.sh +--- tests/help/help-version.sh.orig ++++ tests/help/help-version.sh @@ -241,6 +241,7 @@ parted_setup () { args="-s $tmp_in mklab for i in $built_programs; do # Skip these. diff --git a/coreutils-skip-some-sort-tests-on-ppc.patch b/coreutils-skip-some-sort-tests-on-ppc.patch index 5a304e0..88ecc71 100644 --- a/coreutils-skip-some-sort-tests-on-ppc.patch +++ b/coreutils-skip-some-sort-tests-on-ppc.patch @@ -12,18 +12,18 @@ Valgrind diagnoses problems in 'mkstemp64' deep down in glibc on PowerPC: by 0x1000A427: maybe_create_temp (sort.c:1176) by 0x100031BF: main (sort.c:1223) -* tests/misc/sort-stale-thread-mem.sh: Skip on ppc/ppc64. -* tests/misc/sort-u-FMR.sh: Likewise. +* tests/sort/sort-stale-thread-mem.sh: Skip on ppc/ppc64. +* tests/sort/sort-u-FMR.sh: Likewise. --- - tests/misc/sort-stale-thread-mem.sh | 4 ++++ - tests/misc/sort-u-FMR.sh | 4 ++++ + tests/sort/sort-stale-thread-mem.sh | 4 ++++ + tests/sort/sort-u-FMR.sh | 4 ++++ 2 files changed, 8 insertions(+) -Index: tests/misc/sort-stale-thread-mem.sh +Index: tests/sort/sort-stale-thread-mem.sh =================================================================== ---- tests/misc/sort-stale-thread-mem.sh.orig -+++ tests/misc/sort-stale-thread-mem.sh +--- tests/sort/sort-stale-thread-mem.sh.orig ++++ tests/sort/sort-stale-thread-mem.sh @@ -27,6 +27,10 @@ require_valgrind_ grep '^#define HAVE_PTHREAD_T 1' "$CONFIG_HEADER" > /dev/null || skip_ 'requires pthreads' @@ -35,10 +35,10 @@ Index: tests/misc/sort-stale-thread-mem.sh # gensort output seems to trigger the failure more often, # so prefer gensort if it is available. (gensort -a 10000 in) 2>/dev/null || -Index: tests/misc/sort-u-FMR.sh +Index: tests/sort/sort-u-FMR.sh =================================================================== ---- tests/misc/sort-u-FMR.sh.orig -+++ tests/misc/sort-u-FMR.sh +--- tests/sort/sort-u-FMR.sh.orig ++++ tests/sort/sort-u-FMR.sh @@ -20,6 +20,10 @@ print_ver_ sort require_valgrind_ diff --git a/coreutils-test_without_valgrind.patch b/coreutils-test_without_valgrind.patch index ce39d8a..4ec6cdb 100644 --- a/coreutils-test_without_valgrind.patch +++ b/coreutils-test_without_valgrind.patch @@ -1,11 +1,11 @@ --- - tests/misc/shuf-reservoir.sh | 3 +-- + tests/shuf/shuf-reservoir.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) -Index: tests/misc/shuf-reservoir.sh +Index: tests/shuf/shuf-reservoir.sh =================================================================== ---- tests/misc/shuf-reservoir.sh.orig -+++ tests/misc/shuf-reservoir.sh +--- tests/shuf/shuf-reservoir.sh.orig ++++ tests/shuf/shuf-reservoir.sh @@ -37,8 +37,7 @@ run_shuf_n() # Critical memory-related bugs will cause a segfault here diff --git a/coreutils.changes b/coreutils.changes index 7b09826..4051060 100644 --- a/coreutils.changes +++ b/coreutils.changes @@ -1,3 +1,68 @@ +------------------------------------------------------------------- +Thu Aug 31 09:56:48 UTC 2023 - Thorsten Kukuk + +- Update to 9.4: + Bug fixes: + * b2sum --check will no longer read unallocated memory when + presented with malformed checksum lines. + [bug introduced in coreutils-9.2] + * cp --parents again succeeds when preserving mode for absolute directories. + Previously it would have failed with a "No such file or directory" error. + [bug introduced in coreutils-9.1] + * cp --sparse=never will avoid copy-on-write (reflinking) and copy offloading, + to ensure no holes present in the destination copy. + [bug introduced in coreutils-9.0] + * cksum again diagnoses read errors in its default CRC32 mode. + [bug introduced in coreutils-9.0] + * cksum --check now ensures filenames with a leading backslash character + are escaped appropriately in the status output. + This also applies to the standalone checksumming utilities. + [bug introduced in coreutils-8.25] + * dd again supports more than two multipliers for numbers. + Previously numbers of the form '1024x1024x32' gave "invalid number" errors. + [bug introduced in coreutils-9.1] + * factor, numfmt, and tsort now diagnose read errors on the input. + [This bug was present in "the beginning".] + * install --strip now supports installing to files with a leading hyphen. + Previously such file names would have caused the strip process to fail. + [This bug was present in "the beginning".] + * ls now shows symlinks specified on the command line that can't be traversed. + Previously a "Too many levels of symbolic links" diagnostic was given. + [This bug was present in "the beginning".] + * pr --length=1 --double-space no longer enters an infinite loop. + [This bug was present in "the beginning".] + * tac now handles short reads on its input. Previously it may have exited + erroneously, especially with large input files with no separators. + [This bug was present in "the beginning".] + * uptime no longer incorrectly prints "0 users" on OpenBSD, + and is being built again on FreeBSD and Haiku. + [bugs introduced in coreutils-9.2] + * wc -l and cksum no longer crash with an "Illegal instruction" error + on x86 Linux kernels that disable XSAVE YMM. This was seen on Xen VMs. + [bug introduced in coreutils-9.0] + Changes in behavior: + * cp -v and mv -v will no longer output a message for each file skipped + due to -i, or -u. Instead they only output this information with --debug. + I.e., 'cp -u -v' etc. will have the same verbosity as before coreutils-9.3. + * cksum -b no longer prints base64-encoded checksums. Rather that + short option is reserved to better support emulation of the standalone + checksum utilities with cksum. + * mv dir x now complains differently if x/dir is a nonempty directory. + Previously it said "mv: cannot move 'dir' to 'x/dir': Directory not empty", + where it was unclear whether 'dir' or 'x/dir' was the problem. + Now it says "mv: cannot overwrite 'x/dir': Directory not empty". + Similarly for other renames where the destination must be the problem. + [problem introduced in coreutils-6.0] +- Enable systemd-logind support +- Add gnulib-readutmp.patch: Fix seg.fault of who, pinky, uptime [dgo#65617] +- Create -systemd flavor with binaries linked against libsystemd +- Drop coreutils-invalid-ids.patch to get consistent behavior, most tools + where already removed from that patch. +- coreutils-misc.patch: adjust paths +- coreutils-skip-some-sort-tests-on-ppc.patch: adjust paths +- coreutils-test_without_valgrind.patch: adjust paths +- coreutils-i18n.patch: update from Fedora + ------------------------------------------------------------------- Thu Apr 20 09:19:20 UTC 2023 - Bernhard Voelker diff --git a/coreutils.spec b/coreutils.spec index e4baa7c..95d6c20 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -24,11 +24,13 @@ %global psuffix -single %elif "%{flavor}" == "testsuite" %global psuffix -testsuite +%elif "%{flavor}" == "systemd" +%global psuffix -systemd %else %global psuffix %{nil} %endif Name: coreutils%{?psuffix} -Version: 9.3 +Version: 9.4 Release: 0 Summary: GNU Core Utilities License: GPL-3.0-or-later @@ -42,13 +44,15 @@ Patch1: coreutils-remove_hostname_documentation.patch Patch3: coreutils-remove_kill_documentation.patch Patch4: coreutils-i18n.patch Patch8: coreutils-sysinfo.patch -Patch16: coreutils-invalid-ids.patch # OBS / RPMLINT require /usr/bin/timeout to be built with the -fpie option. Patch100: coreutils-build-timeout-as-pie.patch # There is no network in the build root so make the test succeed Patch112: coreutils-getaddrinfo.patch # Assorted fixes Patch113: coreutils-misc.patch +# gnulib seg.faults if there is no session +# https://debbugs.gnu.org/cgi/bugreport.cgi?bug=65617 +Patch114: gnulib-readutmp.patch # Skip 2 valgrind'ed sort tests on ppc/ppc64 which would fail due to # a glibc issue in mkstemp. Patch300: coreutils-skip-some-sort-tests-on-ppc.patch @@ -73,6 +77,9 @@ BuildRequires: libselinux-devel BuildRequires: makeinfo BuildRequires: perl BuildRequires: xz +%if "%{name}" == "coreutils-systemd" +BuildRequires: pkgconfig(libsystemd) +%endif %if 0%{?suse_version} > 1320 BuildRequires: gcc-PIE %endif @@ -101,6 +108,10 @@ Conflicts: coreutils Provides: coreutils = %{version}-%{release} %endif %endif +%if "%{name}" == "coreutils-systemd" +Provides: coreutils:%{_bindir}/who +Requires: coreutils = %{version} +%endif # ================================================ %description @@ -133,17 +144,17 @@ This package contains the documentation for the GNU Core Utilities. %prep %setup -q -n coreutils-%{version} -%patch4 +%patch4 -p1 %patch1 %patch3 %patch8 -%patch16 # %if 0%{?suse_version} <= 1320 %patch100 %endif %patch112 %patch113 +%patch114 -p1 %patch300 @@ -172,6 +183,9 @@ export CFLAGS="%{optflags}" --enable-single-binary \ --without-openssl \ --without-gmp \ +%endif +%if "%{name}" == "coreutils-systemd" + --enable-systemd \ %endif DEFAULT_POSIX2_VERSION=200112 \ alternative=199209 @@ -220,6 +234,10 @@ rm -rf %{buildroot}%{_datadir}/locale > coreutils.lang %endif %endif +%if "%{name}" == "coreutils-systemd" +mkdir -p %{buildroot}%{_bindir} +install src/{pinky,uptime,users,who} %{buildroot}%{_bindir}/ +%endif # ================================================ %post @@ -239,6 +257,10 @@ rm -rf %{buildroot}%{_datadir}/locale %license COPYING %doc NEWS README THANKS +%exclude %{_bindir}/pinky +%exclude %{_bindir}/uptime +%exclude %{_bindir}/users +%exclude %{_bindir}/who %{_bindir}/* %{_libdir}/%{name} @@ -250,6 +272,14 @@ rm -rf %{buildroot}%{_datadir}/locale %{_mandir}/man1/*.1%{?ext_man} %endif +%elif "%{name}" == "coreutils-systemd" +%license COPYING +%doc NEWS README THANKS +%{_bindir}/pinky +%{_bindir}/uptime +%{_bindir}/users +%{_bindir}/who + %else # test-suite diff --git a/gnulib-readutmp.patch b/gnulib-readutmp.patch new file mode 100644 index 0000000..e1bf4f9 --- /dev/null +++ b/gnulib-readutmp.patch @@ -0,0 +1,13 @@ +diff --git a/lib/readutmp.c b/lib/readutmp.c +index 0173b7e0c1..e99158677c 100644 +--- a/lib/readutmp.c ++++ b/lib/readutmp.c +@@ -795,7 +795,7 @@ read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options) + { + char **sessions; + int num_sessions = sd_get_sessions (&sessions); +- if (num_sessions >= 0) ++ if (num_sessions > 0) + { + char **session_ptr; + for (session_ptr = sessions; *session_ptr != NULL; session_ptr++)