diff --git a/coreutils-8.32-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch index 021d2a5..37ce3e6 100644 --- a/coreutils-8.32-DIR_COLORS.patch +++ b/coreutils-8.32-DIR_COLORS.patch @@ -1,4 +1,4 @@ -From c7b13f5e1a7ad012c510a8bdd5a8943ab4b55833 Mon Sep 17 00:00:00 2001 +From bca11e30e8a6281a8cbddc9fb196dd86ab09c955 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 17 Jun 2016 16:58:18 +0200 Subject: [PATCH] downstream changes to default DIR_COLORS @@ -9,7 +9,7 @@ Subject: [PATCH] downstream changes to default DIR_COLORS 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/DIR_COLORS b/DIR_COLORS -index b465771..ad42b09 100644 +index 540f6cd..b4785b6 100644 --- a/DIR_COLORS +++ b/DIR_COLORS @@ -1,3 +1,7 @@ @@ -30,7 +30,7 @@ index b465771..ad42b09 100644 # =================================================================== # Terminal filters # =================================================================== -@@ -69,7 +76,7 @@ DOOR 01;35 # door +@@ -70,7 +77,7 @@ DOOR 01;35 # door BLK 40;33;01 # block device driver CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... @@ -40,7 +40,7 @@ index b465771..ad42b09 100644 SETGID 30;43 # regular file that is setgid (g+s) CAPABILITY 00 # regular file with capability (very expensive to lookup) diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor -index eab6258..1627b63 100644 +index e3b0ec3..39a0a4c 100644 --- a/DIR_COLORS.lightbgcolor +++ b/DIR_COLORS.lightbgcolor @@ -1,3 +1,9 @@ @@ -63,7 +63,7 @@ index eab6258..1627b63 100644 # =================================================================== # Terminal filters # =================================================================== -@@ -59,17 +68,17 @@ TERM xterm* +@@ -60,17 +69,17 @@ TERM xterm* #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all RESET 0 # reset to "normal" color @@ -86,7 +86,7 @@ index eab6258..1627b63 100644 SETUID 37;41 # regular file that is setuid (u+s) SETGID 30;43 # regular file that is setgid (g+s) CAPABILITY 00 # regular file with capability (very expensive to lookup) -@@ -78,7 +87,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky +@@ -79,7 +88,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for regular files with execute permission: @@ -96,5 +96,5 @@ index eab6258..1627b63 100644 # =================================================================== # File extension attributes -- -2.34.1 +2.49.0 diff --git a/coreutils-9.6-ls-selinux-crash.patch b/coreutils-9.6-ls-selinux-crash.patch deleted file mode 100644 index 70837cc..0000000 --- a/coreutils-9.6-ls-selinux-crash.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 915004f403cb25fadb207ddfdbe6a2f43bd44fac Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Fri, 17 Jan 2025 17:29:34 +0000 -Subject: [PATCH] ls: fix crash with --context - -* src/ls.c (main): Flag that we need to stat() -if we're going to get security context (call file_has_aclinfo_cache). -(file_has_aclinfo_cache): Be defensive and only lookup the device -for the file if the stat has been performed. -(has_capability_cache): Likewise. -* tests/ls/selinux-segfault.sh: Add a test case. -Reported by Bruno Haible. ---- - src/ls.c | 10 +++++----- - tests/ls/selinux-segfault.sh | 3 +++ - 2 files changed, 8 insertions(+), 5 deletions(-) - -diff --git a/src/ls.c b/src/ls.c -index 3215360216..f67167f160 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -1768,7 +1768,7 @@ main (int argc, char **argv) - - format_needs_stat = ((sort_type == sort_time) | (sort_type == sort_size) - | (format == long_format) -- | print_block_size | print_hyperlink); -+ | print_block_size | print_hyperlink | print_scontext); - format_needs_type = ((! format_needs_stat) - & (recursive | print_with_color | print_scontext - | directories_first -@@ -3309,7 +3309,7 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f, - static int unsupported_scontext_err; - static dev_t unsupported_device; - -- if (f->stat.st_dev == unsupported_device) -+ if (f->stat_ok && f->stat.st_dev == unsupported_device) - { - ai->buf = ai->u.__gl_acl_ch; - ai->size = 0; -@@ -3322,7 +3322,7 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f, - errno = 0; - int n = file_has_aclinfo (file, ai, flags); - int err = errno; -- if (n <= 0 && !acl_errno_valid (err)) -+ if (f->stat_ok && n <= 0 && !acl_errno_valid (err)) - { - unsupported_return = n; - unsupported_scontext = ai->scontext; -@@ -3342,14 +3342,14 @@ has_capability_cache (char const *file, struct fileinfo *f) - found that has_capability fails indicating lack of support. */ - static dev_t unsupported_device; - -- if (f->stat.st_dev == unsupported_device) -+ if (f->stat_ok && f->stat.st_dev == unsupported_device) - { - errno = ENOTSUP; - return 0; - } - - bool b = has_capability (file); -- if ( !b && !acl_errno_valid (errno)) -+ if (f->stat_ok && !b && !acl_errno_valid (errno)) - unsupported_device = f->stat.st_dev; - return b; - } -diff --git a/tests/ls/selinux-segfault.sh b/tests/ls/selinux-segfault.sh -index 11623acb3f..1cac2b5fc0 100755 ---- a/tests/ls/selinux-segfault.sh -+++ b/tests/ls/selinux-segfault.sh -@@ -30,4 +30,7 @@ mkdir sedir || framework_failure_ - ln -sf missing sedir/broken || framework_failure_ - returns_ 1 ls -L -R -Z -m sedir > out || fail=1 - -+# ls 9.6 would segfault with the following -+ls -Z . > out || fail=1 -+ - Exit $fail diff --git a/coreutils-9.6-who-m-systemd.patch b/coreutils-9.6-who-m-systemd.patch deleted file mode 100644 index 5d43364..0000000 --- a/coreutils-9.6-who-m-systemd.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 24450e5eecf012bc1ea8cab8d677a45fa42c1778 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= -Date: Mon, 24 Feb 2025 10:36:35 +0100 -Subject: who: fix -m with guessed tty names - -* who.c (scan_entries): Account for guessed tty names (e.g. -'sshd pts/1') from the readutmp module when using the systemd backend. -Addresses https://bugzilla.redhat.com/2343998 ---- - src/who.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/who.c b/src/who.c -index b56a1ac..17c1e34 100644 ---- a/src/who.c -+++ b/src/who.c -@@ -583,7 +583,7 @@ scan_entries (idx_t n, struct gl_utmp const *utmp_buf) - while (n--) - { - if (!my_line_only -- || STREQ (ttyname_b, utmp_buf->ut_line)) -+ || str_endswith (utmp_buf->ut_line, ttyname_b)) - { - if (need_users && IS_USER_PROCESS (utmp_buf)) - print_user (utmp_buf, boottime); diff --git a/coreutils-9.9-fix-cut-test-aarch64.patch b/coreutils-9.9-fix-cut-test-aarch64.patch new file mode 100644 index 0000000..600f87b --- /dev/null +++ b/coreutils-9.9-fix-cut-test-aarch64.patch @@ -0,0 +1,28 @@ +From 95044cb5eaea83d02f768feb5ab79fcf5e6ad782 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Mon, 22 Dec 2025 17:12:48 +0000 +Subject: [PATCH] tests: avoid false failure due to ulimit on aarch64 + +* tests/cut/cut-huge-range.sh: Add an extra 1MiB headroom, +which was seen with aarch64. +Reported at https://bugzilla.redhat.com/2424302 + +Cherry-picked-by: Lukáš Zaoral +Upstream-commit: 95044cb5eaea83d02f768feb5ab79fcf5e6ad782 +--- + tests/cut/cut-huge-range.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/cut/cut-huge-range.sh b/tests/cut/cut-huge-range.sh +index 4bd1b129d8..98d7e8f0b9 100755 +--- a/tests/cut/cut-huge-range.sh ++++ b/tests/cut/cut-huge-range.sh +@@ -22,6 +22,7 @@ getlimits_ + + vm=$(get_min_ulimit_v_ returns_ 0 cut -b1 /dev/null) \ + || skip_ 'shell lacks ulimit, or ASAN enabled' ++vm=$(($vm+1000)) # https://bugzilla.redhat.com/2424302 + + # Ensure we can cut up to our sentinel value. + # Don't use expr to subtract one, + diff --git a/coreutils-9.9-gnulib-c23.patch b/coreutils-9.9-gnulib-c23.patch new file mode 100644 index 0000000..82e3899 --- /dev/null +++ b/coreutils-9.9-gnulib-c23.patch @@ -0,0 +1,169 @@ +From 891761bca1aa78336e5b18c121075b6e4696c5d4 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Sun, 23 Nov 2025 00:50:40 -0800 +Subject: [PATCH] Port to C23 qualifier-generic fns like strchr +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This ports Gnulib to strict C23 platforms that reject code +like ‘char *q = strchr (P, 'x');’ when P is a pointer to const, +because in C23 strchr is a qualifier-generic function so +strchr (P, 'x') returns char const *. +This patch does not attempt to do the following two things, +which might be useful in the future: +1. When compiling on non-C23 platforms, check user code for +portability to platforms that define qualifier-generic functions. +2. Port Gnulib to platforms that have qualifier-generic functions +not listed in the C23 standard, e.g., strchrnul. I don’t know +of any such platforms. +* lib/mbschr.c (mbschr): +* lib/memchr2.c (memchr2): +Port to C23, where functions like strchr are qualifier-generic. +* lib/c++defs.h (_GL_FUNCDECL_SYS_NAME): New macro. +* lib/c++defs.h (_GL_FUNCDECL_SYS): +* lib/stdlib.in.h (bsearch): +Use it, to prevent C23 names like strchr from acting like macros. +* lib/string.in.h (memchr, strchr, strpbrk, strrchr): +Do not #undef when GNULIB_POSIXCHECK is defined, as this could +cause conforming C23 code to fail to conform. It’s not clear why +_GL_WARN_ON_USE_CXX; perhaps it was needed but isn’t any more? +But for now, limit the removal of #undef to these four functions +where #undeffing is clearly undesirable in C23. +* lib/wchar.in.h (wmemchr): Parenthesize function name in decl, +to prevent it from acting like a macro. + +Cherry-picked-by: Lukáš Zaoral +Upstream-commit: df17f4f37ed3ca373d23ad42eae51122bdb96626 +--- + lib/c++defs.h | 12 +++++++++++- + lib/mbschr.c | 2 +- + lib/memchr2.c | 2 +- + lib/stdlib.in.h | 6 +++--- + lib/string.in.h | 4 ---- + lib/wchar.in.h | 2 +- + 6 files changed, 17 insertions(+), 11 deletions(-) + +diff --git a/lib/c++defs.h b/lib/c++defs.h +index b77979a..7384457 100644 +--- a/lib/c++defs.h ++++ b/lib/c++defs.h +@@ -127,6 +127,16 @@ + #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters,...) \ + _GL_EXTERN_C_FUNC __VA_ARGS__ rettype rpl_func parameters + ++/* _GL_FUNCDECL_SYS_NAME (func) expands to plain func if C++, and to ++ parenthsized func otherwise. Parenthesization is needed in C23 if ++ the function is like strchr and so is a qualifier-generic macro ++ that expands to something more complicated. */ ++#ifdef __cplusplus ++# define _GL_FUNCDECL_SYS_NAME(func) func ++#else ++# define _GL_FUNCDECL_SYS_NAME(func) (func) ++#endif ++ + /* _GL_FUNCDECL_SYS (func, rettype, parameters, [attributes]); + declares the system function, named func, with the given prototype, + consisting of return type, parameters, and attributes. +@@ -139,7 +149,7 @@ + _GL_FUNCDECL_SYS (posix_openpt, int, (int flags), _GL_ATTRIBUTE_NODISCARD); + */ + #define _GL_FUNCDECL_SYS(func,rettype,parameters,...) \ +- _GL_EXTERN_C_FUNC __VA_ARGS__ rettype func parameters ++ _GL_EXTERN_C_FUNC __VA_ARGS__ rettype _GL_FUNCDECL_SYS_NAME (func) parameters + + /* _GL_CXXALIAS_RPL (func, rettype, parameters); + declares a C++ alias called GNULIB_NAMESPACE::func +diff --git a/lib/mbschr.c b/lib/mbschr.c +index c9e14b5..6582134 100644 +--- a/lib/mbschr.c ++++ b/lib/mbschr.c +@@ -65,5 +65,5 @@ mbschr (const char *string, int c) + return NULL; + } + else +- return strchr (string, c); ++ return (char *) strchr (string, c); + } +diff --git a/lib/memchr2.c b/lib/memchr2.c +index 7493823..d7724ae 100644 +--- a/lib/memchr2.c ++++ b/lib/memchr2.c +@@ -55,7 +55,7 @@ memchr2 (void const *s, int c1_in, int c2_in, size_t n) + c2 = (unsigned char) c2_in; + + if (c1 == c2) +- return memchr (s, c1, n); ++ return (void *) memchr (s, c1, n); + + /* Handle the first few bytes by reading one byte at a time. + Do this until VOID_PTR is aligned on a longword boundary. */ +diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h +index bef0aaa..fd0e1e0 100644 +--- a/lib/stdlib.in.h ++++ b/lib/stdlib.in.h +@@ -224,9 +224,9 @@ _GL_INLINE_HEADER_BEGIN + + /* Declarations for ISO C N3322. */ + #if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__ +-_GL_EXTERN_C void *bsearch (const void *__key, +- const void *__base, size_t __nmemb, size_t __size, +- int (*__compare) (const void *, const void *)) ++_GL_EXTERN_C void *_GL_FUNCDECL_SYS_NAME (bsearch) ++ (const void *__key, const void *__base, size_t __nmemb, size_t __size, ++ int (*__compare) (const void *, const void *)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3) _GL_ARG_NONNULL ((5)); + _GL_EXTERN_C void qsort (void *__base, size_t __nmemb, size_t __size, + int (*__compare) (const void *, const void *)) +diff --git a/lib/string.in.h b/lib/string.in.h +index fdcdd21..8b56acf 100644 +--- a/lib/string.in.h ++++ b/lib/string.in.h +@@ -409,7 +409,6 @@ _GL_CXXALIASWARN1 (memchr, void const *, + _GL_CXXALIASWARN (memchr); + # endif + #elif defined GNULIB_POSIXCHECK +-# undef memchr + /* Assume memchr is always declared. */ + _GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - " + "use gnulib module memchr for portability" ); +@@ -674,7 +673,6 @@ _GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - " + #if defined GNULIB_POSIXCHECK + /* strchr() does not work with multibyte strings if the locale encoding is + GB18030 and the character to be searched is a digit. */ +-# undef strchr + /* Assume strchr is always declared. */ + _GL_WARN_ON_USE_CXX (strchr, + const char *, char *, (const char *, int), +@@ -981,7 +979,6 @@ _GL_CXXALIASWARN (strpbrk); + Even in this simple case, it does not work with multibyte strings if the + locale encoding is GB18030 and one of the characters to be searched is a + digit. */ +-# undef strpbrk + _GL_WARN_ON_USE_CXX (strpbrk, + const char *, char *, (const char *, const char *), + "strpbrk cannot work correctly on character strings " +@@ -1011,7 +1008,6 @@ _GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings " + #if defined GNULIB_POSIXCHECK + /* strrchr() does not work with multibyte strings if the locale encoding is + GB18030 and the character to be searched is a digit. */ +-# undef strrchr + /* Assume strrchr is always declared. */ + _GL_WARN_ON_USE_CXX (strrchr, + const char *, char *, (const char *, int), +diff --git a/lib/wchar.in.h b/lib/wchar.in.h +index ab602a2..6be4515 100644 +--- a/lib/wchar.in.h ++++ b/lib/wchar.in.h +@@ -301,7 +301,7 @@ _GL_EXTERN_C int wcsncmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); + # ifndef __cplusplus +-_GL_EXTERN_C wchar_t *wmemchr (const wchar_t *__s, wchar_t __wc, size_t __n) ++_GL_EXTERN_C wchar_t *(wmemchr) (const wchar_t *__s, wchar_t __wc, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); + # endif + _GL_EXTERN_C wchar_t *wmemset (wchar_t *__s, wchar_t __wc, size_t __n) +-- +2.52.0 + diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index d19ec29..341ee2c 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,4 +1,4 @@ -From d179da4730f414069dd2c0ac995a32398718916c Mon Sep 17 00:00:00 2001 +From 91be1a584108a6a3d96f64382bbf206c4213b3db Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 29 Mar 2010 17:20:34 +0000 Subject: [PATCH] coreutils-df-direct.patch @@ -11,10 +11,10 @@ Subject: [PATCH] coreutils-df-direct.patch create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index ec58f6c..17cda80 100644 +index b420606..0ccb368 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -12467,6 +12467,13 @@ some systems (notably Solaris), doing this yields more up to date results, +@@ -12597,6 +12597,13 @@ some systems (notably Solaris), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -29,10 +29,10 @@ index ec58f6c..17cda80 100644 @opindex --total @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index 5c7efd8..52ece19 100644 +index 75e638c..ef9f0a7 100644 --- a/src/df.c +++ b/src/df.c -@@ -122,6 +122,9 @@ static bool print_type; +@@ -121,6 +121,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -42,7 +42,7 @@ index 5c7efd8..52ece19 100644 /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -249,13 +252,15 @@ enum +@@ -248,13 +251,15 @@ enum NO_SYNC_OPTION = CHAR_MAX + 1, SYNC_OPTION, TOTAL_OPTION, @@ -71,7 +71,7 @@ index 5c7efd8..52ece19 100644 if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1452,6 +1460,17 @@ get_point (char const *point, const struct stat *statp) +@@ -1446,6 +1454,17 @@ get_point (char const *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -89,7 +89,7 @@ index 5c7efd8..52ece19 100644 if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_device (name)) return; -@@ -1522,6 +1541,7 @@ or all file systems by default.\n\ +@@ -1516,6 +1535,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -97,7 +97,7 @@ index 5c7efd8..52ece19 100644 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1616,6 +1636,9 @@ main (int argc, char **argv) +@@ -1610,6 +1630,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -107,7 +107,7 @@ index 5c7efd8..52ece19 100644 case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1712,6 +1735,13 @@ main (int argc, char **argv) +@@ -1706,6 +1729,13 @@ main (int argc, char **argv) } } @@ -183,5 +183,5 @@ index 0000000..8e4cfb8 + +Exit $fail -- -2.48.1 +2.52.0 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index e7699c1..83579e9 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From a153c65067f6c09cf2cf38dc7c149aa1521c615a Mon Sep 17 00:00:00 2001 +From a81b096084524e9aeef5e8b81fc829eb9efec581 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -7,39 +7,31 @@ Subject: [PATCH] coreutils-i18n.patch bootstrap.conf | 2 + configure.ac | 6 + lib/linebuffer.h | 8 + - lib/mbchar.c | 23 ++ - lib/mbchar.h | 373 +++++++++++++++++ lib/mbfile.c | 20 + - lib/mbfile.h | 267 ++++++++++++ - m4/mbchar.m4 | 13 + - m4/mbfile.m4 | 14 + + lib/mbfile.h | 283 +++++++++++++ + m4/mbfile.m4 | 16 + src/cut.c | 508 +++++++++++++++++++++-- src/expand-common.c | 114 ++++++ src/expand-common.h | 12 + src/expand.c | 90 +++- - src/fold.c | 311 ++++++++++++-- src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- - src/sort.c | 792 +++++++++++++++++++++++++++++++++--- + src/sort.c | 791 +++++++++++++++++++++++++++++++++--- src/unexpand.c | 101 ++++- 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 | 51 ++- 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 ++++++++ - 30 files changed, 3603 insertions(+), 197 deletions(-) - create mode 100644 lib/mbchar.c - create mode 100644 lib/mbchar.h + 25 files changed, 2879 insertions(+), 167 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h - create mode 100644 m4/mbchar.m4 create mode 100644 m4/mbfile.m4 create mode 100644 tests/expand/mb.sh create mode 100644 tests/i18n/sort.sh @@ -47,23 +39,23 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index 380fa11..ca80e6f 100644 +index ec68ac8..ec2fbbe 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -165,6 +165,8 @@ gnulib_modules=" - maintainer-makefile +@@ -171,6 +171,8 @@ gnulib_modules=" malloc-gnu manywarnings + mbbuf + mbchar + mbfile mbrlen mbrtoc32 mbrtowc diff --git a/configure.ac b/configure.ac -index bf6da2a..321016d 100644 +index 5e99ef3..ac07577 100644 --- a/configure.ac +++ b/configure.ac -@@ -505,6 +505,12 @@ fi +@@ -465,6 +465,12 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -102,422 +94,14 @@ index ca56f80..509b7e6 100644 }; /* Initialize linebuffer LINEBUFFER for use. */ -diff --git a/lib/mbchar.c b/lib/mbchar.c -new file mode 100644 -index 0000000..d94b7c3 ---- /dev/null -+++ b/lib/mbchar.c -@@ -0,0 +1,23 @@ -+/* Copyright (C) 2001, 2006, 2009-2024 Free Software Foundation, Inc. -+ -+ This file is free software: you can redistribute it and/or modify -+ it under the terms of the GNU Lesser General Public License as -+ published by the Free Software Foundation; either version 2.1 of the -+ License, or (at your option) any later version. -+ -+ This file is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public License -+ along with this program. If not, see . */ -+ -+ -+#include -+ -+#define MBCHAR_INLINE _GL_EXTERN_INLINE -+ -+#include -+ -+#include "mbchar.h" -diff --git a/lib/mbchar.h b/lib/mbchar.h -new file mode 100644 -index 0000000..c06ef11 ---- /dev/null -+++ b/lib/mbchar.h -@@ -0,0 +1,373 @@ -+/* Multibyte character data type. -+ Copyright (C) 2001, 2005-2007, 2009-2024 Free Software Foundation, Inc. -+ -+ This file is free software: you can redistribute it and/or modify -+ it under the terms of the GNU Lesser General Public License as -+ published by the Free Software Foundation; either version 2.1 of the -+ License, or (at your option) any later version. -+ -+ This file is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public License -+ along with this program. If not, see . */ -+ -+/* Written by Bruno Haible . */ -+ -+/* A multibyte character is a short subsequence of a char* string, -+ representing a single 32-bit wide character. -+ -+ We use multibyte characters instead of 32-bit wide characters because -+ of the following goals: -+ 1) correct multibyte handling, i.e. operate according to the LC_CTYPE -+ locale, -+ 2) ease of maintenance, i.e. the maintainer needs not know all details -+ of the ISO C 99 standard, -+ 3) don't fail grossly if the input is not in the encoding set by the -+ locale, because often different encodings are in use in the same -+ countries (ISO-8859-1/UTF-8, EUC-JP/Shift_JIS, ...), -+ 4) fast in the case of ASCII characters. -+ -+ Multibyte characters are only accessed through the mb* macros. -+ -+ mb_ptr (mbc) -+ return a pointer to the beginning of the multibyte sequence. -+ -+ mb_len (mbc) -+ returns the number of bytes occupied by the multibyte sequence. -+ Always > 0. -+ -+ mb_iseq (mbc, sc) -+ returns true if mbc is the standard ASCII character sc. -+ -+ mb_isnul (mbc) -+ returns true if mbc is the nul character. -+ -+ mb_cmp (mbc1, mbc2) -+ returns a positive, zero, or negative value depending on whether mbc1 -+ sorts after, same or before mbc2. -+ -+ mb_casecmp (mbc1, mbc2) -+ returns a positive, zero, or negative value depending on whether mbc1 -+ sorts after, same or before mbc2, modulo upper/lowercase conversion. -+ -+ mb_equal (mbc1, mbc2) -+ returns true if mbc1 and mbc2 are equal. -+ -+ mb_caseequal (mbc1, mbc2) -+ returns true if mbc1 and mbc2 are equal modulo upper/lowercase conversion. -+ -+ mb_isalnum (mbc) -+ returns true if mbc is alphanumeric. -+ -+ mb_isalpha (mbc) -+ returns true if mbc is alphabetic. -+ -+ mb_isascii(mbc) -+ returns true if mbc is plain ASCII. -+ -+ mb_isblank (mbc) -+ returns true if mbc is a blank. -+ -+ mb_iscntrl (mbc) -+ returns true if mbc is a control character. -+ -+ mb_isdigit (mbc) -+ returns true if mbc is a decimal digit. -+ -+ mb_isgraph (mbc) -+ returns true if mbc is a graphic character. -+ -+ mb_islower (mbc) -+ returns true if mbc is lowercase. -+ -+ mb_isprint (mbc) -+ returns true if mbc is a printable character. -+ -+ mb_ispunct (mbc) -+ returns true if mbc is a punctuation character. -+ -+ mb_isspace (mbc) -+ returns true if mbc is a space character. -+ -+ mb_isupper (mbc) -+ returns true if mbc is uppercase. -+ -+ mb_isxdigit (mbc) -+ returns true if mbc is a hexadecimal digit. -+ -+ mb_width (mbc) -+ returns the number of columns on the output device occupied by mbc. -+ Always >= 0. -+ -+ mb_putc (mbc, stream) -+ outputs mbc on stream, a byte oriented FILE stream opened for output. -+ -+ mb_setascii (&mbc, sc) -+ assigns the standard ASCII character sc to mbc. -+ (Only available if the 'mbfile' module is in use.) -+ -+ mb_copy (&destmbc, &srcmbc) -+ copies srcmbc to destmbc. -+ -+ Here are the function prototypes of the macros. -+ -+ extern const char * mb_ptr (const mbchar_t mbc); -+ extern size_t mb_len (const mbchar_t mbc); -+ extern bool mb_iseq (const mbchar_t mbc, char sc); -+ extern bool mb_isnul (const mbchar_t mbc); -+ extern int mb_cmp (const mbchar_t mbc1, const mbchar_t mbc2); -+ extern int mb_casecmp (const mbchar_t mbc1, const mbchar_t mbc2); -+ extern bool mb_equal (const mbchar_t mbc1, const mbchar_t mbc2); -+ extern bool mb_caseequal (const mbchar_t mbc1, const mbchar_t mbc2); -+ extern bool mb_isalnum (const mbchar_t mbc); -+ extern bool mb_isalpha (const mbchar_t mbc); -+ extern bool mb_isascii (const mbchar_t mbc); -+ extern bool mb_isblank (const mbchar_t mbc); -+ extern bool mb_iscntrl (const mbchar_t mbc); -+ extern bool mb_isdigit (const mbchar_t mbc); -+ extern bool mb_isgraph (const mbchar_t mbc); -+ extern bool mb_islower (const mbchar_t mbc); -+ extern bool mb_isprint (const mbchar_t mbc); -+ extern bool mb_ispunct (const mbchar_t mbc); -+ extern bool mb_isspace (const mbchar_t mbc); -+ extern bool mb_isupper (const mbchar_t mbc); -+ extern bool mb_isxdigit (const mbchar_t mbc); -+ extern int mb_width (const mbchar_t mbc); -+ extern void mb_putc (const mbchar_t mbc, FILE *stream); -+ extern void mb_setascii (mbchar_t *new, char sc); -+ extern void mb_copy (mbchar_t *new, const mbchar_t *old); -+ */ -+ -+#ifndef _MBCHAR_H -+#define _MBCHAR_H 1 -+ -+/* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */ -+#if !_GL_CONFIG_H_INCLUDED -+ #error "Please include config.h first." -+#endif -+ -+#include -+#include -+ -+_GL_INLINE_HEADER_BEGIN -+#ifndef MBCHAR_INLINE -+# define MBCHAR_INLINE _GL_INLINE -+#endif -+ -+/* The longest multibyte characters, nowadays, are 4 bytes long. -+ Regardless of the values of MB_CUR_MAX and MB_LEN_MAX. */ -+#define MBCHAR_BUF_SIZE 4 -+ -+struct mbchar -+{ -+ const char *ptr; /* pointer to current character */ -+ size_t bytes; /* number of bytes of current character, > 0 */ -+ bool wc_valid; /* true if wc is a valid 32-bit wide character */ -+ char32_t wc; /* if wc_valid: the current character */ -+#if defined GNULIB_MBFILE -+ char buf[MBCHAR_BUF_SIZE]; /* room for the bytes, used for file input only */ -+#endif -+}; -+ -+/* EOF (not a real character) is represented with bytes = 0 and -+ wc_valid = false. */ -+ -+typedef struct mbchar mbchar_t; -+ -+/* Access the current character. */ -+#define mb_ptr(mbc) ((mbc).ptr) -+#define mb_len(mbc) ((mbc).bytes) -+ -+/* Comparison of characters. */ -+#define mb_iseq(mbc, sc) ((mbc).wc_valid && (mbc).wc == (sc)) -+#define mb_isnul(mbc) ((mbc).wc_valid && (mbc).wc == 0) -+#define mb_cmp(mbc1, mbc2) \ -+ ((mbc1).wc_valid \ -+ ? ((mbc2).wc_valid \ -+ ? _GL_CMP ((mbc1).wc, (mbc2).wc) \ -+ : -1) \ -+ : ((mbc2).wc_valid \ -+ ? 1 \ -+ : (mbc1).bytes == (mbc2).bytes \ -+ ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ -+ : (mbc1).bytes < (mbc2).bytes \ -+ ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ -+ : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) -+#define mb_casecmp(mbc1, mbc2) \ -+ ((mbc1).wc_valid \ -+ ? ((mbc2).wc_valid \ -+ ? _GL_CMP (c32tolower ((mbc1).wc), c32tolower ((mbc2).wc)) \ -+ : -1) \ -+ : ((mbc2).wc_valid \ -+ ? 1 \ -+ : (mbc1).bytes == (mbc2).bytes \ -+ ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ -+ : (mbc1).bytes < (mbc2).bytes \ -+ ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ -+ : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) -+#define mb_equal(mbc1, mbc2) \ -+ ((mbc1).wc_valid && (mbc2).wc_valid \ -+ ? (mbc1).wc == (mbc2).wc \ -+ : (mbc1).bytes == (mbc2).bytes \ -+ && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) -+#define mb_caseequal(mbc1, mbc2) \ -+ ((mbc1).wc_valid && (mbc2).wc_valid \ -+ ? c32tolower ((mbc1).wc) == c32tolower ((mbc2).wc) \ -+ : (mbc1).bytes == (mbc2).bytes \ -+ && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) -+ -+/* , classification. */ -+#define mb_isascii(mbc) \ -+ ((mbc).wc_valid && (mbc).wc >= 0 && (mbc).wc <= 127) -+#define mb_isalnum(mbc) ((mbc).wc_valid && c32isalnum ((mbc).wc)) -+#define mb_isalpha(mbc) ((mbc).wc_valid && c32isalpha ((mbc).wc)) -+#define mb_isblank(mbc) ((mbc).wc_valid && c32isblank ((mbc).wc)) -+#define mb_iscntrl(mbc) ((mbc).wc_valid && c32iscntrl ((mbc).wc)) -+#define mb_isdigit(mbc) ((mbc).wc_valid && c32isdigit ((mbc).wc)) -+#define mb_isgraph(mbc) ((mbc).wc_valid && c32isgraph ((mbc).wc)) -+#define mb_islower(mbc) ((mbc).wc_valid && c32islower ((mbc).wc)) -+#define mb_isprint(mbc) ((mbc).wc_valid && c32isprint ((mbc).wc)) -+#define mb_ispunct(mbc) ((mbc).wc_valid && c32ispunct ((mbc).wc)) -+#define mb_isspace(mbc) ((mbc).wc_valid && c32isspace ((mbc).wc)) -+#define mb_isupper(mbc) ((mbc).wc_valid && c32isupper ((mbc).wc)) -+#define mb_isxdigit(mbc) ((mbc).wc_valid && c32isxdigit ((mbc).wc)) -+ -+/* Extra function. */ -+ -+/* Unprintable characters appear as a small box of width 1. */ -+#define MB_UNPRINTABLE_WIDTH 1 -+ -+MBCHAR_INLINE int -+mb_width_aux (char32_t wc) -+{ -+ int w = c32width (wc); -+ /* For unprintable characters, arbitrarily return 0 for control characters -+ and MB_UNPRINTABLE_WIDTH otherwise. */ -+ return (w >= 0 ? w : c32iscntrl (wc) ? 0 : MB_UNPRINTABLE_WIDTH); -+} -+ -+#define mb_width(mbc) \ -+ ((mbc).wc_valid ? mb_width_aux ((mbc).wc) : MB_UNPRINTABLE_WIDTH) -+ -+/* Output. */ -+#define mb_putc(mbc, stream) fwrite ((mbc).ptr, 1, (mbc).bytes, (stream)) -+ -+#if defined GNULIB_MBFILE -+/* Assignment. */ -+# define mb_setascii(mbc, sc) \ -+ ((mbc)->ptr = (mbc)->buf, (mbc)->bytes = 1, (mbc)->wc_valid = 1, \ -+ (mbc)->wc = (mbc)->buf[0] = (sc)) -+#endif -+ -+/* Copying a character. */ -+MBCHAR_INLINE void -+mb_copy (mbchar_t *new_mbc, const mbchar_t *old_mbc) -+{ -+#if defined GNULIB_MBFILE -+ if (old_mbc->ptr == &old_mbc->buf[0]) -+ { -+ memcpy (&new_mbc->buf[0], &old_mbc->buf[0], old_mbc->bytes); -+ new_mbc->ptr = &new_mbc->buf[0]; -+ } -+ else -+#endif -+ new_mbc->ptr = old_mbc->ptr; -+ new_mbc->bytes = old_mbc->bytes; -+ if ((new_mbc->wc_valid = old_mbc->wc_valid)) -+ new_mbc->wc = old_mbc->wc; -+} -+ -+ -+/* is_basic(c) tests whether the single-byte character c is -+ - in the ISO C "basic character set" or is one of '@', '$', and '`' -+ which ISO C 23 § 5.2.1.1.(1) guarantees to be single-byte and in -+ practice are safe to treat as basic in the execution character set, -+ or -+ - in the POSIX "portable character set", which -+ -+ equally guarantees to be single-byte. -+ This is a convenience function, and is in this file only to share code -+ between mbiter.h, mbuiter.h, and mbfile.h. */ -+#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ -+ && ('$' == 36) && ('%' == 37) && ('&' == 38) && ('\'' == 39) \ -+ && ('(' == 40) && (')' == 41) && ('*' == 42) && ('+' == 43) \ -+ && (',' == 44) && ('-' == 45) && ('.' == 46) && ('/' == 47) \ -+ && ('0' == 48) && ('1' == 49) && ('2' == 50) && ('3' == 51) \ -+ && ('4' == 52) && ('5' == 53) && ('6' == 54) && ('7' == 55) \ -+ && ('8' == 56) && ('9' == 57) && (':' == 58) && (';' == 59) \ -+ && ('<' == 60) && ('=' == 61) && ('>' == 62) && ('?' == 63) \ -+ && ('@' == 64) && ('A' == 65) && ('B' == 66) && ('C' == 67) \ -+ && ('D' == 68) && ('E' == 69) && ('F' == 70) && ('G' == 71) \ -+ && ('H' == 72) && ('I' == 73) && ('J' == 74) && ('K' == 75) \ -+ && ('L' == 76) && ('M' == 77) && ('N' == 78) && ('O' == 79) \ -+ && ('P' == 80) && ('Q' == 81) && ('R' == 82) && ('S' == 83) \ -+ && ('T' == 84) && ('U' == 85) && ('V' == 86) && ('W' == 87) \ -+ && ('X' == 88) && ('Y' == 89) && ('Z' == 90) && ('[' == 91) \ -+ && ('\\' == 92) && (']' == 93) && ('^' == 94) && ('_' == 95) \ -+ && ('`' == 96) && ('a' == 97) && ('b' == 98) && ('c' == 99) \ -+ && ('d' == 100) && ('e' == 101) && ('f' == 102) && ('g' == 103) \ -+ && ('h' == 104) && ('i' == 105) && ('j' == 106) && ('k' == 107) \ -+ && ('l' == 108) && ('m' == 109) && ('n' == 110) && ('o' == 111) \ -+ && ('p' == 112) && ('q' == 113) && ('r' == 114) && ('s' == 115) \ -+ && ('t' == 116) && ('u' == 117) && ('v' == 118) && ('w' == 119) \ -+ && ('x' == 120) && ('y' == 121) && ('z' == 122) && ('{' == 123) \ -+ && ('|' == 124) && ('}' == 125) && ('~' == 126) -+/* The character set is ISO-646, not EBCDIC. */ -+# define IS_BASIC_ASCII 1 -+ -+/* All locale encodings (see localcharset.h) map the characters 0x00..0x7F -+ to U+0000..U+007F, like ASCII, except for -+ CP864 different mapping of '%' -+ SHIFT_JIS different mappings of 0x5C, 0x7E -+ JOHAB different mapping of 0x5C -+ However, these characters in the range 0x20..0x7E are in the ISO C -+ "basic character set" and in the POSIX "portable character set", which -+ ISO C and POSIX guarantee to be single-byte. Thus, locales with these -+ encodings are not POSIX compliant. And they are most likely not in use -+ any more (as of 2023). */ -+# define is_basic(c) ((unsigned char) (c) < 0x80) -+ -+#else -+ -+MBCHAR_INLINE bool -+is_basic (char c) -+{ -+ switch (c) -+ { -+ case '\0': -+ case '\007': case '\010': -+ case '\t': case '\n': case '\v': case '\f': case '\r': -+ case ' ': case '!': case '"': case '#': case '$': case '%': -+ case '&': case '\'': case '(': case ')': case '*': -+ case '+': case ',': case '-': case '.': case '/': -+ case '0': case '1': case '2': case '3': case '4': -+ case '5': case '6': case '7': case '8': case '9': -+ case ':': case ';': case '<': case '=': case '>': -+ case '?': case '@': -+ case 'A': case 'B': case 'C': case 'D': case 'E': -+ case 'F': case 'G': case 'H': case 'I': case 'J': -+ case 'K': case 'L': case 'M': case 'N': case 'O': -+ case 'P': case 'Q': case 'R': case 'S': case 'T': -+ case 'U': case 'V': case 'W': case 'X': case 'Y': -+ case 'Z': -+ case '[': case '\\': case ']': case '^': case '_': case '`': -+ case 'a': case 'b': case 'c': case 'd': case 'e': -+ case 'f': case 'g': case 'h': case 'i': case 'j': -+ case 'k': case 'l': case 'm': case 'n': case 'o': -+ case 'p': case 'q': case 'r': case 's': case 't': -+ case 'u': case 'v': case 'w': case 'x': case 'y': -+ case 'z': case '{': case '|': case '}': case '~': -+ return 1; -+ default: -+ return 0; -+ } -+} -+ -+#endif -+ -+_GL_INLINE_HEADER_END -+ -+#endif /* _MBCHAR_H */ diff --git a/lib/mbfile.c b/lib/mbfile.c new file mode 100644 -index 0000000..8d2957b +index 0000000..f4e3e77 --- /dev/null +++ b/lib/mbfile.c @@ -0,0 +1,20 @@ +/* Multibyte character I/O: macros for multi-byte encodings. -+ Copyright (C) 2012-2023 Free Software Foundation, Inc. ++ Copyright (C) 2012-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as @@ -538,12 +122,12 @@ index 0000000..8d2957b +#include "mbfile.h" diff --git a/lib/mbfile.h b/lib/mbfile.h new file mode 100644 -index 0000000..ad61c19 +index 0000000..c852f31 --- /dev/null +++ b/lib/mbfile.h -@@ -0,0 +1,267 @@ +@@ -0,0 +1,283 @@ +/* Multibyte character I/O: macros for multi-byte encodings. -+ Copyright (C) 2001, 2005, 2009-2023 Free Software Foundation, Inc. ++ Copyright (C) 2001, 2005, 2009-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as @@ -598,6 +182,7 @@ index 0000000..ad61c19 + +#include +#include ++#include +#include +#include + @@ -608,14 +193,22 @@ index 0000000..ad61c19 +# define MBFILE_INLINE _GL_INLINE +#endif + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++/* Guarantee two characters of pushback. */ ++#define MBFILE_MAX_PUSHBACK 2 ++ +struct mbfile_multi { + FILE *fp; + bool eof_seen; -+ bool have_pushback; ++ unsigned int pushback_count; /* <= MBFILE_MAX_PUSHBACK */ + mbstate_t state; + unsigned int bufcount; + char buf[MBCHAR_BUF_SIZE]; -+ struct mbchar pushback; ++ struct mbchar pushback[MBFILE_MAX_PUSHBACK]; +}; + +MBFILE_INLINE void @@ -624,19 +217,19 @@ index 0000000..ad61c19 + unsigned int new_bufcount; + size_t bytes; + ++ /* Return character pushed back, if there is one. */ ++ if (mbf->pushback_count > 0) ++ { ++ mb_copy (mbc, &mbf->pushback[mbf->pushback_count - 1]); ++ mbf->pushback_count--; ++ return; ++ } ++ + /* If EOF has already been seen, don't use getc. This matters if + mbf->fp is connected to an interactive tty. */ + if (mbf->eof_seen) + goto eof; + -+ /* Return character pushed back, if there is one. */ -+ if (mbf->have_pushback) -+ { -+ mb_copy (mbc, &mbf->pushback); -+ mbf->have_pushback = false; -+ return; -+ } -+ + new_bufcount = mbf->bufcount; + + /* If mbf->state is not in an initial state, some more 32-bit wide character @@ -785,8 +378,10 @@ index 0000000..ad61c19 +MBFILE_INLINE void +mbfile_multi_ungetc (const struct mbchar *mbc, struct mbfile_multi *mbf) +{ -+ mb_copy (&mbf->pushback, mbc); -+ mbf->have_pushback = true; ++ if (mbf->pushback_count == MBFILE_MAX_PUSHBACK) ++ abort (); ++ mb_copy (&mbf->pushback[mbf->pushback_count], mbc); ++ mbf->pushback_count++; +} + +typedef struct mbfile_multi mb_file_t; @@ -796,7 +391,7 @@ index 0000000..ad61c19 +#define mbf_init(mbf, stream) \ + ((mbf).fp = (stream), \ + (mbf).eof_seen = false, \ -+ (mbf).have_pushback = false, \ ++ (mbf).pushback_count = 0, \ + mbszero (&(mbf).state), \ + (mbf).bufcount = 0) + @@ -806,39 +401,27 @@ index 0000000..ad61c19 + +#define mb_iseof(mbc) ((mbc).bytes == 0) + ++ ++#ifdef __cplusplus ++} ++#endif ++ +_GL_INLINE_HEADER_END + +#endif /* _MBFILE_H */ -diff --git a/m4/mbchar.m4 b/m4/mbchar.m4 -new file mode 100644 -index 0000000..471e8c4 ---- /dev/null -+++ b/m4/mbchar.m4 -@@ -0,0 +1,13 @@ -+# mbchar.m4 serial 9 -+dnl Copyright (C) 2005-2007, 2009-2024 Free Software Foundation, Inc. -+dnl This file is free software; the Free Software Foundation -+dnl gives unlimited permission to copy and/or distribute it, -+dnl with or without modifications, as long as this notice is preserved. -+ -+dnl autoconf tests required for use of mbchar.m4 -+dnl From Bruno Haible. -+ -+AC_DEFUN([gl_MBCHAR], -+[ -+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) -+]) diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 new file mode 100644 -index 0000000..83068a9 +index 0000000..1d126e0 --- /dev/null +++ b/m4/mbfile.m4 -@@ -0,0 +1,14 @@ -+# mbfile.m4 serial 7 -+dnl Copyright (C) 2005, 2008-2023 Free Software Foundation, Inc. +@@ -0,0 +1,16 @@ ++# mbfile.m4 ++# serial 7 ++dnl Copyright (C) 2005, 2008-2025 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. ++dnl This file is offered as-is, without any warranty. + +dnl autoconf tests required for use of mbfile.h +dnl From Bruno Haible. @@ -849,7 +432,7 @@ index 0000000..83068a9 + : +]) diff --git a/src/cut.c b/src/cut.c -index b424997..c9f181c 100644 +index f0effb9..36479d6 100644 --- a/src/cut.c +++ b/src/cut.c @@ -27,6 +27,11 @@ @@ -1509,7 +1092,7 @@ index b424997..c9f181c 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index 2dbbbe4..91a90a3 100644 +index 14dd804..0d8eaaa 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -1520,7 +1103,7 @@ index 2dbbbe4..91a90a3 100644 #include "system.h" #include "c-ctype.h" #include "fadvise.h" -@@ -123,6 +124,119 @@ set_increment_size (colno tabval) +@@ -132,6 +133,119 @@ set_increment_size (colno tabval) return ok; } @@ -1641,7 +1224,7 @@ index 2dbbbe4..91a90a3 100644 to the list of tab stops. */ extern void diff --git a/src/expand-common.h b/src/expand-common.h -index fe6c8ed..80a1280 100644 +index 46ef4e3..e19469b 100644 --- a/src/expand-common.h +++ b/src/expand-common.h @@ -29,6 +29,18 @@ extern idx_t max_column_width; @@ -1818,414 +1401,11 @@ index 5ec7ce9..65ac315 100644 } } -diff --git a/src/fold.c b/src/fold.c -index b64aad4..a156337 100644 ---- a/src/fold.c -+++ b/src/fold.c -@@ -23,10 +23,32 @@ - #include - #include - -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ -+#if HAVE_WCHAR_H -+# include -+#endif -+ -+/* Get iswprint(), iswblank(), wcwidth(). */ -+#if HAVE_WCTYPE_H -+# include -+#endif -+ - #include "system.h" - #include "fadvise.h" - #include "xdectoint.h" - -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC -+ installation; work around this configuration error. */ -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 -+# undef MB_LEN_MAX -+# define MB_LEN_MAX 16 -+#endif -+ -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ -+#if HAVE_MBRTOWC && defined mbstate_t -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) -+#endif -+ - #define TAB_WIDTH 8 - - /* The official name of this program (e.g., no 'g' prefix). */ -@@ -34,20 +56,41 @@ - - #define AUTHORS proper_name ("David MacKenzie") - -+#define FATAL_ERROR(Message) \ -+ do \ -+ { \ -+ error (0, 0, (Message)); \ -+ usage (2); \ -+ } \ -+ while (0) -+ -+enum operating_mode -+{ -+ /* Fold texts by columns that are at the given positions. */ -+ column_mode, -+ -+ /* Fold texts by bytes that are at the given positions. */ -+ byte_mode, -+ -+ /* Fold texts by characters that are at the given positions. */ -+ character_mode, -+}; -+ -+/* The argument shows current mode. (Default: column_mode) */ -+static enum operating_mode operating_mode; -+ - /* If nonzero, try to break on whitespace. */ - static bool break_spaces; - --/* If nonzero, count bytes, not column positions. */ --static bool count_bytes; -- - /* If nonzero, at least one of the files we read was standard input. */ - static bool have_read_stdin; - --static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::"; -+static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::"; - - static struct option const longopts[] = - { - {"bytes", no_argument, nullptr, 'b'}, -+ {"characters", no_argument, nullptr, 'c'}, - {"spaces", no_argument, nullptr, 's'}, - {"width", required_argument, nullptr, 'w'}, - {GETOPT_HELP_OPTION_DECL}, -@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ - - fputs (_("\ - -b, --bytes count bytes rather than columns\n\ -+ -c, --characters count characters rather than columns\n\ - -s, --spaces break at spaces\n\ - -w, --width=WIDTH use WIDTH columns instead of 80\n\ - "), stdout); -@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ - static size_t - adjust_column (size_t column, char c) - { -- if (!count_bytes) -+ if (operating_mode != byte_mode) - { - if (c == '\b') - { -@@ -115,30 +159,14 @@ adjust_column (size_t column, char c) - to stdout, with maximum line length WIDTH. - Return true if successful. */ - --static bool --fold_file (char const *filename, size_t width) -+static void -+fold_text (FILE *istream, size_t width, int *saved_errno) - { -- FILE *istream; - int c; - size_t column = 0; /* Screen column where next char will go. */ - idx_t offset_out = 0; /* Index in 'line_out' for next char. */ - static char *line_out = nullptr; - static idx_t allocated_out = 0; -- int saved_errno; -- -- if (STREQ (filename, "-")) -- { -- istream = stdin; -- have_read_stdin = true; -- } -- else -- istream = fopen (filename, "r"); -- -- if (istream == nullptr) -- { -- error (0, errno, "%s", quotef (filename)); -- return false; -- } - - fadvise (istream, FADVISE_SEQUENTIAL); - -@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t width) - bool found_blank = false; - idx_t logical_end = offset_out; - -+ /* If LINE_OUT has no wide character, -+ put a new wide character in LINE_OUT -+ if column is bigger than width. */ -+ if (offset_out == 0) -+ { -+ line_out[offset_out++] = c; -+ continue; -+ } -+ - /* Look for the last blank. */ - while (logical_end) - { -@@ -212,13 +249,224 @@ fold_file (char const *filename, size_t width) - line_out[offset_out++] = c; - } - -- saved_errno = errno; -+ *saved_errno = errno; - if (!ferror (istream)) -- saved_errno = 0; -+ *saved_errno = 0; - - if (offset_out) - fwrite (line_out, sizeof (char), offset_out, stdout); - -+} -+ -+#if HAVE_MBRTOWC -+static void -+fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) -+{ -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ size_t buflen = 0; /* The length of the byte sequence in buf. */ -+ char *bufpos = buf; /* Next read position of BUF. */ -+ wint_t wc; /* A gotten wide character. */ -+ size_t mblength; /* The byte size of a multibyte character which shows -+ as same character as WC. */ -+ mbstate_t state, state_bak; /* State of the stream. */ -+ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ -+ -+ static char *line_out = NULL; -+ idx_t offset_out = 0; /* Index in `line_out' for next char. */ -+ static idx_t allocated_out = 0; -+ -+ int increment; -+ size_t column = 0; -+ -+ size_t last_blank_pos; -+ size_t last_blank_column; -+ int is_blank_seen; -+ int last_blank_increment = 0; -+ int is_bs_following_last_blank; -+ size_t bs_following_last_blank_num; -+ int is_cr_after_last_blank; -+ -+#define CLEAR_FLAGS \ -+ do \ -+ { \ -+ last_blank_pos = 0; \ -+ last_blank_column = 0; \ -+ is_blank_seen = 0; \ -+ is_bs_following_last_blank = 0; \ -+ bs_following_last_blank_num = 0; \ -+ is_cr_after_last_blank = 0; \ -+ } \ -+ while (0) -+ -+#define START_NEW_LINE \ -+ do \ -+ { \ -+ putchar ('\n'); \ -+ column = 0; \ -+ offset_out = 0; \ -+ CLEAR_FLAGS; \ -+ } \ -+ while (0) -+ -+ CLEAR_FLAGS; -+ memset (&state, '\0', sizeof(mbstate_t)); -+ -+ for (;; bufpos += mblength, buflen -= mblength) -+ { -+ if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream)) -+ { -+ memmove (buf, bufpos, buflen); -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream); -+ bufpos = buf; -+ } -+ -+ if (buflen < 1) -+ break; -+ -+ /* Get a wide character. */ -+ state_bak = state; -+ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state); -+ -+ switch (mblength) -+ { -+ case (size_t)-1: -+ case (size_t)-2: -+ convfail++; -+ state = state_bak; -+ /* Fall through. */ -+ -+ case 0: -+ mblength = 1; -+ break; -+ } -+ -+rescan: -+ if (convfail) -+ increment = 1; -+ else if (wc == L'\n') -+ { -+ /* preserve newline */ -+ fwrite (line_out, sizeof(char), offset_out, stdout); -+ START_NEW_LINE; -+ continue; -+ } -+ else if (operating_mode == byte_mode) /* byte mode */ -+ increment = mblength; -+ else if (operating_mode == character_mode) /* character mode */ -+ increment = 1; -+ else /* column mode */ -+ { -+ switch (wc) -+ { -+ case L'\b': -+ increment = (column > 0) ? -1 : 0; -+ break; -+ -+ case L'\r': -+ increment = -1 * column; -+ break; -+ -+ case L'\t': -+ increment = 8 - column % 8; -+ break; -+ -+ default: -+ increment = wcwidth (wc); -+ increment = (increment < 0) ? 0 : increment; -+ } -+ } -+ -+ if (column + increment > width && break_spaces && last_blank_pos) -+ { -+ fwrite (line_out, sizeof(char), last_blank_pos, stdout); -+ putchar ('\n'); -+ -+ offset_out = offset_out - last_blank_pos; -+ column = column - last_blank_column + ((is_cr_after_last_blank) -+ ? last_blank_increment : bs_following_last_blank_num); -+ memmove (line_out, line_out + last_blank_pos, offset_out); -+ CLEAR_FLAGS; -+ goto rescan; -+ } -+ -+ if (column + increment > width && column != 0) -+ { -+ fwrite (line_out, sizeof(char), offset_out, stdout); -+ START_NEW_LINE; -+ goto rescan; -+ } -+ -+ if (allocated_out - offset_out <= mblength) -+ { -+ line_out = xpalloc (line_out, &allocated_out, 1, -1, sizeof *line_out); -+ } -+ -+ memcpy (line_out + offset_out, bufpos, mblength); -+ offset_out += mblength; -+ column += increment; -+ -+ if (is_blank_seen && !convfail && wc == L'\r') -+ is_cr_after_last_blank = 1; -+ -+ if (is_bs_following_last_blank && !convfail && wc == L'\b') -+ ++bs_following_last_blank_num; -+ else -+ is_bs_following_last_blank = 0; -+ -+ if (break_spaces && !convfail && iswblank (wc)) -+ { -+ last_blank_pos = offset_out; -+ last_blank_column = column; -+ is_blank_seen = 1; -+ last_blank_increment = increment; -+ is_bs_following_last_blank = 1; -+ bs_following_last_blank_num = 0; -+ is_cr_after_last_blank = 0; -+ } -+ } -+ -+ *saved_errno = errno; -+ if (!ferror (istream)) -+ *saved_errno = 0; -+ -+ if (offset_out) -+ fwrite (line_out, sizeof (char), offset_out, stdout); -+ -+} -+#endif -+ -+/* Fold file FILENAME, or standard input if FILENAME is "-", -+ to stdout, with maximum line length WIDTH. -+ Return true if successful. */ -+ -+static bool -+fold_file (char const *filename, size_t width) -+{ -+ FILE *istream; -+ int saved_errno; -+ -+ if (STREQ (filename, "-")) -+ { -+ istream = stdin; -+ have_read_stdin = true; -+ } -+ else -+ istream = fopen (filename, "r"); -+ -+ if (istream == nullptr) -+ { -+ error (0, errno, "%s", filename); -+ return false; -+ } -+ -+ /* Define how ISTREAM is being folded. */ -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ fold_multibyte_text (istream, width, &saved_errno); -+ else -+#endif -+ fold_text (istream, width, &saved_errno); -+ - if (STREQ (filename, "-")) - clearerr (istream); - else if (fclose (istream) != 0 && !saved_errno) -@@ -249,7 +497,8 @@ main (int argc, char **argv) - - atexit (close_stdout); - -- break_spaces = count_bytes = have_read_stdin = false; -+ operating_mode = column_mode; -+ break_spaces = have_read_stdin = false; - - while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1) - { -@@ -258,7 +507,15 @@ main (int argc, char **argv) - switch (optc) - { - case 'b': /* Count bytes rather than columns. */ -- count_bytes = true; -+ if (operating_mode != column_mode) -+ FATAL_ERROR (_("only one way of folding may be specified")); -+ operating_mode = byte_mode; -+ break; -+ -+ case 'c': -+ if (operating_mode != column_mode) -+ FATAL_ERROR (_("only one way of folding may be specified")); -+ operating_mode = character_mode; - break; - - case 's': /* Break at word boundaries. */ diff --git a/src/local.mk b/src/local.mk -index fd9dc81..5133cc0 100644 +index a8ad6b4..b0e61ec 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -476,8 +476,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -490,8 +490,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -2235,9 +1415,9 @@ index fd9dc81..5133cc0 100644 +src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c lib/mbchar.c src_wc_SOURCES = src/wc.c - if USE_AVX2_WC_LINECOUNT + if USE_AVX512_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index e7081a0..19e0268 100644 +index 10b8c52..079c86c 100644 --- a/src/pr.c +++ b/src/pr.c @@ -312,6 +312,24 @@ @@ -2584,7 +1764,7 @@ index e7081a0..19e0268 100644 h_next = h + chars_per_column; } } -@@ -1748,9 +1872,9 @@ static void +@@ -1751,9 +1875,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -2596,7 +1776,7 @@ index e7081a0..19e0268 100644 padding_not_printed = ANYWHERE; } -@@ -2024,13 +2148,13 @@ store_char (char c) +@@ -2030,13 +2154,13 @@ store_char (char c) /* May be too generous. */ buff = xpalloc (buff, &buff_allocated, 1, -1, sizeof *buff); } @@ -2612,7 +1792,7 @@ index e7081a0..19e0268 100644 char *s; int num_width; -@@ -2047,22 +2171,24 @@ add_line_number (COLUMN *p) +@@ -2053,22 +2177,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. */ @@ -2641,7 +1821,7 @@ index e7081a0..19e0268 100644 output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2221,7 +2347,7 @@ print_white_space (void) +@@ -2227,7 +2353,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2650,7 +1830,7 @@ index e7081a0..19e0268 100644 h_old = h_new; } while (++h_old <= goal) -@@ -2241,6 +2367,7 @@ print_sep_string (void) +@@ -2247,6 +2373,7 @@ print_sep_string (void) { char const *s = col_sep_string; int l = col_sep_length; @@ -2658,7 +1838,7 @@ index e7081a0..19e0268 100644 if (separators_not_printed <= 0) { -@@ -2252,6 +2379,7 @@ print_sep_string (void) +@@ -2258,6 +2385,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2666,7 +1846,7 @@ index e7081a0..19e0268 100644 while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2265,12 +2393,15 @@ print_sep_string (void) +@@ -2271,12 +2399,15 @@ print_sep_string (void) } else { @@ -2683,7 +1863,7 @@ index e7081a0..19e0268 100644 /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2298,7 +2429,7 @@ print_clump (COLUMN *p, int n, char *clump) +@@ -2307,7 +2438,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -2692,7 +1872,7 @@ index e7081a0..19e0268 100644 { if (tabify_output) { -@@ -2322,6 +2453,74 @@ print_char (char c) +@@ -2331,6 +2462,74 @@ print_char (char c) putchar (c); } @@ -2767,7 +1947,7 @@ index e7081a0..19e0268 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2498,9 +2697,9 @@ read_line (COLUMN *p) +@@ -2507,9 +2706,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2779,7 +1959,7 @@ index e7081a0..19e0268 100644 padding_not_printed = ANYWHERE; } -@@ -2569,7 +2768,7 @@ print_stored (COLUMN *p) +@@ -2578,7 +2777,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -2788,7 +1968,7 @@ index e7081a0..19e0268 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2581,7 +2780,7 @@ print_stored (COLUMN *p) +@@ -2590,7 +2789,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -2797,7 +1977,7 @@ index e7081a0..19e0268 100644 pad_vertically = true; -@@ -2601,9 +2800,9 @@ print_stored (COLUMN *p) +@@ -2610,9 +2809,9 @@ print_stored (COLUMN *p) } } @@ -2809,7 +1989,7 @@ index e7081a0..19e0268 100644 padding_not_printed = ANYWHERE; } -@@ -2616,8 +2815,8 @@ print_stored (COLUMN *p) +@@ -2625,8 +2824,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2820,7 +2000,7 @@ index e7081a0..19e0268 100644 } return true; -@@ -2636,7 +2835,7 @@ print_stored (COLUMN *p) +@@ -2645,7 +2844,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2829,7 +2009,7 @@ index e7081a0..19e0268 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2646,10 +2845,10 @@ char_to_clump (char c) +@@ -2655,10 +2854,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2842,7 +2022,7 @@ index e7081a0..19e0268 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2730,6 +2929,164 @@ char_to_clump (char c) +@@ -2739,6 +2938,164 @@ char_to_clump (char c) return chars; } @@ -3008,13 +2188,14 @@ index e7081a0..19e0268 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 0928fd5..8c43fd4 100644 +index 05d00cc..eb51f20 100644 --- a/src/sort.c +++ b/src/sort.c -@@ -29,6 +29,14 @@ - #include +@@ -30,6 +30,15 @@ #include #include + #include ++ +#if HAVE_WCHAR_H +# include +#endif @@ -3026,7 +2207,7 @@ index 0928fd5..8c43fd4 100644 #include "system.h" #include "argmatch.h" #include "assure.h" -@@ -158,14 +166,39 @@ static int thousands_sep; +@@ -160,14 +169,39 @@ static int thousands_sep; /* We currently ignore multi-byte grouping chars. */ static bool thousands_sep_ignored; @@ -3067,7 +2248,7 @@ index 0928fd5..8c43fd4 100644 /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -342,13 +375,11 @@ static bool stable; +@@ -344,13 +378,11 @@ static bool stable; /* An int value outside char range. */ enum { NON_CHAR = CHAR_MAX + 1 }; @@ -3084,9 +2265,9 @@ index 0928fd5..8c43fd4 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -807,6 +838,46 @@ reap_all (void) - reap (-1); - } +@@ -386,6 +418,46 @@ struct tempnode + static struct tempnode *volatile temphead; + static struct tempnode *volatile *temptail = &temphead; +/* Function pointers. */ +static void @@ -3131,7 +2312,7 @@ index 0928fd5..8c43fd4 100644 /* Clean up any remaining temporary files. */ static void -@@ -1274,7 +1345,7 @@ zaptemp (char const *name) +@@ -1343,7 +1415,7 @@ zaptemp (char const *name) free (node); } @@ -3140,7 +2321,7 @@ index 0928fd5..8c43fd4 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1289,7 +1360,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1358,7 +1430,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -3149,7 +2330,7 @@ index 0928fd5..8c43fd4 100644 { size_t i; -@@ -1301,7 +1372,7 @@ inittables (void) +@@ -1370,7 +1442,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -3158,7 +2339,7 @@ index 0928fd5..8c43fd4 100644 /* 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 const *s) +@@ -1450,6 +1522,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -3243,7 +2424,7 @@ index 0928fd5..8c43fd4 100644 /* 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) +@@ -1676,7 +1826,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -3252,7 +2433,7 @@ index 0928fd5..8c43fd4 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1621,10 +1770,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1685,10 +1835,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -3265,7 +2446,7 @@ index 0928fd5..8c43fd4 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1650,12 +1799,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1718,12 +1868,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3338,7 +2519,7 @@ index 0928fd5..8c43fd4 100644 { 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, struct keyfield const *key) +@@ -1738,10 +1947,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. */ @@ -3351,7 +2532,7 @@ index 0928fd5..8c43fd4 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1719,10 +1927,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1787,10 +1996,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3364,7 +2545,7 @@ index 0928fd5..8c43fd4 100644 if (newlim) lim = newlim; } -@@ -1753,6 +1961,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1825,6 +2034,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3495,7 +2676,7 @@ index 0928fd5..8c43fd4 100644 /* 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, char const *file) +@@ -1911,8 +2244,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3520,7 +2701,7 @@ index 0928fd5..8c43fd4 100644 line->keybeg = line_start; } } -@@ -1978,12 +2324,10 @@ find_unit_order (char const *number) +@@ -2050,12 +2397,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3536,7 +2717,7 @@ index 0928fd5..8c43fd4 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1995,7 +2339,7 @@ human_numcompare (char const *a, char const *b) +@@ -2067,7 +2412,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -3545,7 +2726,7 @@ index 0928fd5..8c43fd4 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2005,6 +2349,25 @@ numcompare (char const *a, char const *b) +@@ -2077,6 +2422,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3571,7 +2752,7 @@ index 0928fd5..8c43fd4 100644 static int nan_compare (long double a, long double b) { -@@ -2046,7 +2409,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2118,7 +2482,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3580,7 +2761,7 @@ index 0928fd5..8c43fd4 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2385,15 +2748,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2457,15 +2821,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3598,7 +2779,7 @@ index 0928fd5..8c43fd4 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2539,7 +2901,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2611,7 +2974,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 */ @@ -3607,7 +2788,7 @@ index 0928fd5..8c43fd4 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2587,9 +2949,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2659,9 +3022,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3620,7 +2801,7 @@ index 0928fd5..8c43fd4 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2600,9 +2962,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2672,9 +3035,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3633,7 +2814,7 @@ index 0928fd5..8c43fd4 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2610,19 +2972,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2682,19 +3045,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3657,17 +2838,8 @@ index 0928fd5..8c43fd4 100644 } } -@@ -2633,7 +2995,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) - { - error (0, 0, - _("%snumbers use %s as a decimal point in this locale"), -- tab == decimal_point ? "" : _("note "), -+ (tab_length && tab[0] == decimal_point) ? "" : _("note "), - quote (((char []) {decimal_point, 0}))); - - } -@@ -2675,11 +3037,87 @@ diff_reversed (int diff, bool reversed) - return reversed ? (diff < 0) - (diff > 0) : diff; +@@ -2746,11 +3109,87 @@ diff_reversed (int diff, bool reversed) + return reversed ? _GL_CMP (0, diff) : diff; } +#if HAVE_MBRTOWC @@ -3755,7 +2927,7 @@ index 0928fd5..8c43fd4 100644 { struct keyfield *key = keylist; -@@ -2760,7 +3198,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2831,7 +3270,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3764,7 +2936,7 @@ index 0928fd5..8c43fd4 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2870,6 +3308,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2941,6 +3380,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -3976,7 +3148,7 @@ index 0928fd5..8c43fd4 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2897,7 +3540,7 @@ compare (struct line const *a, struct line const *b) +@@ -2968,7 +3612,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3985,7 +3157,7 @@ index 0928fd5..8c43fd4 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4285,6 +4928,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4340,6 +4984,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -3993,7 +3165,7 @@ index 0928fd5..8c43fd4 100644 break; case 'g': key->general_numeric = true; -@@ -4364,7 +5008,7 @@ main (int argc, char **argv) +@@ -4419,7 +5064,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4002,7 +3174,7 @@ index 0928fd5..8c43fd4 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4387,6 +5031,29 @@ main (int argc, char **argv) +@@ -4442,6 +5087,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4032,7 +3204,7 @@ index 0928fd5..8c43fd4 100644 have_read_stdin = false; inittables (); -@@ -4657,13 +5324,34 @@ main (int argc, char **argv) +@@ -4717,13 +5385,34 @@ main (int argc, char **argv) case 't': { @@ -4065,13 +3237,13 @@ index 0928fd5..8c43fd4 100644 +#endif + if (newtab_length == 1 && optarg[1]) { - if (STREQ (optarg, "\\0")) + if (streq (optarg, "\\0")) - newtab = '\0'; + newtab[0] = '\0'; else { /* Provoke with 'sort -txx'. Complain about -@@ -4674,9 +5362,11 @@ main (int argc, char **argv) +@@ -4734,9 +5423,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4528,11 +3700,11 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 12e30b4..1529db6 100644 +index 53fc53e..0148422 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -390,6 +390,8 @@ all_tests = \ - tests/sort/sort-discrim.sh \ +@@ -412,6 +412,8 @@ all_tests = \ + tests/sort/sort-field-limit.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ + tests/misc/sort-mb-tests.sh \ @@ -4540,7 +3712,7 @@ index 12e30b4..1529db6 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -593,6 +595,7 @@ all_tests = \ +@@ -618,6 +620,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4548,7 +3720,7 @@ index 12e30b4..1529db6 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -749,6 +752,7 @@ all_tests = \ +@@ -774,6 +777,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4623,79 +3795,6 @@ index 4b07210..68b9ea1 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index 0981ec9..ba889c8 100755 ---- a/tests/misc/fold.pl -+++ b/tests/misc/fold.pl -@@ -20,9 +20,17 @@ use strict; - - (my $program_name = $0) =~ s|.*/||; - -+my $prog = 'fold'; -+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 $prog = 'fold'; -+ -+# uncommented to enable multibyte paths -+my $mb_locale = $ENV{LOCALE_FR_UTF8}; -+! defined $mb_locale || $mb_locale eq 'none' -+ and $mb_locale = 'C'; - - my @Tests = - ( -@@ -44,9 +52,48 @@ my @Tests = - {OUT=>"123456\n7890\nabcdef\nghij\n123456\n7890"}], - ); - -+# 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 fold 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; -+ } -+ 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}; - --my $prog = 'fold'; - my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); - exit $fail; diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh new file mode 100644 index 0000000..11836ba @@ -4748,7 +3847,7 @@ index 0000000..11836ba + +Exit $fail diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index 27d9c17..4976335 100755 +index bb7469c..c1dec95 100755 --- a/tests/misc/unexpand.pl +++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); @@ -4766,7 +3865,7 @@ index 27d9c17..4976335 100755 my @Tests = ( ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], -@@ -128,6 +136,37 @@ my @Tests = +@@ -132,6 +140,37 @@ my @Tests = ['ts2', '-t5,8', {IN=>"x\t \t y\n"}, {OUT=>"x\t\t y\n"}], ); @@ -4934,7 +4033,7 @@ index a3204d3..40942a5 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort.pl b/tests/sort/sort.pl -index 2ee92c4..96c7965 100755 +index 5fa9d52..a66952a 100755 --- a/tests/sort/sort.pl +++ b/tests/sort/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; @@ -4954,7 +4053,7 @@ index 2ee92c4..96c7965 100755 # Since each test is run with a file name and with redirected stdin, # the name in the diagnostic is either the file name or "-". # Normalize each diagnostic to use '-'. -@@ -423,6 +428,38 @@ foreach my $t (@Tests) +@@ -428,6 +433,38 @@ foreach my $t (@Tests) } } @@ -4993,7 +4092,7 @@ index 2ee92c4..96c7965 100755 @Tests = triple_test \@Tests; # Remember that triple_test creates from each test with exactly one "IN" -@@ -432,6 +469,7 @@ foreach my $t (@Tests) +@@ -437,6 +474,7 @@ foreach my $t (@Tests) # 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; @@ -5180,5 +4279,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.48.1 +2.52.0 diff --git a/coreutils-python3.patch b/coreutils-python3.patch index e6ff471..447fdbc 100644 --- a/coreutils-python3.patch +++ b/coreutils-python3.patch @@ -1,4 +1,4 @@ -From f1a6e8d840a28eb2ab7a488e0d06450b7192c76d Mon Sep 17 00:00:00 2001 +From 8927d505ecb5334f09c48ef98ef1f464f581d0f7 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Tue, 2 Apr 2024 14:11:26 +0100 Subject: [PATCH] coreutils-python3.patch @@ -10,10 +10,10 @@ Subject: [PATCH] coreutils-python3.patch 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/init.cfg b/init.cfg -index 612d287..9a6fa2d 100644 +index ac05f7b..26d9516 100644 --- a/init.cfg +++ b/init.cfg -@@ -597,10 +597,10 @@ seek_data_capable_() +@@ -601,10 +601,10 @@ seek_data_capable_() # Skip the current test if "." lacks d_type support. require_dirent_d_type_() { @@ -37,7 +37,7 @@ index 1a2f76f..42d3924 100644 # Intended to exit 0 only on Linux/GNU systems. import os diff --git a/tests/du/move-dir-while-traversing.sh b/tests/du/move-dir-while-traversing.sh -index 1d0a359..bd03542 100755 +index adf482b..cf9214a 100755 --- a/tests/du/move-dir-while-traversing.sh +++ b/tests/du/move-dir-while-traversing.sh @@ -21,8 +21,8 @@ print_ver_ du @@ -61,5 +61,5 @@ index 1d0a359..bd03542 100755 import os,sys -- -2.48.1 +2.51.0 diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch deleted file mode 100644 index 91bc5b5..0000000 --- a/coreutils-selinux.patch +++ /dev/null @@ -1,87 +0,0 @@ -From fc96cab095d704e8bf9934812dd8d6f87fbf4be4 Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Wed, 30 Aug 2023 17:19:58 +0200 -Subject: [PATCH] coreutils-selinux.patch - ---- - src/cp.c | 19 ++++++++++++++++++- - src/install.c | 12 +++++++++++- - 2 files changed, 29 insertions(+), 2 deletions(-) - -diff --git a/src/cp.c b/src/cp.c -index a0ec067..1169c6a 100644 ---- a/src/cp.c -+++ b/src/cp.c -@@ -996,7 +996,7 @@ main (int argc, char **argv) - selinux_enabled = (0 < is_selinux_enabled ()); - cp_option_init (&x); - -- while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:TZ", -+ while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ", - long_opts, nullptr)) - != -1) - { -@@ -1048,6 +1048,23 @@ main (int argc, char **argv) - copy_contents = true; - break; - -+ case 'c': -+ fprintf (stderr, "%s: warning: option '-c' is deprecated," -+ " please use '--preserve=context' instead\n", argv[0]); -+ if (x.set_security_context) -+ { -+ fprintf (stderr, -+ "%s: cannot force target context and preserve it\n", -+ argv[0]); -+ exit (1); -+ } -+ else if (selinux_enabled) -+ { -+ x.preserve_security_context = true; -+ x.require_preserve_context = true; -+ } -+ break; -+ - case 'd': - x.preserve_links = true; - x.dereference = DEREF_NEVER; -diff --git a/src/install.c b/src/install.c -index b3b26ab..2d2f072 100644 ---- a/src/install.c -+++ b/src/install.c -@@ -807,7 +807,7 @@ main (int argc, char **argv) - dir_arg = false; - umask (0); - -- while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z", long_options, -+ while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPt:TvS:Z", long_options, - nullptr)) - != -1) - { -@@ -872,6 +872,9 @@ main (int argc, char **argv) - no_target_directory = true; - break; - -+ case 'P': -+ fprintf (stderr, "%s: warning: option '-P' is deprecated," -+ " please use '--preserve-context' instead\n", argv[0]); - case PRESERVE_CONTEXT_OPTION: - if (! selinux_enabled) - { -@@ -879,6 +882,13 @@ main (int argc, char **argv) - "this kernel is not SELinux-enabled")); - break; - } -+ if (x.set_security_context) -+ { -+ fprintf (stderr, -+ "%s: cannot force target context and preserve it\n", -+ argv[0]); -+ exit (1); -+ } - x.preserve_security_context = true; - use_default_selinux_context = false; - break; --- -2.48.1 - diff --git a/coreutils.spec b/coreutils.spec index 23eb924..6712263 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,6 +1,6 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.6 +Version: 9.9 Release: 2%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later @@ -32,20 +32,17 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch -# ls: fix crash with --context -# https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=915004f403cb25fadb207ddfdbe6a2f43bd44fac -Patch105: coreutils-9.6-ls-selinux-crash.patch +# gnulib C23 support +# https://github.com/coreutils/gnulib/commit/df17f4f37ed3ca373d23ad42eae51122bdb96626 +Patch105: coreutils-9.9-gnulib-c23.patch -# who: fix -m with guessed tty names (rhbz#2343998) -# https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=24450e5eecf012bc1ea8cab8d677a45fa42c1778 -Patch106: coreutils-9.6-who-m-systemd.patch +# fix cut test failure on aarch64 rawhide (rhbz#2424302) +# https://github.com/coreutils/coreutils/commit/95044cb5eaea83d02f768feb5ab79fcf5e6ad782 +Patch106: coreutils-9.9-fix-cut-test-aarch64.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch -# downstream SELinux options deprecated since 2009 -Patch950: coreutils-selinux.patch - Conflicts: filesystem < 3 # To avoid clobbering installs @@ -128,6 +125,9 @@ packaged as a single multicall binary. # https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7 Obsoletes: %{name} < 8.24-100 +# Gnulib translations are maintained seprately since coreutils 9.6 (#2393892) +Requires: gnulib-l10n + # info doc refers to "Specifying the Time Zone" from glibc-doc (#959597) Suggests: glibc-doc @@ -164,7 +164,7 @@ find tests -name '*.sh' -perm 0644 -print -exec chmod 0755 '{}' '+' # FIXME: Force a newer gettext version to workaround `autoreconf -i` errors # with coreutils 9.6 and bundled gettext 0.19.2 from gettext-common-devel. -sed -i 's/0.19.2/0.22.5/' bootstrap.conf configure.ac +sed -i "s/0.19.2/$(rpm -q --queryformat '%%{VERSION}\n' gettext-devel)/" bootstrap.conf configure.ac autoreconf -fiv @@ -286,6 +286,37 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Jan 13 2026 Lukáš Zaoral - 9.9-2 +- fix cut test failure on aarch64 rawhide (rhbz#2424302) + +* Wed Nov 26 2025 Lukáš Zaoral - 9.9-1 +- rebase to latest upstream release (rhbz#2413803) + +* Mon Sep 29 2025 Lukáš Zaoral - 9.8-3 +- require gnulib-l10n for translations of gnulib messages (rhbz#2393892) + +* Thu Sep 25 2025 Lukáš Zaoral - 9.8-2 +- tail: fix tailing larger number of lines in regular files (rhbz#2398008) + +* Wed Sep 24 2025 Lukáš Zaoral - 9.8-1 +- rebase to latest upstream release (rhbz#2397467) +- remove downstream patch for selinux options deprecated since 2009 + +* Wed Jul 23 2025 Fedora Release Engineering - 9.7-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + +* Mon Jun 30 2025 Lukáš Zaoral - 9.7-4 +- stty: add support for arbitrary baud rates (rhbz#2375439) + +* Wed May 28 2025 Lukáš Zaoral - 9.7-3 +- sort: fix buffer under-read (CVE-2025-5278) + +* Mon May 19 2025 Lukáš Zaoral - 9.7-2 +- cp/mv: do not fail when copying of trivial NFSv4 ACLs fails (rhbz#2363149) + +* Wed Apr 09 2025 Lukáš Zaoral - 9.7-1 +- rebase to latest upstream release (rhbz#2358624) + * Tue Feb 25 2025 Lukáš Zaoral - 9.6-2 - fix 'who -m' with guessed tty names (rhbz#2343998) diff --git a/sources b/sources index 498bfd9..0952ab1 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.6.tar.xz) = 398391d7f9d77e6117b750abb8711eebdd9cd2549e7846cab26884fb2dd522b6bcfb8bf7fef35a12683e213ada7f89b817bf615628628d42aee3fa3102647b28 -SHA512 (coreutils-9.6.tar.xz.sig) = a8e578b5e1d053b49e3e2c5dc94431d17c6a14662f459b2174cea23865ccca32e5ae5c13fedb0a8345d25269a9b98cb7f463a897c9663f9f9bcaf61e5c781378 +SHA512 (coreutils-9.9.tar.xz.sig) = 0a3dfdfa6b4234e2e1d42142269f959bdf3cf8f6605a50270a27eff84dd22588f182121f7dd3eeb04be45f5109d02690215065b3d3b43882874d0e165a1435d0 +SHA512 (coreutils-9.9.tar.xz) = e7b0e59f7732d2c098ea4934014f470248bd5c4764210e9200a698010a8e3b95bbb26e543f0cd73ed5a4b8e1f8cda932c73f39954d68175e4deaa47526610c65