From 681ee7d49f85c89c6a3e49634e22c86d0822b3343a24d54363300893bad9d372 Mon Sep 17 00:00:00 2001 From: Bernhard Voelker Date: Fri, 2 Dec 2016 23:04:18 +0000 Subject: [PATCH] Accepting request 443228 from home:berny:branches:Base:System - Update to 8.26 (for details see included NEWS file) - coreutils.spec (%description): Add b2sum, a new utility. (BuildRequires): Add timezone to enable new 'date-debug.sh' test. - coreutils-i18n.patch: Sync I18N patch from Fedora, as the diff for the old i18n implementation of expand/unexpand has become unmaintainable: git://pkgs.fedoraproject.org/coreutils.git - Remove now-upstream patches: * coreutils-df-hash-in-filter.patch * coreutils-diagnose-fts-readdir-failure.patch * coreutils-m5sum-sha-sum-fix-ignore-missing-with-00-checksums.patch * coreutils-maint-fix-dependency-of-man-arch.1.patch - Refresh/merge all other patches: * coreutils-invalid-ids.patch * coreutils-ocfs2_reflinks.patch * coreutils-remove_hostname_documentation.patch * coreutils-remove_kill_documentation.patch * coreutils-skip-gnulib-test-tls.patch * coreutils-sysinfo.patch * coreutils-tests-shorten-extreme-factor-tests.patch OBS-URL: https://build.opensuse.org/request/show/443228 OBS-URL: https://build.opensuse.org/package/show/Base:System/coreutils?expand=0&rev=278 --- coreutils-8.25.tar.xz | 3 - coreutils-8.25.tar.xz.sig | 17 - coreutils-8.26.tar.xz | 3 + coreutils-8.26.tar.xz.sig | 17 + coreutils-df-hash-in-filter.patch | 304 --- coreutils-diagnose-fts-readdir-failure.patch | 260 --- coreutils-i18n.patch | 2020 +++++++++++------ coreutils-invalid-ids.patch | 6 +- ...fix-ignore-missing-with-00-checksums.patch | 157 -- ...s-maint-fix-dependency-of-man-arch.1.patch | 70 - coreutils-ocfs2_reflinks.patch | 6 +- coreutils-remove_hostname_documentation.patch | 12 +- coreutils-remove_kill_documentation.patch | 8 +- coreutils-skip-gnulib-test-tls.patch | 2 +- coreutils-sysinfo.patch | 4 +- ...s-tests-shorten-extreme-factor-tests.patch | 2 +- coreutils-testsuite.changes | 25 + coreutils-testsuite.spec | 31 +- coreutils.changes | 25 + coreutils.spec | 31 +- 20 files changed, 1488 insertions(+), 1515 deletions(-) delete mode 100644 coreutils-8.25.tar.xz delete mode 100644 coreutils-8.25.tar.xz.sig create mode 100644 coreutils-8.26.tar.xz create mode 100644 coreutils-8.26.tar.xz.sig delete mode 100644 coreutils-df-hash-in-filter.patch delete mode 100644 coreutils-diagnose-fts-readdir-failure.patch delete mode 100644 coreutils-m5sum-sha-sum-fix-ignore-missing-with-00-checksums.patch delete mode 100644 coreutils-maint-fix-dependency-of-man-arch.1.patch diff --git a/coreutils-8.25.tar.xz b/coreutils-8.25.tar.xz deleted file mode 100644 index 8baf74c..0000000 --- a/coreutils-8.25.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:31e67c057a5b32a582f26408c789e11c2e8d676593324849dcf5779296cdce87 -size 5725008 diff --git a/coreutils-8.25.tar.xz.sig b/coreutils-8.25.tar.xz.sig deleted file mode 100644 index fa5ec8e..0000000 --- a/coreutils-8.25.tar.xz.sig +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1 - -iQIcBAABAgAGBQJWn2zaAAoJEN9v2XEwYDfZvPsP/0o/JM9G7sLXFBX93XO7uYWH -8q2I5hIWcQZiGc/1PZtHM+2GLkh0heiLcKcsY1Ewk/EYlRuGS5MO5M4dh5YHAeaE -LFNfJcAIvClhwgniVXvElTaEfyBDhslh9WVKJCgZ748s6AgDv0SD5dI0X7bpj4Pz -j8wpWaJdrf8kRrjNqhTJtrmO92fUbkULG9+kmp9HZZFYzPUcLyF0ZdA2j3ZxWwP0 -OK9zfuY08mVdPVFlPjep1kvNX+See86xDd3HiOkxAJ3oDvHCKPzn8PzREejYAMl+ -NfdHovMw85MzaQlYsqduyr9iTBQSOyO6KJ85VM3GEexjxyGqqgwgSXLw9SZgaF9L -pbzAlcvGsFxsOEJF27dllL03SSqMfvDOXs/vRKALzi8jxW/gyGRG3Ft8Dd0pW70w -1vqRwFf/XQuChTUTYsAlshcKu8MPrQbJoU6UPbZOj0odFaWxNQ/E4msoN/NT9Xbi -5buuf43mvUmMXXT+p+fwXiaATn8wuOd4G/Mzc2Q/4zpyUi4MvnmUZ0FD0F39r1WS -jZI2QS8ktpOqV11WArShZLo6X0T9tHHt40/3PLeXJE+RuddU2VR+Yzx3jqUTK8TJ -7S9/DEu+l7dgioZdaXFwS0FcenH4PvRT+V0PwmPMWwrTKDa0G/zrtva488dCJQM7 -SUlh/zsEIB3hX2erMwTl -=W+ce ------END PGP SIGNATURE----- diff --git a/coreutils-8.26.tar.xz b/coreutils-8.26.tar.xz new file mode 100644 index 0000000..62d2020 --- /dev/null +++ b/coreutils-8.26.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:155e94d748f8e2bc327c66e0cbebdb8d6ab265d2f37c3c928f7bf6c3beba9a8e +size 5810244 diff --git a/coreutils-8.26.tar.xz.sig b/coreutils-8.26.tar.xz.sig new file mode 100644 index 0000000..d75c08d --- /dev/null +++ b/coreutils-8.26.tar.xz.sig @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1 + +iQIcBAABAgAGBQJYPyRpAAoJEN9v2XEwYDfZ0I4P/3oaPYXMPEOKuDDpEcLumn26 +gYIMQc1jIMbBNQe120gQmNPkRr5dTKt5Bap9qYkCj0pI/6VxVIWDo0xrOLYZi7AN +Xgr0kX2qLDFEH+EHkC1BpsAdpsgwfvLmVWPHS62CNKgVDgGiP1cRJZe8oVmlBCiR +3ES7pUsBfDn3hbdKNTTmMDtro1rQMOxfHkVCZLAva+JjdzpE+KTvzZzKkVuZZfJ/ +Mi/ZySrXZXFvPBS7GXgop4x8EodyzQMeKO+nvpIUEBY1yLQgCvni5/CBI8w/EViD +DSjj0zWsCQkEjx6HCohi8sBHUYZ+M3lB4rkFk7aevdioPZUGfLkW31LT/cUJC/VV +MIQKWzQtZO/WCJuyEbWP2m25c4MtnnhTm5yoi29yT/CoTRlUWkIQpXm4oD1cJXHy +PpHveu8qM0qRaAtVdXE3pmapIMYUV4g7vxSuCjZRrgiDLhp/K7Lzt5xBhl++kPU2 +U9uc202eah4Towo0pbHsuEJT0vk0GGLq8/17dCa/ss8wV+86ZLxl0kZYy4CNEnIW +vsCN6CJ5AoAEVrMN1F7ZJYnH4hoJedvIczThnAkNTqYYE3wnN9stOe28Oy/a0/tg +bt5/Mn0JbmQei890uU8zcEdUjidHqGV4hKk1E2UC4UCyHG/VcHv9gfr8OaD/xPDr +SoauDCHpBU7J7FT/DX+k +=vkKy +-----END PGP SIGNATURE----- diff --git a/coreutils-df-hash-in-filter.patch b/coreutils-df-hash-in-filter.patch deleted file mode 100644 index 8f72887..0000000 --- a/coreutils-df-hash-in-filter.patch +++ /dev/null @@ -1,304 +0,0 @@ -# Upstream patch to improve df performance with many mount points; -# to be removed with coreutils > v8.25. - -Upstream patch: - http://git.sv.gnu.org/cgit/coreutils.git/commit/?id=1c17f61ef9 - -Downstream addition: -* THANKS: Propagate the addition of Josef Cejka from THANKS.in -to this file (usually done via "make dist"). - -______________________________________________________________________ -From 1c17f61ef993a5ee5fb0d3bc47b7b25782ae386c Mon Sep 17 00:00:00 2001 -From: Philipp Thomas -Date: Sun, 31 Jul 2016 21:24:18 +0200 -Subject: [PATCH] df: improve performance with many mount points - -Use hash table for seaching in filter_mount_list() and get_dev() - -This improves performance for 20K mount entries from: - real 0m1.731s - user 0m0.532s - sys 0m1.188s -to: - real 0m1.066s - user 0m0.028s - sys 0m1.032s - -* src/df.c (devlist_table): Define hash table. -(devlist_hash): Add hash function. -(devlist_compare): Add hash comparison function. -(devlist_for_dev): Add lookup function. -(devlist_free): Add cleanup function. -(filter_mount_list): Use the above hash table. -While at it, rename the variable 'devlist' to 'seen_dev' for -better readability. -(me_for_dev): Use the above lookup function. -NEWS: Mention the improvement. -THANKS.in: Remove the committer; add original submitter Josef Cejka. ---- - NEWS | 3 + - THANKS | 1 - THANKS.in | 2 - - src/df.c | 110 +++++++++++++++++++++++++++++++++++++++++++------------------- - 4 files changed, 82 insertions(+), 34 deletions(-) - -Index: NEWS -=================================================================== ---- NEWS.orig -+++ NEWS -@@ -8,6 +8,9 @@ GNU coreutils NEWS - introduced in coreutils-8.0. du, chmod, chgrp and chown started using - fts in 6.0. chcon was added in coreutils-6.9.91 with fts support. ] - -+ df now filters the system mount list more efficiently, with 20000 -+ mount entries now being processed in about 1.1s compared to 1.7s. -+ - - * Noteworthy changes in release 8.25 (2016-01-20) [stable] - -Index: THANKS.in -=================================================================== ---- THANKS.in.orig -+++ THANKS.in -@@ -322,6 +322,7 @@ Jon Peatfield J.S. - Joost van Baal joostvb@xs4all.nl - Jordi Pujol jordipujolp@gmail.com - Jorge Stolfi stolfi@ic.unicamp.br -+Josef Cejka jcejka@suse.com - Joseph D. Wagner joe@josephdwagner.info - Joseph S. Myers jsm28@cam.ac.uk - Josh Triplett josh@freedesktop.org -@@ -514,7 +515,6 @@ Petter Reinholdtsen pere - Phelippe Neveu pneveu@pcigeomatics.com - Phil Richards phil.richards@vf.vodafone.co.uk - Philipp Gortan gortan@gmail.com --Philipp Thomas pth@suse.de - Philippe De Muyter phdm@macqel.be - Philippe Schnoebelen Philippe.Schnoebelen@imag.fr - Phillip Jones mouse@datastacks.com -Index: src/df.c -=================================================================== ---- src/df.c.orig -+++ src/df.c -@@ -34,6 +34,7 @@ - #include "mountlist.h" - #include "quote.h" - #include "find-mount-point.h" -+#include "hash.h" - - /* The official name of this program (e.g., no 'g' prefix). */ - #define PROGRAM_NAME "df" -@@ -43,14 +44,16 @@ - proper_name ("David MacKenzie"), \ - proper_name ("Paul Eggert") - --/* Filled with device numbers of examined file systems to avoid -- duplicates in output. */ --static struct devlist -+struct devlist - { - dev_t dev_num; - struct mount_entry *me; - struct devlist *next; --} *device_list; -+}; -+ -+/* Filled with device numbers of examined file systems to avoid -+ duplicates in output. */ -+static Hash_table *devlist_table; - - /* If true, show even file systems with zero size or - uninteresting types. */ -@@ -603,23 +606,67 @@ excluded_fstype (const char *fstype) - return false; - } - -+static size_t -+devlist_hash (void const *x, size_t table_size) -+{ -+ struct devlist const *p = x; -+ return (uintmax_t) p->dev_num % table_size; -+} -+ -+static bool -+devlist_compare (void const *x, void const *y) -+{ -+ struct devlist const *a = x; -+ struct devlist const *b = y; -+ return a->dev_num == b->dev_num; -+} -+ -+static struct devlist * -+devlist_for_dev (dev_t dev) -+{ -+ if (devlist_table == NULL) -+ return NULL; -+ struct devlist dev_entry; -+ dev_entry.dev_num = dev; -+ return hash_lookup (devlist_table, &dev_entry); -+} -+ -+static void -+devlist_free (void *p) -+{ -+ free (p); -+} -+ - /* Filter mount list by skipping duplicate entries. - In the case of duplicates - based on the device number - the mount entry - with a '/' in its me_devname (i.e., not pseudo name like tmpfs) wins. - If both have a real devname (e.g. bind mounts), then that with the shorter - me_mountdir wins. With DEVICES_ONLY == true (set with df -a), only update -- the global device_list, rather than filtering the global mount_list. */ -+ the global devlist_table, rather than filtering the global mount_list. */ - - static void - filter_mount_list (bool devices_only) - { - struct mount_entry *me; - -+ /* Temporary list to keep entries ordered. */ -+ struct devlist *device_list = NULL; -+ int mount_list_size = 0; -+ -+ for (me = mount_list; me; me = me->me_next) -+ mount_list_size++; -+ -+ devlist_table = hash_initialize (mount_list_size, NULL, -+ devlist_hash, -+ devlist_compare, -+ devlist_free); -+ if (devlist_table == NULL) -+ xalloc_die (); -+ - /* Sort all 'wanted' entries into the list device_list. */ - for (me = mount_list; me;) - { - struct stat buf; -- struct devlist *devlist; - struct mount_entry *discard_me = NULL; - - /* Avoid stating remote file systems as that may hang. -@@ -635,21 +682,20 @@ filter_mount_list (bool devices_only) - else - { - /* If we've already seen this device... */ -- for (devlist = device_list; devlist; devlist = devlist->next) -- if (devlist->dev_num == buf.st_dev) -- break; -+ struct devlist *seen_dev = devlist_for_dev (buf.st_dev); - -- if (devlist) -+ if (seen_dev) - { -- bool target_nearer_root = strlen (devlist->me->me_mountdir) -+ bool target_nearer_root = strlen (seen_dev->me->me_mountdir) - > strlen (me->me_mountdir); - /* With bind mounts, prefer items nearer the root of the source */ -- bool source_below_root = devlist->me->me_mntroot != NULL -+ bool source_below_root = seen_dev->me->me_mntroot != NULL - && me->me_mntroot != NULL -- && (strlen (devlist->me->me_mntroot) -+ && (strlen (seen_dev->me->me_mntroot) - < strlen (me->me_mntroot)); -- if (! print_grand_total && me->me_remote && devlist->me->me_remote -- && ! STREQ (devlist->me->me_devname, me->me_devname)) -+ if (! print_grand_total -+ && me->me_remote && seen_dev->me->me_remote -+ && ! STREQ (seen_dev->me->me_devname, me->me_devname)) - { - /* Don't discard remote entries with different locations, - as these are more likely to be explicitly mounted. -@@ -658,21 +704,21 @@ filter_mount_list (bool devices_only) - } - else if ((strchr (me->me_devname, '/') - /* let "real" devices with '/' in the name win. */ -- && ! strchr (devlist->me->me_devname, '/')) -+ && ! strchr (seen_dev->me->me_devname, '/')) - /* let points towards the root of the device win. */ - || (target_nearer_root && ! source_below_root) - /* let an entry overmounted on a new device win... */ -- || (! STREQ (devlist->me->me_devname, me->me_devname) -+ || (! STREQ (seen_dev->me->me_devname, me->me_devname) - /* ... but only when matching an existing mnt point, - to avoid problematic replacement when given - inaccurate mount lists, seen with some chroot - environments for example. */ - && STREQ (me->me_mountdir, -- devlist->me->me_mountdir))) -+ seen_dev->me->me_mountdir))) - { - /* Discard mount entry for existing device. */ -- discard_me = devlist->me; -- devlist->me = me; -+ discard_me = seen_dev->me; -+ seen_dev->me = me; - } - else - { -@@ -691,12 +737,14 @@ filter_mount_list (bool devices_only) - } - else - { -- /* Add the device number to the global list devlist. */ -- devlist = xmalloc (sizeof *devlist); -+ /* Add the device number to the device_table. */ -+ struct devlist *devlist = xmalloc (sizeof *devlist); - devlist->me = me; - devlist->dev_num = buf.st_dev; - devlist->next = device_list; - device_list = devlist; -+ if (hash_insert (devlist_table, devlist) == NULL) -+ xalloc_die (); - - me = me->me_next; - } -@@ -711,28 +759,24 @@ filter_mount_list (bool devices_only) - me = device_list->me; - me->me_next = mount_list; - mount_list = me; -- /* Free devlist entry and advance. */ -- struct devlist *devlist = device_list->next; -- free (device_list); -- device_list = devlist; -+ device_list = device_list->next; - } -+ -+ hash_free (devlist_table); -+ devlist_table = NULL; - } - } - -+ - /* Search a mount entry list for device id DEV. - Return the corresponding mount entry if found or NULL if not. */ - - static struct mount_entry const * _GL_ATTRIBUTE_PURE - me_for_dev (dev_t dev) - { -- struct devlist *dl = device_list; -- -- while (dl) -- { -- if (dl->dev_num == dev) -+ struct devlist *dl = devlist_for_dev (dev); -+ if (dl) - return dl->me; -- dl = dl->next; -- } - - return NULL; - } -Index: THANKS -=================================================================== ---- THANKS.orig -+++ THANKS -@@ -406,6 +406,7 @@ Jon Ringuette jonr - Joost van Baal joostvb@xs4all.nl - Jordi Pujol jordipujolp@gmail.com - Jorge Stolfi stolfi@ic.unicamp.br -+Josef Cejka jcejka@suse.com - Joseph D. Wagner joe@josephdwagner.info - Joseph S. Myers jsm28@cam.ac.uk - Josh Triplett josh@freedesktop.org diff --git a/coreutils-diagnose-fts-readdir-failure.patch b/coreutils-diagnose-fts-readdir-failure.patch deleted file mode 100644 index b87a408..0000000 --- a/coreutils-diagnose-fts-readdir-failure.patch +++ /dev/null @@ -1,260 +0,0 @@ -Upstream patch - - to diagnose readdir() failures in fts-based utilities, - - fixes boo#984910, - - to be removed with coreutils > v8.25, - - consists of the following parts: - 1. the fix in thee gnulib submodule - 2. the NEWS entry - 3. the test added to verify the fix. - 4. Upstream coreutils commit to fix the test on 32-bit - ----------------------------------------------------------------------- -1. Upstream gnulib submodule commit: - http://git.sv.gnu.org/cgit/gnulib.git/commit/?id=6835fc458f30 - -Taken without the ChangeLog change: - -From 6835fc458f30b94f15d69c35a79cbc2dfabe2d06 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Wed, 22 Jun 2016 13:49:53 +0100 -Subject: [PATCH] fts: handle readdir() errors - -* lib/fts.c (fts_build): readdir(3) returns NULL when finished, -but also upon error when it will also set errno. Therefore -flag the error case from readdir(). We treat the case where -no items are read the same as if the dir can't be accessed, -i.e. by setting fts_errno to FTS_DNR. - -The bug was initially reported by Peter Benie -http://bugzilla.opensuse.org/show_bug.cgi?id=984910 -where it was mentioned that readdir() may fail -when an NFS server has a poor readdir cookie implementation. ----------------------------------------------------------------------- -2. Upstream coreutils commit: - http://git.sv.gnu.org/cgit/coreutils.git/commit/?id=ef9650170f79 - -Take the NEWS change only, as the fix in fts.c was already -pulled in with the above gnulib commit. - -From ef9650170f795be41223c8887258a1c596ecc162 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Sun, 26 Jun 2016 20:58:41 +0100 -Subject: [PATCH] all: update gnulib submodule and tests/init.sh to latest - -* NEWS: Specifically mention the fts readdir() fix. ----------------------------------------------------------------------- -3. Upstream coreutils commit to add a test: -http://git.sv.gnu.org/cgit/coreutils.git/commit/?id=26616776c0c6 - -From 26616776c0c620ce72b3b69aa5ed63f495552a9e Mon Sep 17 00:00:00 2001 -From: Peter Benie -Date: Sun, 26 Jun 2016 19:07:45 +0100 -Subject: [PATCH] tests: verify that fts diagnoses readdir() failures - -* tests/rm/rm-readdir-fail.sh: A new test to simulate readdir() -failing immediately or after returning a few entries, and verifying -that rm does the appropriate thing. -This was initially reported at: -http://bugzilla.opensuse.org/show_bug.cgi?id=984910 -where it was mentioned that readdir() may fail -when an NFS server has a poor readdir cookie implementation. ----------------------------------------------------------------------- -4. Upstream coreutils commit to fix the test on 32-bit -http://git.sv.gnu.org/cgit/coreutils.git/commit/?id=54c1397510cb - -From 54c1397510cb08433680b5b7da46a8201770e9ee Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Wed, 6 Jul 2016 18:08:32 +0100 -Subject: [PATCH] tests: avoid false failure on 32 bit in readdir() test - -* tests/rm/rm-readdir-fail.sh: Since we use the returned dirent -from the readdir wrapper it must be the correct type and not -just cast. Therefore setup so that we only have to define a -wrapper for readdir(), which works appropriately on 32 and 64 bit. -Issue reported by Bernhard Voelker, where rm was seen to invoke -rmdir() on invalid file names. ----------------------------------------------------------------------- ---- - NEWS | 9 +++ - lib/fts.c | 14 ++++- - tests/local.mk | 1 - tests/rm/rm-readdir-fail.sh | 107 ++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 129 insertions(+), 2 deletions(-) - -Index: NEWS -=================================================================== ---- NEWS.orig -+++ NEWS -@@ -1,5 +1,14 @@ - GNU coreutils NEWS -*- outline -*- - -+* Noteworthy downstream / openSUSE changes -+ -+ chcon, chgrp, chmod, chown, du, and rm, or specifically utilities -+ using the FTS interface, now diagnose failures returned by readdir(). -+ [this bug was inherent in the use of fts: thus, for rm the bug was -+ introduced in coreutils-8.0. du, chmod, chgrp and chown started using -+ fts in 6.0. chcon was added in coreutils-6.9.91 with fts support. ] -+ -+ - * Noteworthy changes in release 8.25 (2016-01-20) [stable] - - ** Bug fixes -Index: lib/fts.c -=================================================================== ---- lib/fts.c.orig -+++ lib/fts.c -@@ -1461,9 +1461,18 @@ fts_build (register FTS *sp, int type) - while (cur->fts_dirp) { - bool is_dir; - size_t d_namelen; -+ __set_errno (0); - struct dirent *dp = readdir(cur->fts_dirp); -- if (dp == NULL) -+ if (dp == NULL) { -+ if (errno) { -+ cur->fts_errno = errno; -+ /* If we've not read any items yet, treat -+ the error as if we can't access the dir. */ -+ cur->fts_info = (continue_readdir || nitems) -+ ? FTS_ERR : FTS_DNR; -+ } - break; -+ } - if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) - continue; - -@@ -1622,7 +1631,8 @@ mem1: saved_er - - /* If didn't find anything, return NULL. */ - if (!nitems) { -- if (type == BREAD) -+ if (type == BREAD -+ && cur->fts_info != FTS_DNR && cur->fts_info != FTS_ERR) - cur->fts_info = FTS_DP; - fts_lfree(head); - return (NULL); -Index: tests/local.mk -=================================================================== ---- tests/local.mk.orig -+++ tests/local.mk -@@ -223,6 +223,7 @@ all_tests = \ - tests/rm/unreadable.pl \ - tests/rm/v-slash.sh \ - tests/rm/many-dir-entries-vs-OOM.sh \ -+ tests/rm/rm-readdir-fail.sh \ - tests/chgrp/default-no-deref.sh \ - tests/chgrp/deref.sh \ - tests/chgrp/no-x.sh \ -Index: tests/rm/rm-readdir-fail.sh -=================================================================== ---- /dev/null -+++ tests/rm/rm-readdir-fail.sh -@@ -0,0 +1,107 @@ -+#!/bin/sh -+# Test rm's behaviour when the directory cannot be read. -+# This test is skipped on systems that lack LD_PRELOAD support. -+ -+# Copyright (C) 2016 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program 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 General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ rm -+require_gcc_shared_ -+ -+mkdir -p dir/notempty || framework_failure_ -+ -+# Simulate "readdir" failure. -+cat > k.c <<\EOF || framework_failure_ -+#define _GNU_SOURCE -+ -+/* Setup so we don't have to worry about readdir64. */ -+#ifndef __LP64__ -+# define _FILE_OFFSET_BITS 64 -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+ -+struct dirent *readdir (DIR *dirp) -+{ -+ static struct dirent *(*real_readdir)(DIR *dirp); -+ if (! real_readdir && ! (real_readdir = dlsym (RTLD_NEXT, "readdir"))) -+ { -+ fprintf (stderr, "Failed to find readdir()\n"); -+ errno = ESRCH; -+ return NULL; -+ } -+ static struct dirent* d; -+ if (! d && ! ( d = real_readdir (dirp))) -+ { -+ fprintf (stderr, "Failed to get dirent\n"); -+ errno = ENOENT; -+ return NULL; -+ } -+ -+ /* Flag that LD_PRELOAD and above functions work. */ -+ static int count = 1; -+ if (count == 1) -+ fclose (fopen ("preloaded", "w")); -+ -+ /* Return some entries to trigger partial read failure, -+ ensuring we don't return ignored '.' or '..' */ -+ char const *readdir_partial = getenv ("READDIR_PARTIAL"); -+ if (readdir_partial && *readdir_partial && count <= 3) -+ { -+ count++; -+ d->d_name[0]='0'+count; d->d_name[1]='\0'; -+#ifdef _DIRENT_HAVE_D_NAMLEN -+ _D_EXACT_NAMELEN(d)=2; -+#endif -+ errno = 0; -+ return d; -+ }; -+ -+ /* Fail. */ -+ errno = ENOENT; -+ return NULL; -+} -+EOF -+ -+# Then compile/link it: -+gcc_shared_ k.c k.so \ -+ || framework_failure_ 'failed to build shared library' -+ -+# Test if LD_PRELOAD works: -+export READDIR_PARTIAL -+for READDIR_PARTIAL in '' '1'; do -+ rm -f preloaded -+ (LD_PRELOAD=$LD_PRELOAD:./k.so returns_ 1 rm -Rf dir 2>>err) || fail=1 -+ test -f preloaded || -+ skip_ "internal test failure: maybe LD_PRELOAD doesn't work?" -+done -+ -+# First case is failure to read any items from dir, then assume empty. -+# Generally that will be diagnosed when rm tries to rmdir(). -+# Second case is more general error where we fail immediately -+# (with ENOENT in this case but it could be anything). -+cat < exp -+rm: cannot remove 'dir': Directory not empty -+rm: traversal failed: dir: No such file or directory -+EOF -+ -+compare exp err || fail=1 -+ -+Exit $fail diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 18299e5..c8db28b 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,17 +1,24 @@ + 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 | 441 ++++++++++++++++++++++++- - src/expand.c | 165 +++++++++ + src/expand-common.c | 114 ++++++ + src/expand-common.h | 12 + src/expand.c | 92 ++++- src/fold.c | 308 ++++++++++++++++- - src/join.c | 363 ++++++++++++++++++-- - src/pr.c | 444 +++++++++++++++++++++++-- - src/sort.c | 765 +++++++++++++++++++++++++++++++++++++++++--- - src/unexpand.c | 228 +++++++++++++ - src/uniq.c | 263 ++++++++++++++- - tests/i18n/sort-month.sh | 34 + + src/join.c | 359 +++++++++++++++++--- + src/pr.c | 443 ++++++++++++++++++++++--- + src/sort.c | 772 +++++++++++++++++++++++++++++++++++++++++--- + src/unexpand.c | 101 ++++- + src/uniq.c | 265 ++++++++++++++- + tests/expand/mb.sh | 183 ++++++++++ tests/i18n/sort.sh | 29 + - tests/local.mk | 3 + tests/local.mk | 4 tests/misc/cut.pl | 7 - tests/misc/expand.pl | 40 ++ + tests/misc/expand.pl | 42 ++ tests/misc/fold.pl | 50 ++ tests/misc/join.pl | 50 ++ tests/misc/sort-mb-tests.sh | 45 ++ @@ -20,8 +27,41 @@ tests/misc/unexpand.pl | 39 ++ tests/misc/uniq.pl | 55 +++ tests/pr/pr-tests.pl | 49 ++ - 22 files changed, 3287 insertions(+), 181 deletions(-) + tests/unexpand/mb.sh | 172 +++++++++ + 30 files changed, 3778 insertions(+), 219 deletions(-) + create mode 100644 lib/mbfile.c + create mode 100644 lib/mbfile.h + create mode 100644 m4/mbfile.m4 + create mode 100644 tests/expand/mb.sh + create mode 100644 tests/i18n/sort.sh + create mode 100644 tests/misc/sort-mb-tests.sh + create mode 100644 tests/unexpand/mb.sh +Index: bootstrap.conf +=================================================================== +--- bootstrap.conf.orig ++++ bootstrap.conf +@@ -152,6 +152,7 @@ gnulib_modules=" + maintainer-makefile + malloc-gnu + manywarnings ++ mbfile + mbrlen + mbrtowc + mbsalign +Index: configure.ac +=================================================================== +--- configure.ac.orig ++++ configure.ac +@@ -427,6 +427,8 @@ fi + # I'm leaving it here for now. This whole thing needs to be modernized... + gl_WINSIZE_IN_PTEM + ++gl_MBFILE ++ + gl_HEADER_TIOCGWINSZ_IN_TERMIOS_H + + if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ Index: lib/linebuffer.h =================================================================== --- lib/linebuffer.h.orig @@ -48,6 +88,293 @@ Index: lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ +Index: lib/mbfile.c +=================================================================== +--- /dev/null ++++ lib/mbfile.c +@@ -0,0 +1,3 @@ ++#include ++#define MBFILE_INLINE _GL_EXTERN_INLINE ++#include "mbfile.h" +Index: lib/mbfile.h +=================================================================== +--- /dev/null ++++ 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. ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program 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 General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++/* Written by Mitsuru Chinen ++ and Bruno Haible . */ ++ ++/* The macros in this file implement multi-byte character input from a ++ stream. ++ ++ mb_file_t ++ is the type for multibyte character input stream, usable for variable ++ declarations. ++ ++ mbf_char_t ++ is the type for multibyte character or EOF, usable for variable ++ declarations. ++ ++ mbf_init (mbf, stream) ++ initializes the MB_FILE for reading from stream. ++ ++ mbf_getc (mbc, mbf) ++ reads the next multibyte character from mbf and stores it in mbc. ++ ++ mb_iseof (mbc) ++ returns true if mbc represents the EOF value. ++ ++ Here are the function prototypes of the macros. ++ ++ extern void mbf_init (mb_file_t mbf, FILE *stream); ++ extern void mbf_getc (mbf_char_t mbc, mb_file_t mbf); ++ extern bool mb_iseof (const mbf_char_t mbc); ++ */ ++ ++#ifndef _MBFILE_H ++#define _MBFILE_H 1 ++ ++#include ++#include ++#include ++#include ++ ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.1 has a bug: and must be included before ++ . */ ++#include ++#include ++#include ++ ++#include "mbchar.h" ++ ++#ifndef _GL_INLINE_HEADER_BEGIN ++ #error "Please include config.h first." ++#endif ++_GL_INLINE_HEADER_BEGIN ++#ifndef MBFILE_INLINE ++# define MBFILE_INLINE _GL_INLINE ++#endif ++ ++struct mbfile_multi { ++ FILE *fp; ++ bool eof_seen; ++ bool have_pushback; ++ mbstate_t state; ++ unsigned int bufcount; ++ char buf[MBCHAR_BUF_SIZE]; ++ struct mbchar pushback; ++}; ++ ++MBFILE_INLINE void ++mbfile_multi_getc (struct mbchar *mbc, struct mbfile_multi *mbf) ++{ ++ size_t bytes; ++ ++ /* 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; ++ } ++ ++ /* Before using mbrtowc, we need at least one byte. */ ++ if (mbf->bufcount == 0) ++ { ++ int c = getc (mbf->fp); ++ if (c == EOF) ++ { ++ mbf->eof_seen = true; ++ goto eof; ++ } ++ mbf->buf[0] = (unsigned char) c; ++ mbf->bufcount++; ++ } ++ ++ /* Handle most ASCII characters quickly, without calling mbrtowc(). */ ++ if (mbf->bufcount == 1 && mbsinit (&mbf->state) && is_basic (mbf->buf[0])) ++ { ++ /* These characters are part of the basic character set. ISO C 99 ++ guarantees that their wide character code is identical to their ++ char code. */ ++ mbc->wc = mbc->buf[0] = mbf->buf[0]; ++ mbc->wc_valid = true; ++ mbc->ptr = &mbc->buf[0]; ++ mbc->bytes = 1; ++ mbf->bufcount = 0; ++ return; ++ } ++ ++ /* Use mbrtowc on an increasing number of bytes. Read only as many bytes ++ from mbf->fp as needed. This is needed to give reasonable interactive ++ behaviour when mbf->fp is connected to an interactive tty. */ ++ for (;;) ++ { ++ /* We don't know whether the 'mbrtowc' function updates the state when ++ it returns -2, - this is the ISO C 99 and glibc-2.2 behaviour - or ++ not - amended ANSI C, glibc-2.1 and Solaris 2.7 behaviour. We ++ don't have an autoconf test for this, yet. ++ The new behaviour would allow us to feed the bytes one by one into ++ mbrtowc. But the old behaviour forces us to feed all bytes since ++ the end of the last character into mbrtowc. Since we want to retry ++ with more bytes when mbrtowc returns -2, we must backup the state ++ before calling mbrtowc, because implementations with the new ++ behaviour will clobber it. */ ++ mbstate_t backup_state = mbf->state; ++ ++ bytes = mbrtowc (&mbc->wc, &mbf->buf[0], mbf->bufcount, &mbf->state); ++ ++ if (bytes == (size_t) -1) ++ { ++ /* An invalid multibyte sequence was encountered. */ ++ /* Return a single byte. */ ++ bytes = 1; ++ mbc->wc_valid = false; ++ break; ++ } ++ else if (bytes == (size_t) -2) ++ { ++ /* An incomplete multibyte character. */ ++ mbf->state = backup_state; ++ if (mbf->bufcount == MBCHAR_BUF_SIZE) ++ { ++ /* An overlong incomplete multibyte sequence was encountered. */ ++ /* Return a single byte. */ ++ bytes = 1; ++ mbc->wc_valid = false; ++ break; ++ } ++ else ++ { ++ /* Read one more byte and retry mbrtowc. */ ++ int c = getc (mbf->fp); ++ if (c == EOF) ++ { ++ /* An incomplete multibyte character at the end. */ ++ mbf->eof_seen = true; ++ bytes = mbf->bufcount; ++ mbc->wc_valid = false; ++ break; ++ } ++ mbf->buf[mbf->bufcount] = (unsigned char) c; ++ mbf->bufcount++; ++ } ++ } ++ else ++ { ++ if (bytes == 0) ++ { ++ /* A null wide character was encountered. */ ++ bytes = 1; ++ assert (mbf->buf[0] == '\0'); ++ assert (mbc->wc == 0); ++ } ++ mbc->wc_valid = true; ++ break; ++ } ++ } ++ ++ /* Return the multibyte sequence mbf->buf[0..bytes-1]. */ ++ mbc->ptr = &mbc->buf[0]; ++ memcpy (&mbc->buf[0], &mbf->buf[0], bytes); ++ mbc->bytes = bytes; ++ ++ mbf->bufcount -= bytes; ++ if (mbf->bufcount > 0) ++ { ++ /* It's not worth calling memmove() for so few bytes. */ ++ unsigned int count = mbf->bufcount; ++ char *p = &mbf->buf[0]; ++ ++ do ++ { ++ *p = *(p + bytes); ++ p++; ++ } ++ while (--count > 0); ++ } ++ return; ++ ++eof: ++ /* An mbchar_t with bytes == 0 is used to indicate EOF. */ ++ mbc->ptr = NULL; ++ mbc->bytes = 0; ++ mbc->wc_valid = false; ++ return; ++} ++ ++MBFILE_INLINE void ++mbfile_multi_ungetc (const struct mbchar *mbc, struct mbfile_multi *mbf) ++{ ++ mb_copy (&mbf->pushback, mbc); ++ mbf->have_pushback = true; ++} ++ ++typedef struct mbfile_multi mb_file_t; ++ ++typedef mbchar_t mbf_char_t; ++ ++#define mbf_init(mbf, stream) \ ++ ((mbf).fp = (stream), \ ++ (mbf).eof_seen = false, \ ++ (mbf).have_pushback = false, \ ++ memset (&(mbf).state, '\0', sizeof (mbstate_t)), \ ++ (mbf).bufcount = 0) ++ ++#define mbf_getc(mbc, mbf) mbfile_multi_getc (&(mbc), &(mbf)) ++ ++#define mbf_ungetc(mbc, mbf) mbfile_multi_ungetc (&(mbc), &(mbf)) ++ ++#define mb_iseof(mbc) ((mbc).bytes == 0) ++ ++#ifndef _GL_INLINE_HEADER_BEGIN ++ #error "Please include config.h first." ++#endif ++_GL_INLINE_HEADER_BEGIN ++ ++#endif /* _MBFILE_H */ +Index: m4/mbfile.m4 +=================================================================== +--- /dev/null ++++ m4/mbfile.m4 +@@ -0,0 +1,14 @@ ++# mbfile.m4 serial 7 ++dnl Copyright (C) 2005, 2008-2015 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 mbfile.h ++dnl From Bruno Haible. ++ ++AC_DEFUN([gl_MBFILE], ++[ ++ AC_REQUIRE([AC_TYPE_MBSTATE_T]) ++ : ++]) Index: src/cut.c =================================================================== --- src/cut.c.orig @@ -613,207 +940,323 @@ Index: src/cut.c } if (optind == argc) +Index: src/expand-common.c +=================================================================== +--- src/expand-common.c.orig ++++ src/expand-common.c +@@ -18,6 +18,7 @@ + + #include + #include ++#include + #include "system.h" + #include "die.h" + #include "error.h" +@@ -85,6 +86,119 @@ add_tab_stop (uintmax_t tabval) + } + } + ++extern int ++set_utf_locale (void) ++{ ++ /*try using some predefined locale */ ++ const char* predef_locales[] = {"C.UTF8","en_US.UTF8","en_GB.UTF8"}; ++ ++ const int predef_locales_count=3; ++ for (int i=0;ibufcount=0; ++ if (c == 0xEF) ++ { ++ c=fgetc(fp); ++ } ++ else ++ { ++ if (c != EOF) ++ { ++ ungetc(c,fp); ++ } ++ return false; ++ } ++ ++ if (c == 0xBB) ++ { ++ c=fgetc(fp); ++ } ++ else ++ { ++ if ( c!= EOF ) ++ { ++ mbf->buf[0]=(unsigned char) 0xEF; ++ mbf->bufcount=1; ++ ungetc(c,fp); ++ return false; ++ } ++ else ++ { ++ ungetc(0xEF,fp); ++ return false; ++ } ++ } ++ if (c == 0xBF) ++ { ++ mbf->bufcount=0; ++ return true; ++ } ++ else ++ { ++ if (c != EOF) ++ { ++ mbf->buf[0]=(unsigned char) 0xEF; ++ mbf->buf[1]=(unsigned char) 0xBB; ++ mbf->bufcount=2; ++ ungetc(c,fp); ++ return false; ++ } ++ else ++ { ++ mbf->buf[0]=(unsigned char) 0xEF; ++ mbf->bufcount=1; ++ ungetc(0xBB,fp); ++ return false; ++ } ++ } ++ return false; ++} ++ ++extern void ++print_bom(void) ++{ ++ putc (0xEF, stdout); ++ putc (0xBB, stdout); ++ putc (0xBF, stdout); ++} ++ + /* 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 +@@ -34,6 +34,18 @@ extern size_t max_column_width; + /* The desired exit status. */ + extern int exit_status; + ++extern int ++set_utf_locale (void); ++ ++extern bool ++check_utf_locale(void); ++ ++extern bool ++check_bom(FILE* fp, mb_file_t *mbf); ++ ++extern void ++print_bom(void); ++ + /* 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 -@@ -37,12 +37,34 @@ +@@ -37,6 +37,9 @@ #include #include #include + -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ -+#if HAVE_WCHAR_H -+# include -+#endif -+ -+/* Get iswblank(). */ -+#if HAVE_WCTYPE_H -+# include -+#endif ++#include + #include "system.h" - #include "error.h" - #include "fadvise.h" - #include "quote.h" + #include "die.h" #include "xstrndup.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 -+# define MB_LEN_MAX 16 -+#endif +@@ -100,19 +103,41 @@ expand (void) + { + /* Input stream. */ + FILE *fp = next_file (NULL); +- ++ mb_file_t mbf; ++ mbf_char_t c; ++ /* True if the starting locale is utf8. */ ++ bool using_utf_locale; + -+/* 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 ++ /* True if the first file contains BOM header. */ ++ bool found_bom; ++ using_utf_locale=check_utf_locale(); + - /* The official name of this program (e.g., no 'g' prefix). */ - #define PROGRAM_NAME "expand" + if (!fp) + return; ++ mbf_init (mbf, fp); ++ found_bom=check_bom(fp,&mbf); -@@ -357,6 +379,142 @@ expand (void) +- while (true) ++ if (using_utf_locale == false && found_bom == true) ++ { ++ /*try using some predefined locale */ ++ ++ if (set_utf_locale () != 0) + { +- /* Input character, or EOF. */ +- int c; ++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); ++ } ++ } ++ ++ ++ if (found_bom == true) ++ { ++ print_bom(); ++ } + ++ while (true) ++ { + /* If true, perform translations. */ + bool convert = true; + +- + /* The following variables have valid values only when CONVERT + is true: */ + +@@ -122,17 +147,48 @@ expand (void) + /* Index in TAB_LIST of next tab stop to examine. */ + size_t tab_index = 0; + +- + /* Convert a line of text. */ + + do + { +- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) +- continue; ++ while (true) { ++ mbf_getc (c, mbf); ++ if ((mb_iseof (c)) && (fp = next_file (fp))) ++ { ++ mbf_init (mbf, fp); ++ if (fp!=NULL) ++ { ++ if (check_bom(fp,&mbf)==true) ++ { ++ /*Not the first file - check BOM header*/ ++ if (using_utf_locale==false && found_bom==false) ++ { ++ /*BOM header in subsequent file but not in the first one. */ ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); ++ } ++ } ++ else ++ { ++ if(using_utf_locale==false && found_bom==true) ++ { ++ /*First file conatined BOM header - locale was switched to UTF ++ /*all subsequent files should contain BOM. */ ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); ++ } ++ } ++ } ++ continue; ++ } ++ else ++ { ++ break; ++ } ++ } ++ + + if (convert) + { +- if (c == '\t') ++ if (mb_iseq (c, '\t')) + { + /* Column the next input tab stop is on. */ + uintmax_t next_tab_column; +@@ -151,32 +207,34 @@ expand (void) + if (putchar (' ') < 0) + die (EXIT_FAILURE, errno, _("write error")); + +- c = ' '; ++ mb_setascii (&c, ' '); + } +- else if (c == '\b') ++ else if (mb_iseq (c, '\b')) + { + /* Go back one column, and force recalculation of the + next tab stop. */ + column -= !!column; + tab_index -= !!tab_index; + } +- else ++ /* A leading control character could make us trip over. */ ++ else if (!mb_iscntrl (c)) + { +- column++; ++ column += mb_width (c); + if (!column) + die (EXIT_FAILURE, 0, _("input line is too long")); + } + +- convert &= convert_entire_line || !! isblank (c); ++ convert &= convert_entire_line || mb_isblank (c); + } + +- if (c < 0) ++ if (mb_iseof (c)) + return; + +- if (putchar (c) < 0) ++ mb_putc (c, stdout); ++ if (ferror (stdout)) + die (EXIT_FAILURE, errno, _("write error")); + } +- while (c != '\n'); ++ while (!mb_iseq (c, '\n')); } } -+#if HAVE_MBRTOWC -+static void -+expand_multibyte (void) -+{ -+ FILE *fp; /* Input strem. */ -+ mbstate_t i_state; /* Current shift state of the input stream. */ -+ mbstate_t i_state_bak; /* Back up the I_STATE. */ -+ mbstate_t o_state; /* Current shift state of the output stream. */ -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ char *bufpos = buf; /* Next read position of BUF. */ -+ size_t buflen = 0; /* The length of the byte sequence in buf. */ -+ wchar_t wc; /* A gotten wide character. */ -+ size_t mblength; /* The byte size of a multibyte character -+ which shows as same character as WC. */ -+ int tab_index = 0; /* Index in `tab_list' of next tabstop. */ -+ int column = 0; /* Column on screen of the next char. */ -+ int next_tab_column; /* Column the next tab stop is on. */ -+ int convert = 1; /* If nonzero, perform translations. */ -+ -+ fp = next_file ((FILE *) NULL); -+ if (fp == NULL) -+ return; -+ -+ memset (&o_state, '\0', sizeof(mbstate_t)); -+ memset (&i_state, '\0', sizeof(mbstate_t)); -+ -+ for (;;) -+ { -+ /* Refill the buffer BUF. */ -+ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) -+ { -+ memmove (buf, bufpos, buflen); -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); -+ bufpos = buf; -+ } -+ -+ /* No character is left in BUF. */ -+ if (buflen < 1) -+ { -+ fp = next_file (fp); -+ -+ if (fp == NULL) -+ break; /* No more files. */ -+ else -+ { -+ memset (&i_state, '\0', sizeof(mbstate_t)); -+ continue; -+ } -+ } -+ -+ /* Get a wide character. */ -+ i_state_bak = i_state; -+ mblength = mbrtowc (&wc, bufpos, buflen, &i_state); -+ -+ switch (mblength) -+ { -+ case (size_t)-1: /* illegal byte sequence. */ -+ case (size_t)-2: -+ mblength = 1; -+ i_state = i_state_bak; -+ if (convert) -+ { -+ ++column; -+ if (convert_entire_line == 0 && !isblank(*bufpos)) -+ convert = 0; -+ } -+ putchar (*bufpos); -+ break; -+ -+ case 0: /* null. */ -+ mblength = 1; -+ if (convert && convert_entire_line == 0) -+ convert = 0; -+ putchar ('\0'); -+ break; -+ -+ default: -+ if (wc == L'\n') /* LF. */ -+ { -+ tab_index = 0; -+ column = 0; -+ convert = 1; -+ putchar ('\n'); -+ } -+ else if (wc == L'\t' && convert) /* Tab. */ -+ { -+ if (tab_size == 0) -+ { -+ /* Do not let tab_index == first_free_tab; -+ stop when it is 1 less. */ -+ while (tab_index < first_free_tab - 1 -+ && column >= tab_list[tab_index]) -+ tab_index++; -+ next_tab_column = tab_list[tab_index]; -+ if (tab_index < first_free_tab - 1) -+ tab_index++; -+ if (column >= next_tab_column) -+ next_tab_column = column + 1; -+ } -+ else -+ next_tab_column = column + tab_size - column % tab_size; -+ -+ while (column < next_tab_column) -+ { -+ putchar (' '); -+ ++column; -+ } -+ } -+ else /* Others. */ -+ { -+ if (convert) -+ { -+ if (wc == L'\b') -+ { -+ if (column > 0) -+ --column; -+ } -+ else -+ { -+ int width; /* The width of WC. */ -+ -+ width = wcwidth (wc); -+ column += (width > 0) ? width : 0; -+ if (convert_entire_line == 0 && !iswblank(wc)) -+ convert = 0; -+ } -+ } -+ fwrite (bufpos, sizeof(char), mblength, stdout); -+ } -+ } -+ buflen -= mblength; -+ bufpos += mblength; -+ } -+} -+#endif -+ - int - main (int argc, char **argv) - { -@@ -421,7 +579,12 @@ main (int argc, char **argv) - - file_list = (optind < argc ? &argv[optind] : stdin_argv); - -- expand (); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ expand_multibyte (); -+ else -+#endif -+ expand (); - - if (have_read_stdin && fclose (stdin) != 0) - error (EXIT_FAILURE, errno, "-"); Index: src/fold.c =================================================================== --- src/fold.c.orig +++ src/fold.c -@@ -22,11 +22,33 @@ +@@ -22,12 +22,34 @@ #include #include @@ -828,6 +1271,7 @@ Index: src/fold.c +#endif + #include "system.h" + #include "die.h" #include "error.h" #include "fadvise.h" #include "xdectoint.h" @@ -847,7 +1291,7 @@ Index: src/fold.c #define TAB_WIDTH 8 /* The official name of this program (e.g., no 'g' prefix). */ -@@ -34,20 +56,41 @@ +@@ -35,20 +57,41 @@ #define AUTHORS proper_name ("David MacKenzie") @@ -893,7 +1337,7 @@ Index: src/fold.c {"spaces", no_argument, NULL, 's'}, {"width", required_argument, NULL, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing t +@@ -76,6 +119,7 @@ Wrap input lines in each FILE, writing t fputs (_("\ -b, --bytes count bytes rather than columns\n\ @@ -901,7 +1345,7 @@ Index: src/fold.c -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 t +@@ -93,7 +137,7 @@ Wrap input lines in each FILE, writing t static size_t adjust_column (size_t column, char c) { @@ -910,7 +1354,7 @@ Index: src/fold.c { if (c == '\b') { -@@ -115,30 +159,14 @@ adjust_column (size_t column, char c) +@@ -116,30 +160,14 @@ adjust_column (size_t column, char c) to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -943,7 +1387,7 @@ Index: src/fold.c fadvise (istream, FADVISE_SEQUENTIAL); -@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t +@@ -169,6 +197,15 @@ fold_file (char const *filename, size_t bool found_blank = false; size_t logical_end = offset_out; @@ -959,16 +1403,16 @@ Index: src/fold.c /* Look for the last blank. */ while (logical_end) { -@@ -214,11 +251,221 @@ fold_file (char const *filename, size_t +@@ -215,11 +252,221 @@ fold_file (char const *filename, size_t line_out[offset_out++] = c; } - saved_errno = errno; + *saved_errno = errno; -+ -+ if (offset_out) -+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); -+ + + if (offset_out) + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); + +} + +#if HAVE_MBRTOWC @@ -1140,10 +1584,10 @@ Index: src/fold.c + } + + *saved_errno = errno; - - if (offset_out) - fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); - ++ ++ if (offset_out) ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); ++ +} +#endif + @@ -1167,7 +1611,7 @@ Index: src/fold.c + + if (istream == NULL) + { -+ error (0, errno, "%s", quotef (filename)); ++ error (0, errno, "%s", filename); + return 1; + } + @@ -1182,7 +1626,7 @@ Index: src/fold.c if (ferror (istream)) { error (0, saved_errno, "%s", quotef (filename)); -@@ -251,7 +498,8 @@ main (int argc, char **argv) +@@ -252,7 +499,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1192,7 +1636,7 @@ Index: src/fold.c while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -260,7 +508,15 @@ main (int argc, char **argv) +@@ -261,7 +509,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -1213,7 +1657,7 @@ Index: src/join.c =================================================================== --- src/join.c.orig +++ src/join.c -@@ -22,18 +22,32 @@ +@@ -22,19 +22,33 @@ #include #include @@ -1228,6 +1672,7 @@ Index: src/join.c +#endif + #include "system.h" + #include "die.h" #include "error.h" #include "fadvise.h" #include "hard-locale.h" @@ -1247,7 +1692,7 @@ Index: src/join.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "join" -@@ -135,10 +149,12 @@ static struct outlist outlist_head; +@@ -136,10 +150,12 @@ static struct outlist outlist_head; /* Last element in 'outlist', where a new element can be added. */ static struct outlist *outlist_end = &outlist_head; @@ -1264,7 +1709,7 @@ Index: src/join.c /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -275,13 +291,14 @@ xfields (struct line *line) +@@ -276,13 +292,14 @@ xfields (struct line *line) if (ptr == lim) return; @@ -1282,7 +1727,7 @@ Index: src/join.c { /* Skip leading blanks before the first field. */ while (field_sep (*ptr)) -@@ -305,6 +322,147 @@ xfields (struct line *line) +@@ -306,6 +323,147 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1430,7 +1875,7 @@ Index: src/join.c static void freeline (struct line *line) { -@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct +@@ -327,56 +485,133 @@ keycmp (struct line const *line1, struct size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -1587,7 +2032,7 @@ Index: src/join.c } /* Check that successive input lines PREV and CURRENT from input file -@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep, +@@ -468,6 +703,11 @@ get_line (FILE *fp, struct line **linep, } ++line_no[which - 1]; @@ -1599,7 +2044,7 @@ Index: src/join.c xfields (line); if (prevline[which - 1]) -@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *li +@@ -567,21 +807,28 @@ prfield (size_t n, struct line const *li /* Output all the fields in line, other than the join field. */ @@ -1631,7 +2076,7 @@ Index: src/join.c prfield (i, line); } } -@@ -591,7 +838,6 @@ static void +@@ -592,7 +839,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; @@ -1639,7 +2084,7 @@ Index: src/join.c size_t field; struct line const *line; -@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct +@@ -626,7 +872,7 @@ prjoin (struct line const *line1, struct o = o->next; if (o == NULL) break; @@ -1648,7 +2093,7 @@ Index: src/join.c } putchar (eolchar); } -@@ -1103,21 +1349,46 @@ main (int argc, char **argv) +@@ -1104,20 +1350,43 @@ main (int argc, char **argv) case 't': { @@ -1675,16 +2120,14 @@ Index: src/join.c + newtablen = 1; if (! newtab) - newtab = '\n'; /* '' => process the whole line. */ -+ { + newtab = (char*)"\n"; /* '' => process the whole line. */ -+ } else if (optarg[1]) { - if (STREQ (optarg, "\\0")) - newtab = '\0'; - else -- error (EXIT_FAILURE, 0, _("multi-character tab %s"), -- quote (optarg)); +- die (EXIT_FAILURE, 0, _("multi-character tab %s"), +- quote (optarg)); + if (newtablen == 1 && newtab[1]) + { + if (STREQ (newtab, "\\0")) @@ -1694,17 +2137,15 @@ Index: src/join.c + if (tab != NULL && strcmp (tab, newtab)) + { + free (newtab); -+ error (EXIT_FAILURE, 0, _("incompatible tabs")); ++ die (EXIT_FAILURE, 0, _("incompatible tabs")); } - if (0 <= tab && tab != newtab) -- error (EXIT_FAILURE, 0, _("incompatible tabs")); +- die (EXIT_FAILURE, 0, _("incompatible tabs")); tab = newtab; -- } + tablen = newtablen; -+ } + } break; - case 'z': Index: src/pr.c =================================================================== --- src/pr.c.orig @@ -1732,9 +2173,9 @@ Index: src/pr.c +#endif + #include "system.h" + #include "die.h" #include "error.h" - #include "fadvise.h" -@@ -323,6 +341,18 @@ +@@ -324,6 +342,18 @@ #include "xstrtol.h" #include "xdectoint.h" @@ -1753,7 +2194,7 @@ Index: src/pr.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" -@@ -415,7 +445,20 @@ struct COLUMN +@@ -416,7 +446,20 @@ struct COLUMN typedef struct COLUMN COLUMN; @@ -1775,7 +2216,7 @@ Index: src/pr.c static bool read_line (COLUMN *p); static bool print_page (void); static bool print_stored (COLUMN *p); -@@ -427,6 +470,7 @@ static void add_line_number (COLUMN *p); +@@ -428,6 +471,7 @@ static void add_line_number (COLUMN *p); static void getoptnum (const char *n_str, int min, int *num, const char *errfmt); static void getoptarg (char *arg, char switch_char, char *character, @@ -1783,7 +2224,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); -@@ -440,7 +484,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); @@ -1791,7 +2232,7 @@ Index: src/pr.c static void cleanup (void); static void print_sep_string (void); static void separator_string (const char *optarg_S); -@@ -452,7 +495,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]. */ @@ -1800,7 +2241,7 @@ Index: src/pr.c /* Index of the position in buff where the next character will be stored. */ -@@ -556,7 +599,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. */ @@ -1809,7 +2250,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. */ -@@ -566,7 +609,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. */ @@ -1821,7 +2262,7 @@ Index: src/pr.c /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -636,7 +682,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. */ @@ -1836,18 +2277,18 @@ Index: src/pr.c /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ -@@ -689,6 +741,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 *col_sep_string = (char *) ""; + static char const *col_sep_string = ""; static int col_sep_length = 0; +static int col_sep_width = 0; static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -839,6 +892,13 @@ separator_string (const char *optarg_S) - col_sep_length = (int) strlen (optarg_S); - col_sep_string = xmalloc (col_sep_length + 1); - strcpy (col_sep_string, optarg_S); +@@ -851,6 +904,13 @@ separator_string (const char *optarg_S) + integer_overflow (); + col_sep_length = len; + col_sep_string = optarg_S; + +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) @@ -1858,7 +2299,7 @@ Index: src/pr.c } int -@@ -863,6 +923,21 @@ main (int argc, char **argv) +@@ -875,6 +935,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1879,8 +2320,8 @@ Index: src/pr.c + n_files = 0; file_names = (argc > 1 - ? xmalloc ((argc - 1) * sizeof (char *)) -@@ -939,8 +1014,12 @@ main (int argc, char **argv) + ? xnmalloc (argc - 1, sizeof (char *)) +@@ -951,8 +1026,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -1895,7 +2336,7 @@ Index: src/pr.c /* Could check tab width > 0. */ untabify_input = true; break; -@@ -953,8 +1032,12 @@ main (int argc, char **argv) +@@ -965,8 +1044,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -1910,7 +2351,7 @@ Index: src/pr.c /* Could check tab width > 0. */ tabify_output = true; break; -@@ -972,8 +1055,8 @@ main (int argc, char **argv) +@@ -984,8 +1067,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -1921,16 +2362,15 @@ Index: src/pr.c break; case 'N': skip_count = false; -@@ -997,7 +1080,7 @@ main (int argc, char **argv) - old_s = false; +@@ -1010,6 +1093,7 @@ main (int argc, char **argv) /* Reset an additional input of -s, -S dominates -s */ - col_sep_string = bad_cast (""); -- col_sep_length = 0; -+ col_sep_length = col_sep_width = 0; + col_sep_string = ""; + col_sep_length = 0; ++ col_sep_width = 0; use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, i +@@ -1166,10 +1250,45 @@ getoptnum (const char *n_str, int min, i a number. */ static void @@ -1978,7 +2418,7 @@ Index: src/pr.c if (*arg) { long int tmp_long; -@@ -1177,6 +1295,11 @@ static void +@@ -1191,6 +1310,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -1990,7 +2430,7 @@ Index: src/pr.c lines_per_body = lines_per_page - lines_per_header - lines_per_footer; if (lines_per_body <= 0) -@@ -1214,7 +1337,7 @@ init_parameters (int number_of_files) +@@ -1228,7 +1352,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -1999,7 +2439,7 @@ Index: src/pr.c use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1244,11 +1367,11 @@ init_parameters (int number_of_files) +@@ -1258,11 +1382,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. */ @@ -2013,16 +2453,16 @@ Index: src/pr.c /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1257,7 +1380,7 @@ init_parameters (int number_of_files) +@@ -1271,7 +1395,7 @@ init_parameters (int number_of_files) } - chars_per_column = (chars_per_line - chars_used_by_number -- - (columns - 1) * col_sep_length) / columns; -+ - (columns - 1) * col_sep_width) / columns; - - if (chars_per_column < 1) - error (EXIT_FAILURE, 0, _("page width too narrow")); -@@ -1275,7 +1398,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)) + sep_chars = INT_MAX; + if (INT_SUBTRACT_WRAPV (chars_per_line - chars_used_by_number, sep_chars, + &useful_chars)) +@@ -1294,7 +1418,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); @@ -2031,7 +2471,7 @@ Index: src/pr.c } /* Open the necessary files, -@@ -1383,7 +1506,7 @@ init_funcs (void) +@@ -1402,7 +1526,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -2040,7 +2480,7 @@ Index: src/pr.c /* This loop takes care of all but the rightmost column. */ -@@ -1417,7 +1540,7 @@ init_funcs (void) +@@ -1436,7 +1560,7 @@ init_funcs (void) } else { @@ -2049,19 +2489,19 @@ Index: src/pr.c h_next = h + chars_per_column; } } -@@ -1708,9 +1831,9 @@ static void +@@ -1727,9 +1851,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; -- if (padding_not_printed - col_sep_length > 0) -+ if (padding_not_printed - col_sep_width > 0) +- if (col_sep_length < padding_not_printed) ++ if (col_sep_width < padding_not_printed) { - pad_across_to (padding_not_printed - col_sep_length); + pad_across_to (padding_not_printed - col_sep_width); padding_not_printed = ANYWHERE; } -@@ -1981,13 +2104,13 @@ store_char (char c) +@@ -2004,13 +2128,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -2077,7 +2517,7 @@ Index: src/pr.c char *s; int num_width; -@@ -2004,22 +2127,24 @@ add_line_number (COLUMN *p) +@@ -2027,22 +2151,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. */ @@ -2106,7 +2546,7 @@ Index: src/pr.c output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2180,7 +2305,7 @@ print_white_space (void) +@@ -2203,7 +2329,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2115,15 +2555,15 @@ Index: src/pr.c h_old = h_new; } while (++h_old <= goal) -@@ -2200,6 +2325,7 @@ print_sep_string (void) +@@ -2223,6 +2349,7 @@ print_sep_string (void) { - char *s; + char const *s = col_sep_string; int l = col_sep_length; + int not_space_flag; - s = col_sep_string; - -@@ -2213,6 +2339,7 @@ print_sep_string (void) + if (separators_not_printed <= 0) + { +@@ -2234,6 +2361,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2131,7 +2571,7 @@ Index: src/pr.c while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2226,12 +2353,15 @@ print_sep_string (void) +@@ -2247,12 +2375,15 @@ print_sep_string (void) } else { @@ -2148,7 +2588,7 @@ Index: src/pr.c /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clu +@@ -2280,7 +2411,7 @@ print_clump (COLUMN *p, int n, char *clu required number of tabs and spaces. */ static void @@ -2157,7 +2597,7 @@ Index: src/pr.c { if (tabify_output) { -@@ -2283,6 +2413,74 @@ print_char (char c) +@@ -2304,6 +2435,74 @@ print_char (char c) putchar (c); } @@ -2232,19 +2672,19 @@ Index: src/pr.c /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2462,9 +2660,9 @@ read_line (COLUMN *p) +@@ -2483,9 +2682,9 @@ read_line (COLUMN *p) align_empty_cols = false; } -- if (padding_not_printed - col_sep_length > 0) -+ if (padding_not_printed - col_sep_width > 0) +- if (col_sep_length < padding_not_printed) ++ if (col_sep_width < padding_not_printed) { - pad_across_to (padding_not_printed - col_sep_length); + pad_across_to (padding_not_printed - col_sep_width); padding_not_printed = ANYWHERE; } -@@ -2534,7 +2732,7 @@ print_stored (COLUMN *p) +@@ -2555,7 +2754,7 @@ print_stored (COLUMN *p) int i; int line = p->current_line++; @@ -2253,7 +2693,7 @@ Index: src/pr.c /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2546,7 +2744,7 @@ print_stored (COLUMN *p) +@@ -2567,7 +2766,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -2262,19 +2702,19 @@ Index: src/pr.c pad_vertically = true; -@@ -2565,9 +2763,9 @@ print_stored (COLUMN *p) +@@ -2586,9 +2785,9 @@ print_stored (COLUMN *p) } } -- if (padding_not_printed - col_sep_length > 0) -+ if (padding_not_printed - col_sep_width > 0) +- if (col_sep_length < padding_not_printed) ++ if (col_sep_width < padding_not_printed) { - pad_across_to (padding_not_printed - col_sep_length); + pad_across_to (padding_not_printed - col_sep_width); padding_not_printed = ANYWHERE; } -@@ -2580,8 +2778,8 @@ print_stored (COLUMN *p) +@@ -2601,8 +2800,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2285,7 +2725,7 @@ Index: src/pr.c } return true; -@@ -2600,7 +2798,7 @@ print_stored (COLUMN *p) +@@ -2621,7 +2820,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2294,7 +2734,7 @@ Index: src/pr.c { unsigned char uc = c; char *s = clump_buff; -@@ -2610,10 +2808,10 @@ char_to_clump (char c) +@@ -2631,10 +2830,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2307,7 +2747,7 @@ Index: src/pr.c { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2694,6 +2892,164 @@ char_to_clump (char c) +@@ -2715,6 +2914,164 @@ char_to_clump (char c) return chars; } @@ -2490,8 +2930,8 @@ Index: src/sort.c + #include "system.h" #include "argmatch.h" - #include "error.h" -@@ -163,14 +171,39 @@ static int decimal_point; + #include "die.h" +@@ -165,14 +173,39 @@ static int decimal_point; /* Thousands separator; if -1, then there isn't one. */ static int thousands_sep; @@ -2532,7 +2972,7 @@ Index: src/sort.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -344,13 +377,11 @@ static bool reverse; +@@ -346,13 +379,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -2549,7 +2989,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. */ -@@ -810,6 +841,46 @@ reap_all (void) +@@ -811,6 +842,46 @@ reap_all (void) reap (-1); } @@ -2596,7 +3036,7 @@ Index: src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1254,7 +1325,7 @@ zaptemp (char const *name) +@@ -1255,7 +1326,7 @@ zaptemp (char const *name) free (node); } @@ -2605,7 +3045,7 @@ Index: src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void c +@@ -1270,7 +1341,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2614,7 +3054,7 @@ Index: src/sort.c { size_t i; -@@ -1281,7 +1352,7 @@ inittables (void) +@@ -1282,7 +1353,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2623,7 +3063,7 @@ Index: src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char con +@@ -1364,6 +1435,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2708,7 +3148,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) -@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf +@@ -1597,7 +1746,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2717,7 +3157,7 @@ Index: src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struc +@@ -1606,10 +1755,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2730,7 +3170,7 @@ Index: src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struc +@@ -1635,11 +1784,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2802,7 +3242,7 @@ Index: src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1653,10 +1861,10 @@ limfield (struct line const *line, struc +@@ -1654,10 +1862,10 @@ limfield (struct line const *line, struc 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -2815,7 +3255,7 @@ Index: src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struc +@@ -1703,10 +1911,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2828,7 +3268,7 @@ Index: src/sort.c if (newlim) lim = newlim; } -@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struc +@@ -1737,6 +1945,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2959,7 +3399,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 -@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1823,8 +2155,22 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2984,7 +3424,23 @@ Index: src/sort.c line->keybeg = line_start; } } -@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char co +@@ -1958,12 +2304,10 @@ find_unit_order (char const *number) + < K/k < M < G < T < P < E < Z < Y */ + + static int +-human_numcompare (char const *a, char const *b) ++human_numcompare (char *a, char *b) + { +- while (blanks[to_uchar (*a)]) +- a++; +- while (blanks[to_uchar (*b)]) +- b++; ++ skipblanks(&a, a + strlen(a)); ++ skipblanks(&b, b + strlen(b)); + + int diff = find_unit_order (a) - find_unit_order (b); + return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); +@@ -1974,7 +2318,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int @@ -2993,7 +3449,7 @@ Index: src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b +@@ -1984,6 +2328,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3019,7 +3475,7 @@ Index: src/sort.c /* Work around a problem whereby the long double value returned by glibc's strtold ("NaN", ...) contains uninitialized bits: clear all bytes of A and B before calling strtold. FIXME: remove this function once -@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char +@@ -2034,7 +2397,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -3028,7 +3484,7 @@ Index: src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, stru +@@ -2310,15 +2673,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0'; @@ -3046,16 +3502,16 @@ Index: src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gke - bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) - && !(key->schar || key->echar); +@@ -2452,7 +2814,7 @@ key_warnings (struct keyfield const *gke + /* 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 */ -- if (!gkey_only && tab == TAB_DEFAULT && !line_offset -+ if (!gkey_only && !tab_length && !line_offset - && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) +- if (!zero_width && !gkey_only && tab == TAB_DEFAULT && !line_offset ++ if (!zero_width && !gkey_only && !tab_length && !line_offset + && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gke +@@ -2510,11 +2872,87 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -3144,7 +3600,7 @@ Index: src/sort.c { struct keyfield *key = keylist; -@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct +@@ -2599,7 +3037,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3153,7 +3609,7 @@ Index: src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2695,6 +3135,211 @@ keycompare (struct line const *a, struct +@@ -2715,6 +3153,211 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3365,7 +3821,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. */ -@@ -2722,7 +3367,7 @@ compare (struct line const *a, struct li +@@ -2742,7 +3385,7 @@ compare (struct line const *a, struct li diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3374,7 +3830,7 @@ Index: src/sort.c { /* Note xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4121,6 +4766,7 @@ set_ordering (char const *s, struct keyf +@@ -4139,6 +4782,7 @@ set_ordering (char const *s, struct keyf break; case 'f': key->translate = fold_toupper; @@ -3382,7 +3838,7 @@ Index: src/sort.c break; case 'g': key->general_numeric = true; -@@ -4199,7 +4845,7 @@ main (int argc, char **argv) +@@ -4218,7 +4862,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3391,7 +3847,7 @@ Index: src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4220,6 +4866,29 @@ main (int argc, char **argv) +@@ -4239,6 +4883,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3421,7 +3877,7 @@ Index: src/sort.c have_read_stdin = false; inittables (); -@@ -4494,13 +5163,34 @@ main (int argc, char **argv) +@@ -4513,13 +5180,34 @@ main (int argc, char **argv) case 't': { @@ -3431,7 +3887,7 @@ Index: src/sort.c + size_t newtab_length = 1; + strncpy (newtab, optarg, MB_LEN_MAX); + if (! newtab[0]) - error (SORT_FAILURE, 0, _("empty tab")); + die (SORT_FAILURE, 0, _("empty tab")); - if (optarg[1]) +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) @@ -3460,22 +3916,21 @@ Index: src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4511,9 +5201,12 @@ main (int argc, char **argv) - quote (optarg)); +@@ -4530,9 +5218,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)) - error (SORT_FAILURE, 0, _("incompatible tabs")); ++ if (tab_length && (tab_length != newtab_length ++ || memcmp (tab, newtab, tab_length) != 0)) + die (SORT_FAILURE, 0, _("incompatible tabs")); - tab = newtab; + memcpy (tab, newtab, newtab_length); + tab_length = newtab_length; } break; -@@ -4751,12 +5444,10 @@ main (int argc, char **argv) +@@ -4770,12 +5460,10 @@ main (int argc, char **argv) sort (files, nfiles, outfile, nthreads); } @@ -3487,266 +3942,213 @@ Index: src/sort.c -#endif if (have_read_stdin && fclose (stdin) == EOF) - die (_("close failed"), "-"); + sort_die (_("close failed"), "-"); Index: src/unexpand.c =================================================================== --- src/unexpand.c.orig +++ src/unexpand.c -@@ -38,12 +38,29 @@ +@@ -38,6 +38,9 @@ #include #include #include + -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ -+#if HAVE_WCHAR_H -+# include -+#endif ++#include + #include "system.h" - #include "error.h" - #include "fadvise.h" - #include "quote.h" + #include "die.h" #include "xstrndup.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 -+# 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 -+ - /* The official name of this program (e.g., no 'g' prefix). */ - #define PROGRAM_NAME "unexpand" - -@@ -103,6 +120,210 @@ static struct option const longopts[] = - {NULL, 0, NULL, 0} - }; - -+static FILE *next_file (FILE *fp); -+ -+#if HAVE_MBRTOWC -+static void -+unexpand_multibyte (void) -+{ -+ FILE *fp; /* Input stream. */ -+ mbstate_t i_state; /* Current shift state of the input stream. */ -+ mbstate_t i_state_bak; /* Back up the I_STATE. */ -+ mbstate_t o_state; /* Current shift state of the output stream. */ -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ char *bufpos = buf; /* Next read position of BUF. */ -+ size_t buflen = 0; /* The length of the byte sequence in 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. */ -+ bool prev_tab = false; -+ -+ /* Index in `tab_list' of next tabstop: */ -+ int tab_index = 0; /* For calculating width of pending tabs. */ -+ int print_tab_index = 0; /* For printing as many tabs as possible. */ -+ unsigned int column = 0; /* Column on screen of next char. */ -+ int next_tab_column; /* Column the next tab stop is on. */ -+ int convert = 1; /* If nonzero, perform translations. */ -+ unsigned int pending = 0; /* Pending columns of blanks. */ -+ -+ fp = next_file ((FILE *) NULL); -+ if (fp == NULL) -+ return; -+ -+ memset (&o_state, '\0', sizeof(mbstate_t)); -+ memset (&i_state, '\0', sizeof(mbstate_t)); -+ -+ for (;;) -+ { -+ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) -+ { -+ memmove (buf, bufpos, buflen); -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); -+ bufpos = buf; -+ } -+ -+ /* Get a wide character. */ -+ if (buflen < 1) -+ { -+ mblength = 1; -+ wc = WEOF; -+ } -+ else -+ { -+ i_state_bak = i_state; -+ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &i_state); -+ } -+ -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ i_state = i_state_bak; -+ wc = L'\0'; -+ } -+ -+ if (wc == L' ' && convert && column < INT_MAX) -+ { -+ ++pending; -+ ++column; -+ } -+ else if (wc == L'\t' && convert) -+ { -+ if (tab_size == 0) -+ { -+ /* Do not let tab_index == first_free_tab; -+ stop when it is 1 less. */ -+ while (tab_index < first_free_tab - 1 -+ && column >= tab_list[tab_index]) -+ tab_index++; -+ next_tab_column = tab_list[tab_index]; -+ if (tab_index < first_free_tab - 1) -+ tab_index++; -+ if (column >= next_tab_column) -+ { -+ convert = 0; /* Ran out of tab stops. */ -+ goto flush_pend_mb; -+ } -+ } -+ else -+ { -+ next_tab_column = column + tab_size - column % tab_size; -+ } -+ pending += next_tab_column - column; -+ column = next_tab_column; -+ } -+ else -+ { -+flush_pend_mb: -+ /* Flush pending spaces. Print as many tabs as possible, -+ then print the rest as spaces. */ -+ if (pending == 1 && column != 1 && !prev_tab) -+ { -+ putchar (' '); -+ pending = 0; -+ } -+ column -= pending; -+ while (pending > 0) -+ { -+ if (tab_size == 0) -+ { -+ /* Do not let print_tab_index == first_free_tab; -+ stop when it is 1 less. */ -+ while (print_tab_index < first_free_tab - 1 -+ && column >= tab_list[print_tab_index]) -+ print_tab_index++; -+ next_tab_column = tab_list[print_tab_index]; -+ if (print_tab_index < first_free_tab - 1) -+ print_tab_index++; -+ } -+ else -+ { -+ next_tab_column = -+ column + tab_size - column % tab_size; -+ } -+ if (next_tab_column - column <= pending) -+ { -+ putchar ('\t'); -+ pending -= next_tab_column - column; -+ column = next_tab_column; -+ } -+ else -+ { -+ --print_tab_index; -+ column += pending; -+ while (pending != 0) -+ { -+ putchar (' '); -+ pending--; -+ } -+ } -+ } -+ -+ if (wc == WEOF) -+ { -+ fp = next_file (fp); -+ if (fp == NULL) -+ break; /* No more files. */ -+ else -+ { -+ memset (&i_state, '\0', sizeof(mbstate_t)); -+ continue; -+ } -+ } -+ -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ if (convert) -+ { -+ ++column; -+ if (convert_entire_line == 0) -+ convert = 0; -+ } -+ mblength = 1; -+ putchar (buf[0]); -+ } -+ else if (mblength == 0) -+ { -+ if (convert && convert_entire_line == 0) -+ convert = 0; -+ mblength = 1; -+ putchar ('\0'); -+ } -+ else -+ { -+ if (convert) -+ { -+ if (wc == L'\b') -+ { -+ if (column > 0) -+ --column; -+ } -+ else -+ { -+ int width; /* The width of WC. */ -+ -+ width = wcwidth (wc); -+ column += (width > 0) ? width : 0; -+ if (convert_entire_line == 0) -+ convert = 0; -+ } -+ } -+ -+ if (wc == L'\n') -+ { -+ tab_index = print_tab_index = 0; -+ column = pending = 0; -+ convert = 1; -+ } -+ fwrite (bufpos, sizeof(char), mblength, stdout); -+ } -+ } -+ prev_tab = wc == L'\t'; -+ buflen -= mblength; -+ bufpos += mblength; -+ } -+} -+#endif -+ -+ - void - usage (int status) +@@ -107,24 +110,47 @@ unexpand (void) { -@@ -523,7 +744,12 @@ main (int argc, char **argv) + /* Input stream. */ + FILE *fp = next_file (NULL); ++ mb_file_t mbf; - file_list = (optind < argc ? &argv[optind] : stdin_argv); + /* The array of pending blanks. In non-POSIX locales, blanks can + include characters other than spaces, so the blanks must be + stored, not merely counted. */ +- char *pending_blank; ++ mbf_char_t *pending_blank; ++ /* True if the starting locale is utf8. */ ++ bool using_utf_locale; ++ ++ /* True if the first file contains BOM header. */ ++ bool found_bom; ++ using_utf_locale=check_utf_locale(); -- unexpand (); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ unexpand_multibyte (); -+ else -+#endif -+ unexpand (); + if (!fp) + 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")); ++ } ++ } + /* The worst case is a non-blank character, then one blank, then a + tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so + allocate MAX_COLUMN_WIDTH bytes to store the blanks. */ +- pending_blank = xmalloc (max_column_width); ++ pending_blank = xmalloc (max_column_width * sizeof (mbf_char_t)); ++ ++ if (found_bom == true) ++ { ++ print_bom(); ++ } + + while (true) + { + /* Input character, or EOF. */ +- int c; ++ mbf_char_t c; + + /* If true, perform translations. */ + bool convert = true; +@@ -158,12 +184,44 @@ unexpand (void) + + do + { +- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) +- continue; ++ while (true) { ++ mbf_getc (c, mbf); ++ if ((mb_iseof (c)) && (fp = next_file (fp))) ++ { ++ mbf_init (mbf, fp); ++ if (fp!=NULL) ++ { ++ if (check_bom(fp,&mbf)==true) ++ { ++ /*Not the first file - check BOM header*/ ++ if (using_utf_locale==false && found_bom==false) ++ { ++ /*BOM header in subsequent file but not in the first one. */ ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); ++ } ++ } ++ else ++ { ++ if(using_utf_locale==false && found_bom==true) ++ { ++ /*First file conatined BOM header - locale was switched to UTF ++ /*all subsequent files should contain BOM. */ ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); ++ } ++ } ++ } ++ continue; ++ } ++ else ++ { ++ break; ++ } ++ } ++ + + if (convert) + { +- bool blank = !! isblank (c); ++ bool blank = mb_isblank (c); + + if (blank) + { +@@ -180,16 +238,16 @@ unexpand (void) + if (next_tab_column < column) + die (EXIT_FAILURE, 0, _("input line is too long")); + +- if (c == '\t') ++ if (mb_iseq (c, '\t')) + { + column = next_tab_column; + + if (pending) +- pending_blank[0] = '\t'; ++ mb_setascii (&pending_blank[0], '\t'); + } + else + { +- column++; ++ column += mb_width (c); + + if (! (prev_blank && column == next_tab_column)) + { +@@ -197,13 +255,14 @@ unexpand (void) + will be replaced by tabs. */ + if (column == next_tab_column) + one_blank_before_tab_stop = true; +- pending_blank[pending++] = c; ++ mb_copy (&pending_blank[pending++], &c); + prev_blank = true; + continue; + } + + /* Replace the pending blanks by a tab or two. */ +- pending_blank[0] = c = '\t'; ++ mb_setascii (&c, '\t'); ++ mb_setascii (&pending_blank[0], '\t'); + } + + /* Discard pending blanks, unless it was a single +@@ -211,7 +270,7 @@ unexpand (void) + pending = one_blank_before_tab_stop; + } + } +- else if (c == '\b') ++ else if (mb_iseq (c, '\b')) + { + /* Go back one column, and force recalculation of the + next tab stop. */ +@@ -219,9 +278,9 @@ unexpand (void) + next_tab_column = column; + tab_index -= !!tab_index; + } +- else ++ else if (!mb_iseq (c, '\n')) + { +- column++; ++ column += mb_width (c); + if (!column) + die (EXIT_FAILURE, 0, _("input line is too long")); + } +@@ -229,8 +288,11 @@ unexpand (void) + if (pending) + { + if (pending > 1 && one_blank_before_tab_stop) +- pending_blank[0] = '\t'; +- if (fwrite (pending_blank, 1, pending, stdout) != pending) ++ mb_setascii (&pending_blank[0], '\t'); ++ ++ for (int n = 0; n < pending; ++n) ++ mb_putc (pending_blank[n], stdout); ++ if (ferror (stdout)) + die (EXIT_FAILURE, errno, _("write error")); + pending = 0; + one_blank_before_tab_stop = false; +@@ -240,16 +302,17 @@ unexpand (void) + convert &= convert_entire_line || blank; + } + +- if (c < 0) ++ if (mb_iseof (c)) + { + free (pending_blank); + return; + } + +- if (putchar (c) < 0) ++ mb_putc (c, stdout); ++ if (ferror (stdout)) + die (EXIT_FAILURE, errno, _("write error")); + } +- while (c != '\n'); ++ while (!mb_iseq (c, '\n')); + } + } - if (have_read_stdin && fclose (stdin) != 0) - error (EXIT_FAILURE, errno, "-"); Index: src/uniq.c =================================================================== --- src/uniq.c.orig @@ -3769,12 +4171,14 @@ Index: src/uniq.c #include "system.h" #include "argmatch.h" #include "linebuffer.h" -@@ -33,6 +44,18 @@ +@@ -32,9 +43,21 @@ + #include "stdio--.h" + #include "xmemcoll.h" #include "xstrtol.h" - #include "memcasecmp.h" - #include "quote.h" +-#include "memcasecmp.h" +#include "xmemcoll.h" -+ + #include "quote.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 @@ -3785,10 +4189,12 @@ Index: src/uniq.c +#if HAVE_MBRTOWC && defined mbstate_t +# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) +#endif - ++ ++ /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "uniq" -@@ -143,6 +166,10 @@ enum + +@@ -144,6 +167,10 @@ enum GROUP_OPTION = CHAR_MAX + 1 }; @@ -3799,7 +4205,7 @@ Index: src/uniq.c static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *m +@@ -260,7 +287,7 @@ size_opt (char const *opt, char const *m return a pointer to the beginning of the line's field to be compared. */ static char * _GL_ATTRIBUTE_PURE @@ -3808,7 +4214,7 @@ Index: src/uniq.c { size_t count; char const *lp = line->buffer; -@@ -272,6 +299,83 @@ find_field (struct linebuffer const *lin +@@ -280,6 +307,83 @@ find_field (struct linebuffer const *lin return line->buffer + i; } @@ -3892,7 +4298,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. -@@ -280,6 +384,8 @@ find_field (struct linebuffer const *lin +@@ -288,6 +392,8 @@ find_field (struct linebuffer const *lin static bool different (char *old, char *new, size_t oldlen, size_t newlen) { @@ -3901,7 +4307,7 @@ Index: src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -287,15 +393,104 @@ different (char *old, char *new, size_t +@@ -295,15 +401,104 @@ different (char *old, char *new, size_t if (ignore_case) { @@ -4011,7 +4417,7 @@ Index: src/uniq.c /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. MATCH is true if the line matches the previous line. -@@ -359,19 +554,38 @@ check_file (const char *infile, const ch +@@ -367,19 +562,38 @@ check_file (const char *infile, const ch char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); bool first_group_printed = false; @@ -4050,7 +4456,7 @@ Index: src/uniq.c new_group = (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)); -@@ -389,6 +603,10 @@ check_file (const char *infile, const ch +@@ -397,6 +611,10 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -4061,7 +4467,7 @@ Index: src/uniq.c first_group_printed = true; } } -@@ -401,17 +619,26 @@ check_file (const char *infile, const ch +@@ -409,17 +627,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -4088,7 +4494,7 @@ Index: src/uniq.c if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -420,6 +647,14 @@ check_file (const char *infile, const ch +@@ -428,6 +655,14 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -4103,7 +4509,7 @@ Index: src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -452,6 +687,9 @@ check_file (const char *infile, const ch +@@ -460,6 +695,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -4113,7 +4519,7 @@ Index: src/uniq.c if (!match) match_count = 0; } -@@ -498,6 +736,19 @@ main (int argc, char **argv) +@@ -506,6 +744,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -4133,45 +4539,194 @@ Index: src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -Index: tests/i18n/sort-month.sh +Index: tests/expand/mb.sh =================================================================== --- /dev/null -+++ tests/i18n/sort-month.sh -@@ -0,0 +1,34 @@ ++++ tests/expand/mb.sh +@@ -0,0 +1,183 @@ +#!/bin/sh -+# Verify sort -M multi-byte support. ++ ++# Copyright (C) 2012-2015 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program 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 General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ sort -+require_valgrind_ -+ -+# Skip this test if some deallocations are -+# avoided at process end. -+grep '^#define lint 1' $CONFIG_HEADER > /dev/null || -+ skip_ 'Allocation checks only work reliably in "lint" mode' ++print_ver_ expand + +export LC_ALL=en_US.UTF-8 -+locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ -+ || skip_ "No UTF-8 locale available" + -+# Note the use of ɑ here which expands to -+# a wider representation upon case conversion -+# which triggered an assertion in sort -M -+cat < exp -+. -+ɑ ++#input containing multibyte characters ++cat <<\EOF > in || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++EOF ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ ++ ++cat <<\EOF > exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#multiple files as an input ++cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++expand ./in ./in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#test characters with display widths != 1 ++env printf '12345678 ++e\t|ascii(1) ++\u00E9\t|composed(1) ++e\u0301\t|decomposed(1) ++\u3000\t|ideo-space(2) ++\uFF0D\t|full-hypen(2) ++' > in || framework_failure_ ++ ++env printf '12345678 ++e |ascii(1) ++\u00E9 |composed(1) ++e\u0301 |decomposed(1) ++\u3000 |ideo-space(2) ++\uFF0D |full-hypen(2) ++' > exp || framework_failure_ ++ ++expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#shouldn't fail with "input line too long" ++#when a line starts with a control character ++env printf '\n' > in || framework_failure_ ++ ++expand < in > out || fail=1 ++compare in out > /dev/null 2>&1 || fail=1 ++ ++#non-Unicode characters interspersed between Unicode ones ++env printf '12345678 ++\t\xFF| ++\xFF\t| ++\t\xFFä| ++ä\xFF\t| ++\tä\xFF| ++\xFF\tä| ++äbcdef\xFF\t| ++' > in || framework_failure_ ++ ++env printf '12345678 ++ \xFF| ++\xFF | ++ \xFFä| ++ä\xFF | ++ ä\xFF| ++\xFF ä| ++äbcdef\xFF | ++' > exp || framework_failure_ ++ ++expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++ ++ ++#BOM header test 1 ++printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++EOF ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ ++ ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx +EOF + + -+# check large mem leak with --month-sort -+# https://bugzilla.redhat.com/show_bug.cgi?id=1259942 -+valgrind --leak-check=full \ -+ --error-exitcode=1 --errors-for-leak-kinds=definite \ -+ sort -M < exp > out || fail=1 -+compare exp out || { fail=1; cat out; } ++expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LANG=C expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LC_ALL=C expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 + + -+Exit $fail ++printf '\xEF\xBB\xBF' > in1; cat <<\EOF >> in1 || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++EOF ++env printf ' äöü\t. öüä. \tä xx\n' >> in1 || framework_failure_ ++ ++ ++printf '\xEF\xBB\xBF' > exp; cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++expand in1 in1 > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LANG=C expand in1 in1 > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LC_ALL=C expand in1 in1 > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++exit $fail Index: tests/i18n/sort.sh =================================================================== --- /dev/null @@ -4210,16 +4765,31 @@ Index: tests/local.mk =================================================================== --- tests/local.mk.orig +++ tests/local.mk -@@ -344,6 +344,9 @@ all_tests = \ +@@ -350,6 +350,8 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ + tests/misc/sort-mb-tests.sh \ + tests/i18n/sort.sh \ -+ tests/i18n/sort-month.sh \ + tests/misc/sort-h-thousands-sep.sh \ tests/misc/sort-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ - tests/misc/sort-month.sh \ +@@ -542,6 +544,7 @@ all_tests = \ + tests/du/threshold.sh \ + tests/du/trailing-slash.sh \ + tests/du/two-args.sh \ ++ tests/expand/mb.sh \ + tests/id/gnu-zero-uids.sh \ + tests/id/no-context.sh \ + tests/id/context.sh \ +@@ -682,6 +685,7 @@ all_tests = \ + tests/touch/read-only.sh \ + tests/touch/relative.sh \ + tests/touch/trailing-slash.sh \ ++ tests/unexpand/mb.sh \ + $(all_root_tests) + + # See tests/factor/create-test.sh. Index: tests/misc/cut.pl =================================================================== --- tests/misc/cut.pl.orig @@ -4250,7 +4820,7 @@ Index: tests/misc/expand.pl =================================================================== --- tests/misc/expand.pl.orig +++ tests/misc/expand.pl -@@ -23,6 +23,15 @@ use strict; +@@ -27,6 +27,15 @@ my $prog = 'expand'; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4266,8 +4836,17 @@ Index: tests/misc/expand.pl my @Tests = ( ['t1', '--tabs=3', {IN=>"a\tb"}, {OUT=>"a b"}], -@@ -31,6 +40,37 @@ my @Tests = - ['i2', '--tabs=3 -i', {IN=>" \ta\tb"}, {OUT=>" a\tb"}], +@@ -140,6 +149,8 @@ my @Tests = + + + # Test errors ++ # FIXME: The following tests contain ‘quoting’ specific to LC_MESSAGES ++ # So we force LC_MESSAGES=C to make them pass. + ['e1', '--tabs="a"', {IN=>''}, {OUT=>''}, {EXIT=>1}, + {ERR => "$prog: tab size contains invalid character(s): 'a'\n"}], + ['e2', "-t $UINTMAX_OFLOW", {IN=>''}, {OUT=>''}, {EXIT=>1}, +@@ -150,6 +161,37 @@ my @Tests = + {ERR => "$prog: tab sizes must be ascending\n"}], ); +if ($mb_locale ne 'C') @@ -4293,7 +4872,7 @@ Index: tests/misc/expand.pl + push @new_t, $sub; + push @$t, $sub; + } -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; ++ push @new, ["$test_name-mb", @new_t, {ENV => "LANG=$mb_locale LC_MESSAGES=C"}]; + } + push @Tests, @new; + } @@ -4644,8 +5223,8 @@ Index: tests/misc/unexpand.pl my @Tests = ( ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], -@@ -92,6 +100,37 @@ my @Tests = - {EXIT => 1}, {ERR => "$prog: tab stop value is too large\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') @@ -4778,9 +5357,9 @@ Index: tests/pr/pr-tests.pl my @tv = ( # -b option is no longer an official option. But it's still working to -@@ -467,8 +476,48 @@ push @Tests, - {IN=>{3=>"x\ty\tz\n"}}, - {OUT=>join("\t", qw(a b c m n o x y z)) . "\n"} ]; +@@ -474,8 +483,48 @@ push @Tests, + {IN=>{2=>"a\n"}}, + {OUT=>"a\t\t\t\t \t\t\ta\n"} ]; +# Add _POSIX2_VERSION=199209 to the environment of each test +# that uses an old-style option like +1. @@ -4808,7 +5387,7 @@ Index: tests/pr/pr-tests.pl + push @$t, $sub; + } + #temporarily skip some failing tests -+ next if ($test_name =~ "col-0" or $test_name =~ "col-inval"); ++ 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; @@ -4827,3 +5406,180 @@ Index: tests/pr/pr-tests.pl my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; +Index: tests/unexpand/mb.sh +=================================================================== +--- /dev/null ++++ tests/unexpand/mb.sh +@@ -0,0 +1,172 @@ ++#!/bin/sh ++ ++# Copyright (C) 2012-2015 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program 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 General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ unexpand ++ ++export LC_ALL=en_US.UTF-8 ++ ++#input containing multibyte characters ++cat > in <<\EOF ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++cat > exp <<\EOF ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++unexpand -a < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++ ++#multiple files as an input ++cat >> exp <<\EOF ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++ ++unexpand -a ./in ./in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#test characters with a display width larger than 1 ++ ++env printf '12345678 ++e |ascii(1) ++\u00E9 |composed(1) ++e\u0301 |decomposed(1) ++\u3000 |ideo-space(2) ++\uFF0D |full-hypen(2) ++' > in || framework_failure_ ++ ++env printf '12345678 ++e\t|ascii(1) ++\u00E9\t|composed(1) ++e\u0301\t|decomposed(1) ++\u3000\t|ideo-space(2) ++\uFF0D\t|full-hypen(2) ++' > exp || framework_failure_ ++ ++unexpand -a < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#test input where a blank of width > 1 is not being substituted ++in="$(LC_ALL=en_US.UTF-8 printf ' \u3000 ö ü ß')" ++exp='   ö ü ß' ++ ++unexpand -a < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#non-Unicode characters interspersed between Unicode ones ++env printf '12345678 ++ \xFF| ++\xFF | ++ \xFFä| ++ä\xFF | ++ ä\xFF| ++\xFF ä| ++äbcdef\xFF | ++' > in || framework_failure_ ++ ++env printf '12345678 ++\t\xFF| ++\xFF\t| ++\t\xFFä| ++ä\xFF\t| ++\tä\xFF| ++\xFF\tä| ++äbcdef\xFF\t| ++' > exp || framework_failure_ ++ ++unexpand -a < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#BOM header test 1 ++printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ ++ ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++unexpand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LANG=C unexpand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LC_ALL=C unexpand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++ ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++ ++unexpand in in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LANG=C unexpand in in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LC_ALL=C unexpand in in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 diff --git a/coreutils-invalid-ids.patch b/coreutils-invalid-ids.patch index d3981bc..c715835 100644 --- a/coreutils-invalid-ids.patch +++ b/coreutils-invalid-ids.patch @@ -19,12 +19,12 @@ Index: src/chgrp.c =================================================================== --- src/chgrp.c.orig +++ src/chgrp.c -@@ -88,7 +88,7 @@ parse_group (const char *name) +@@ -89,7 +89,7 @@ parse_group (const char *name) { unsigned long int tmp; if (! (xstrtoul (name, NULL, 10, &tmp, "") == LONGINT_OK - && tmp <= GID_T_MAX)) + && tmp <= GID_T_MAX && (gid_t) tmp != (gid_t) -1)) - error (EXIT_FAILURE, 0, _("invalid group: %s"), - quote (name)); + die (EXIT_FAILURE, 0, _("invalid group: %s"), + quote (name)); gid = tmp; diff --git a/coreutils-m5sum-sha-sum-fix-ignore-missing-with-00-checksums.patch b/coreutils-m5sum-sha-sum-fix-ignore-missing-with-00-checksums.patch deleted file mode 100644 index fd45a13..0000000 --- a/coreutils-m5sum-sha-sum-fix-ignore-missing-with-00-checksums.patch +++ /dev/null @@ -1,157 +0,0 @@ -Upstream patch to fix "md5sum --check --ignore-missing" which treated -files with checksums starting with "00" as missing. -To be removed with coreutils > v8.25. - -Test case illustrating the issue: - - $ echo 559 > file - - $ md5sum file | tee file.md5 - 000b64c5d808b7ae98718d6a191325b7 file - -With the file being intact, md5sum previously issued a misleading error -diagnostic, and returned with exit code 1. - - $ md5sum -c --ignore-missing file.md5; echo $? - md5sum: file.md5: no file was verified - 1 - -With the file being changed, md5sum still detected the changed file ("FAILED"), -but still stated that the file was not checked; at least the exit code was okay. - - $ echo tampered >> file - - $ md5sum -c --ignore-missing file.md5; echo $? - file: FAILED - md5sum: WARNING: 1 computed checksum did NOT match - md5sum: file.md5: no file was verified - 1 - -Original patch: -http://git.sv.gnu.org/cgit/coreutils.git/commit/?id=d0ddfadfb27de - -From d0ddfadfb27def2861f35b1a45190a4c1780b257 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Wed, 26 Oct 2016 15:45:01 +0100 -Subject: [PATCH] md5sum,sha*sum: fix --ignore-missing with checksums starting - with 00 - -* NEWS: Mention the fix. -* src/md5sum.c (digest_file): Add a new MISSING parameter to -return whether the file was missing, separately from the digest. -* tests/misc/md5sum.pl: Add a test case. -Fixes http://bugs.gnu.org/24795 ---- - NEWS | 4 ++++ - src/md5sum.c | 20 ++++++++++++-------- - tests/misc/md5sum.pl | 7 +++++++ - 3 files changed, 23 insertions(+), 8 deletions(-) - -Index: NEWS -=================================================================== ---- NEWS.orig -+++ NEWS -@@ -11,6 +11,10 @@ GNU coreutils NEWS - df now filters the system mount list more efficiently, with 20000 - mount entries now being processed in about 1.1s compared to 1.7s. - -+ md5sum --check --ignore-missing no longer treats files with checksums -+ starting with "00" as missing. This also affects sha*sum. -+ [bug introduced with the --ignore-missing feature in coreutils-8.25] -+ - - * Noteworthy changes in release 8.25 (2016-01-20) [stable] - -Index: src/md5sum.c -=================================================================== ---- src/md5sum.c.orig -+++ src/md5sum.c -@@ -462,15 +462,19 @@ print_filename (char const *file, bool e - text because it was a terminal. - - Put the checksum in *BIN_RESULT, which must be properly aligned. -+ Put true in *MISSING if the file can't be opened due to ENOENT. - Return true if successful. */ - - static bool --digest_file (const char *filename, int *binary, unsigned char *bin_result) -+digest_file (const char *filename, int *binary, unsigned char *bin_result, -+ bool *missing) - { - FILE *fp; - int err; - bool is_stdin = STREQ (filename, "-"); - -+ *missing = false; -+ - if (is_stdin) - { - have_read_stdin = true; -@@ -490,7 +494,7 @@ digest_file (const char *filename, int * - { - if (ignore_missing && errno == ENOENT) - { -- *bin_result = '\0'; -+ *missing = true; - return true; - } - error (0, errno, "%s", quotef (filename)); -@@ -603,14 +607,14 @@ digest_check (const char *checkfile_name - '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f' }; - bool ok; -+ bool missing; - /* Only escape in the edge case producing multiple lines, - to ease automatic processing of status output. */ - bool needs_escape = ! status_only && strchr (filename, '\n'); - - properly_formatted_lines = true; - -- *bin_buffer = '\1'; /* flag set to 0 for ignored missing files. */ -- ok = digest_file (filename, &binary, bin_buffer); -+ ok = digest_file (filename, &binary, bin_buffer, &missing); - - if (!ok) - { -@@ -623,10 +627,9 @@ digest_check (const char *checkfile_name - printf (": %s\n", _("FAILED open or read")); - } - } -- else if (ignore_missing && ! *bin_buffer) -+ else if (ignore_missing && missing) - { -- /* Treat an empty buffer as meaning a missing file, -- which is ignored with --ignore-missing. */ -+ /* Ignore missing files with --ignore-missing. */ - ; - } - else -@@ -876,8 +879,9 @@ main (int argc, char **argv) - else - { - int file_is_binary = binary; -+ bool missing; - -- if (! digest_file (file, &file_is_binary, bin_buffer)) -+ if (! digest_file (file, &file_is_binary, bin_buffer, &missing)) - ok = false; - else - { -Index: tests/misc/md5sum.pl -=================================================================== ---- tests/misc/md5sum.pl.orig -+++ tests/misc/md5sum.pl -@@ -149,6 +149,13 @@ my @Tests = - {ERR=> - "md5sum: f.md5: no file was verified\n"}, - {EXIT=> 1}], -+ # coreutils-8.25 with --ignore-missing treated checksums starting with 00 -+ # as if the file was not present -+ ['check-ignore-missing-6', '--check', '--ignore-missing', -+ {AUX=> {f=> '9t'}}, -+ {IN=> {'f.md5' => -+ "006999e6df389641adf1fa3a74801d9d f\n"}}, -+ {OUT=>"f: OK\n"}], - ['bsd-segv', '--check', {IN=> {'z' => "MD5 ("}}, {EXIT=> 1}, - {ERR=> "$prog: z: no properly formatted MD5 checksum lines found\n"}], - diff --git a/coreutils-maint-fix-dependency-of-man-arch.1.patch b/coreutils-maint-fix-dependency-of-man-arch.1.patch deleted file mode 100644 index 0605eff..0000000 --- a/coreutils-maint-fix-dependency-of-man-arch.1.patch +++ /dev/null @@ -1,70 +0,0 @@ -Upstream patch to fix the build dependency between src/arch -> man/arch.1; -to be removed with coreutils > v8.25. - -Downstream addition: -* Propagate the change from local.mk to Makefile.in, which is done -upstreams by autoconf. - -Original patch: -http://git.sv.gnu.org/cgit/coreutils.git/commit/?id=a69e54cfdf7e - -From a69e54cfdf7e5d8c2c3fe315ded649272d7e8711 Mon Sep 17 00:00:00 2001 -From: Bernhard Voelker -Date: Tue, 26 Jul 2016 20:58:08 +0200 -Subject: [PATCH] maint: fix dependency of man/arch.1 - -The following is a reproducer for the wrong dependency: - - $ ./configure --enable-install-program=arch - $ make - $ rm -f src/arch man/arch.1 - $ make man/arch.1 - GEN man/arch.1 - help2man: can't get `--help' info from man/arch.td/arch - Try `--no-discard-stderr' if option outputs to stderr - Makefile:14378: recipe for target 'man/arch.1' failed - make: *** [man/arch.1] Error 127 - -* man/local.mk (man/arch.1): Change to depend on src/arch rather than -src/uname: while the arch binary depends on uname.c and uname-arch.c, -its man page depends on the arch binary. - -Reported downstream by Rodrigues Goldwyn in -https://build.opensuse.org/request/show/415172 ---- - Makefile.in | 2 +- - man/local.mk | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -Index: man/local.mk -=================================================================== ---- man/local.mk.orig -+++ man/local.mk -@@ -56,10 +56,10 @@ if SINGLE_BINARY - mandeps += src/coreutils$(EXEEXT) - else - # Most prog.1 man pages depend on src/prog. List the exceptions: --man/arch.1: src/uname$(EXEEXT) - man/install.1: src/ginstall$(EXEEXT) - man/test.1: src/[$(EXEEXT) - -+man/arch.1: src/arch$(EXEEXT) - man/base32.1: src/base32$(EXEEXT) - man/base64.1: src/base64$(EXEEXT) - man/basename.1: src/basename$(EXEEXT) -Index: Makefile.in -=================================================================== ---- Makefile.in.orig -+++ Makefile.in -@@ -14276,10 +14276,10 @@ distclean-local: - - $(ALL_MANS): $(mandeps) - # Most prog.1 man pages depend on src/prog. List the exceptions: --@SINGLE_BINARY_FALSE@man/arch.1: src/uname$(EXEEXT) - @SINGLE_BINARY_FALSE@man/install.1: src/ginstall$(EXEEXT) - @SINGLE_BINARY_FALSE@man/test.1: src/[$(EXEEXT) - -+@SINGLE_BINARY_FALSE@man/arch.1: src/arch$(EXEEXT) - @SINGLE_BINARY_FALSE@man/base32.1: src/base32$(EXEEXT) - @SINGLE_BINARY_FALSE@man/base64.1: src/base64$(EXEEXT) - @SINGLE_BINARY_FALSE@man/basename.1: src/basename$(EXEEXT) diff --git a/coreutils-ocfs2_reflinks.patch b/coreutils-ocfs2_reflinks.patch index aef3a14..89fef3b 100644 --- a/coreutils-ocfs2_reflinks.patch +++ b/coreutils-ocfs2_reflinks.patch @@ -18,7 +18,7 @@ Index: src/copy.c =================================================================== --- src/copy.c.orig +++ src/copy.c -@@ -315,6 +315,47 @@ sparse_copy (int src_fd, int dest_fd, ch +@@ -324,6 +324,47 @@ sparse_copy (int src_fd, int dest_fd, ch return true; } @@ -66,7 +66,7 @@ Index: src/copy.c /* Perform the O(1) btrfs clone operation, if possible. Upon success, return 0. Otherwise, return -1 and set errno. */ static inline int -@@ -1049,6 +1090,45 @@ copy_reg (char const *src_name, char con +@@ -1054,6 +1095,45 @@ copy_reg (char const *src_name, char con goto close_src_desc; } @@ -112,7 +112,7 @@ Index: src/copy.c /* The semantics of the following open calls are mandated by the specs for both cp and mv. */ if (! *new_dst) -@@ -1192,7 +1272,7 @@ copy_reg (char const *src_name, char con +@@ -1197,7 +1277,7 @@ copy_reg (char const *src_name, char con } /* --attributes-only overrides --reflink. */ diff --git a/coreutils-remove_hostname_documentation.patch b/coreutils-remove_hostname_documentation.patch index 87aa9e9..831b5aa 100644 --- a/coreutils-remove_hostname_documentation.patch +++ b/coreutils-remove_hostname_documentation.patch @@ -6,7 +6,7 @@ Index: doc/coreutils.texi =================================================================== --- doc/coreutils.texi.orig +++ doc/coreutils.texi -@@ -69,7 +69,6 @@ +@@ -70,7 +70,6 @@ * groups: (coreutils)groups invocation. Print group names a user is in. * head: (coreutils)head invocation. Output the first part of files. * hostid: (coreutils)hostid invocation. Print numeric host identifier. @@ -14,7 +14,7 @@ Index: doc/coreutils.texi * id: (coreutils)id invocation. Print user identity. * install: (coreutils)install invocation. Copy files and set attributes. * join: (coreutils)join invocation. Join lines on a common field. -@@ -201,7 +200,7 @@ Free Documentation License''. +@@ -202,7 +201,7 @@ Free Documentation License''. * File name manipulation:: dirname basename pathchk mktemp realpath * Working context:: pwd stty printenv tty * User information:: id logname whoami groups users who @@ -23,7 +23,7 @@ Index: doc/coreutils.texi * SELinux context:: chcon runcon * Modified command invocation:: chroot env nice nohup stdbuf timeout * Process control:: kill -@@ -421,7 +420,6 @@ System context +@@ -423,7 +422,6 @@ System context * date invocation:: Print or set system date and time * nproc invocation:: Print the number of processors * uname invocation:: Print system information @@ -31,7 +31,7 @@ Index: doc/coreutils.texi * hostid invocation:: Print numeric host identifier * uptime invocation:: Print system uptime and load -@@ -14986,7 +14984,6 @@ information. +@@ -15073,7 +15071,6 @@ information. * arch invocation:: Print machine hardware name. * nproc invocation:: Print the number of processors. * uname invocation:: Print system information. @@ -39,7 +39,7 @@ Index: doc/coreutils.texi * hostid invocation:: Print numeric host identifier. * uptime invocation:: Print system uptime and load. @end menu -@@ -15815,15 +15812,6 @@ Note this is non-portable (even across G +@@ -15912,15 +15909,6 @@ Note this is non-portable (even across G Print the machine hardware name (sometimes called the hardware class or hardware type). @@ -55,7 +55,7 @@ Index: doc/coreutils.texi @item -p @itemx --processor @opindex -p -@@ -15877,34 +15865,6 @@ Print the kernel version. +@@ -15974,34 +15962,6 @@ Print the kernel version. @exitstatus diff --git a/coreutils-remove_kill_documentation.patch b/coreutils-remove_kill_documentation.patch index 83aef30..9bef402 100644 --- a/coreutils-remove_kill_documentation.patch +++ b/coreutils-remove_kill_documentation.patch @@ -6,7 +6,7 @@ Index: doc/coreutils.texi =================================================================== --- doc/coreutils.texi.orig +++ doc/coreutils.texi -@@ -72,7 +72,6 @@ +@@ -73,7 +73,6 @@ * id: (coreutils)id invocation. Print user identity. * install: (coreutils)install invocation. Copy files and set attributes. * join: (coreutils)join invocation. Join lines on a common field. @@ -14,7 +14,7 @@ Index: doc/coreutils.texi * link: (coreutils)link invocation. Make hard links between files. * ln: (coreutils)ln invocation. Make links between files. * logname: (coreutils)logname invocation. Print current login name. -@@ -203,7 +202,6 @@ Free Documentation License''. +@@ -204,7 +203,6 @@ Free Documentation License''. * System context:: date arch nproc uname hostid uptime * SELinux context:: chcon runcon * Modified command invocation:: chroot env nice nohup stdbuf timeout @@ -22,7 +22,7 @@ Index: doc/coreutils.texi * Delaying:: sleep * Numeric operations:: factor numfmt seq * File permissions:: Access modes -@@ -448,10 +446,6 @@ Modified command invocation +@@ -450,10 +448,6 @@ Modified command invocation * stdbuf invocation:: Run a command with modified I/O buffering * timeout invocation:: Run a command with a time limit @@ -33,7 +33,7 @@ Index: doc/coreutils.texi Delaying * sleep invocation:: Delay for a specified time -@@ -16799,90 +16793,6 @@ the exit status of @var{command} otherwi +@@ -16896,90 +16890,6 @@ the exit status of @var{command} otherwi @end display diff --git a/coreutils-skip-gnulib-test-tls.patch b/coreutils-skip-gnulib-test-tls.patch index c102429..d494e5d 100644 --- a/coreutils-skip-gnulib-test-tls.patch +++ b/coreutils-skip-gnulib-test-tls.patch @@ -21,7 +21,7 @@ Index: gnulib-tests/gnulib.mk =================================================================== --- gnulib-tests/gnulib.mk.orig +++ gnulib-tests/gnulib.mk -@@ -2242,9 +2242,10 @@ EXTRA_DIST += test-timespec.c macros.h +@@ -2243,9 +2243,10 @@ EXTRA_DIST += test-timespec.c macros.h ## begin gnulib module tls-tests diff --git a/coreutils-sysinfo.patch b/coreutils-sysinfo.patch index f9452c6..c3fbb74 100644 --- a/coreutils-sysinfo.patch +++ b/coreutils-sysinfo.patch @@ -6,7 +6,7 @@ Index: src/uname.c =================================================================== --- src/uname.c.orig +++ src/uname.c -@@ -337,6 +337,36 @@ main (int argc, char **argv) +@@ -338,6 +338,36 @@ main (int argc, char **argv) # endif } #endif @@ -43,7 +43,7 @@ Index: src/uname.c if (! (toprint == UINT_MAX && element == unknown)) print_element (element); } -@@ -362,6 +392,18 @@ main (int argc, char **argv) +@@ -363,6 +393,18 @@ main (int argc, char **argv) element = hardware_platform; } #endif diff --git a/coreutils-tests-shorten-extreme-factor-tests.patch b/coreutils-tests-shorten-extreme-factor-tests.patch index 1013cbb..9a4f1e9 100644 --- a/coreutils-tests-shorten-extreme-factor-tests.patch +++ b/coreutils-tests-shorten-extreme-factor-tests.patch @@ -16,7 +16,7 @@ Index: tests/local.mk =================================================================== --- tests/local.mk.orig +++ tests/local.mk -@@ -680,14 +680,9 @@ all_tests = \ +@@ -691,14 +691,9 @@ all_tests = \ # See tests/factor/create-test.sh. tf = tests/factor factor_tests = \ diff --git a/coreutils-testsuite.changes b/coreutils-testsuite.changes index 64a0674..2bc5efd 100644 --- a/coreutils-testsuite.changes +++ b/coreutils-testsuite.changes @@ -1,3 +1,28 @@ +------------------------------------------------------------------- +Fri Dec 2 17:17:40 UTC 2016 - mail@bernhard-voelker.de + +- Update to 8.26 + (for details see included NEWS file) +- coreutils.spec (%description): Add b2sum, a new utility. +(BuildRequires): Add timezone to enable new 'date-debug.sh' test. +- coreutils-i18n.patch: Sync I18N patch from Fedora, as the diff + for the old i18n implementation of expand/unexpand has become + unmaintainable: + git://pkgs.fedoraproject.org/coreutils.git +- Remove now-upstream patches: + * coreutils-df-hash-in-filter.patch + * coreutils-diagnose-fts-readdir-failure.patch + * coreutils-m5sum-sha-sum-fix-ignore-missing-with-00-checksums.patch + * coreutils-maint-fix-dependency-of-man-arch.1.patch +- Refresh/merge all other patches: + * coreutils-invalid-ids.patch + * coreutils-ocfs2_reflinks.patch + * coreutils-remove_hostname_documentation.patch + * coreutils-remove_kill_documentation.patch + * coreutils-skip-gnulib-test-tls.patch + * coreutils-sysinfo.patch + * coreutils-tests-shorten-extreme-factor-tests.patch + ------------------------------------------------------------------- Tue Nov 1 09:41:12 UTC 2016 - mail@bernhard-voelker.de diff --git a/coreutils-testsuite.spec b/coreutils-testsuite.spec index 60f9940..eb50ec7 100644 --- a/coreutils-testsuite.spec +++ b/coreutils-testsuite.spec @@ -21,7 +21,7 @@ Summary: GNU Core Utilities License: GPL-3.0+ Group: System/Base Url: http://www.gnu.org/software/coreutils/ -Version: 8.25 +Version: 8.26 Release: 0 ################################################################# @@ -52,6 +52,7 @@ BuildRequires: gdb BuildRequires: perl-Expect BuildRequires: python-pyinotify BuildRequires: strace +BuildRequires: timezone %ifarch %ix86 x86_64 ppc ppc64 s390x armv7l armv7hl BuildRequires: valgrind %endif @@ -128,30 +129,13 @@ Patch303: coreutils-tests-shorten-extreme-factor-tests.patch Patch500: coreutils-disable_tests.patch Patch501: coreutils-test_without_valgrind.patch -# Upstream patch to diagnose readdir() failures in fts-based utilities; -# to be removed with coreutils > v8.25. -Patch700: coreutils-diagnose-fts-readdir-failure.patch - -# Upstream patch to improve df performance with many mount points; -# to be removed with coreutils > v8.25. -Patch705: coreutils-df-hash-in-filter.patch - -# Upstream patch to fix the build dependency between src/arch -> man/arch.1; -# to be removed with coreutils > v8.25. -Patch710: coreutils-maint-fix-dependency-of-man-arch.1.patch - -# Upstream patch to fix "md5sum --check --ignore-missing" which treated -# files with checksums starting with "00" as missing; -# to be removed with coreutils > v8.25. -Patch715: coreutils-m5sum-sha-sum-fix-ignore-missing-with-00-checksums.patch - # ================================================ %description These are the GNU core utilities. This package is the union of the GNU fileutils, sh-utils, and textutils packages. - [ arch base32 base64 basename cat chcon chgrp chmod chown chroot cksum comm - cp csplit cut date dd df dir dircolors dirname du echo env expand expr + [ arch b2sum base32 base64 basename cat chcon chgrp chmod chown chroot cksum + comm cp csplit cut date dd df dir dircolors dirname du echo env expand expr factor false fmt fold groups head hostid id install join link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup nproc numfmt od paste pathchk pinky pr printenv printf ptx pwd readlink @@ -187,11 +171,6 @@ the GNU fileutils, sh-utils, and textutils packages. %patch500 %patch501 -%patch700 -%patch705 -%patch710 -%patch715 - #???## We need to statically link to gmp, otherwise we have a build loop #???#sed -i s,'$(LIB_GMP)',%%{_libdir}/libgmp.a,g Makefile.in @@ -231,7 +210,7 @@ make all %{?_smp_mflags} V=1 %if "%{name}" == "coreutils" make install DESTDIR="%buildroot" pkglibexecdir=%{_libdir}/%{name} -# remove kill +# remove kill - we use that from util-linux. rm -v %{buildroot}%{_bindir}/kill rm -v %{buildroot}/%{_mandir}/man1/kill.1 diff --git a/coreutils.changes b/coreutils.changes index 64a0674..2bc5efd 100644 --- a/coreutils.changes +++ b/coreutils.changes @@ -1,3 +1,28 @@ +------------------------------------------------------------------- +Fri Dec 2 17:17:40 UTC 2016 - mail@bernhard-voelker.de + +- Update to 8.26 + (for details see included NEWS file) +- coreutils.spec (%description): Add b2sum, a new utility. +(BuildRequires): Add timezone to enable new 'date-debug.sh' test. +- coreutils-i18n.patch: Sync I18N patch from Fedora, as the diff + for the old i18n implementation of expand/unexpand has become + unmaintainable: + git://pkgs.fedoraproject.org/coreutils.git +- Remove now-upstream patches: + * coreutils-df-hash-in-filter.patch + * coreutils-diagnose-fts-readdir-failure.patch + * coreutils-m5sum-sha-sum-fix-ignore-missing-with-00-checksums.patch + * coreutils-maint-fix-dependency-of-man-arch.1.patch +- Refresh/merge all other patches: + * coreutils-invalid-ids.patch + * coreutils-ocfs2_reflinks.patch + * coreutils-remove_hostname_documentation.patch + * coreutils-remove_kill_documentation.patch + * coreutils-skip-gnulib-test-tls.patch + * coreutils-sysinfo.patch + * coreutils-tests-shorten-extreme-factor-tests.patch + ------------------------------------------------------------------- Tue Nov 1 09:41:12 UTC 2016 - mail@bernhard-voelker.de diff --git a/coreutils.spec b/coreutils.spec index 6410ed9..23b4021 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -21,7 +21,7 @@ Summary: GNU Core Utilities License: GPL-3.0+ Group: System/Base Url: http://www.gnu.org/software/coreutils/ -Version: 8.25 +Version: 8.26 Release: 0 ################################################################# @@ -52,6 +52,7 @@ BuildRequires: gdb BuildRequires: perl-Expect BuildRequires: python-pyinotify BuildRequires: strace +BuildRequires: timezone %ifarch %ix86 x86_64 ppc ppc64 s390x armv7l armv7hl BuildRequires: valgrind %endif @@ -128,30 +129,13 @@ Patch303: coreutils-tests-shorten-extreme-factor-tests.patch Patch500: coreutils-disable_tests.patch Patch501: coreutils-test_without_valgrind.patch -# Upstream patch to diagnose readdir() failures in fts-based utilities; -# to be removed with coreutils > v8.25. -Patch700: coreutils-diagnose-fts-readdir-failure.patch - -# Upstream patch to improve df performance with many mount points; -# to be removed with coreutils > v8.25. -Patch705: coreutils-df-hash-in-filter.patch - -# Upstream patch to fix the build dependency between src/arch -> man/arch.1; -# to be removed with coreutils > v8.25. -Patch710: coreutils-maint-fix-dependency-of-man-arch.1.patch - -# Upstream patch to fix "md5sum --check --ignore-missing" which treated -# files with checksums starting with "00" as missing; -# to be removed with coreutils > v8.25. -Patch715: coreutils-m5sum-sha-sum-fix-ignore-missing-with-00-checksums.patch - # ================================================ %description These are the GNU core utilities. This package is the union of the GNU fileutils, sh-utils, and textutils packages. - [ arch base32 base64 basename cat chcon chgrp chmod chown chroot cksum comm - cp csplit cut date dd df dir dircolors dirname du echo env expand expr + [ arch b2sum base32 base64 basename cat chcon chgrp chmod chown chroot cksum + comm cp csplit cut date dd df dir dircolors dirname du echo env expand expr factor false fmt fold groups head hostid id install join link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup nproc numfmt od paste pathchk pinky pr printenv printf ptx pwd readlink @@ -187,11 +171,6 @@ the GNU fileutils, sh-utils, and textutils packages. %patch500 %patch501 -%patch700 -%patch705 -%patch710 -%patch715 - #???## We need to statically link to gmp, otherwise we have a build loop #???#sed -i s,'$(LIB_GMP)',%%{_libdir}/libgmp.a,g Makefile.in @@ -231,7 +210,7 @@ make all %{?_smp_mflags} V=1 %if "%{name}" == "coreutils" make install DESTDIR="%buildroot" pkglibexecdir=%{_libdir}/%{name} -# remove kill +# remove kill - we use that from util-linux. rm -v %{buildroot}%{_bindir}/kill rm -v %{buildroot}/%{_mandir}/man1/kill.1