wok-next rev 19735

Update some more receipts to v2: coreutils, attr, libpng16 (former libpng), libpng12, libwebp, libxml2.
author Aleksej Bobylev <al.bobylev@gmail.com>
date Sat May 27 16:55:17 2017 +0300 (2017-05-27)
parents b75a21e7b544
children 11f96bc53c0e
files attr-dev/receipt attr/receipt coreutils-character/description.txt coreutils-character/receipt coreutils-command/description.txt coreutils-command/receipt coreutils-conditions/description.txt coreutils-conditions/receipt coreutils-context-system/description.txt coreutils-context-system/receipt coreutils-context-user/description.txt coreutils-context-user/receipt coreutils-context-working/description.txt coreutils-context-working/receipt coreutils-directory/description.txt coreutils-directory/receipt coreutils-disk/description.txt coreutils-disk/receipt coreutils-file-attributes/description.txt coreutils-file-attributes/receipt coreutils-file-format/description.txt coreutils-file-format/receipt coreutils-file-output-full/description.txt coreutils-file-output-full/receipt coreutils-file-output-part/description.txt coreutils-file-output-part/receipt coreutils-file-sort/description.txt coreutils-file-sort/receipt coreutils-file-special/description.txt coreutils-file-special/receipt coreutils-file-summarize/description.txt coreutils-file-summarize/receipt coreutils-line/description.txt coreutils-line/receipt coreutils-numeric/description.txt coreutils-numeric/receipt coreutils-operations/description.txt coreutils-operations/receipt coreutils-path/description.txt coreutils-path/receipt coreutils-print/description.txt coreutils-print/receipt coreutils-redirection/description.txt coreutils-redirection/receipt coreutils/description.coreutils-character.txt coreutils/description.coreutils-command.txt coreutils/description.coreutils-conditions.txt coreutils/description.coreutils-context-system.txt coreutils/description.coreutils-context-user.txt coreutils/description.coreutils-context-working.txt coreutils/description.coreutils-directory.txt coreutils/description.coreutils-disk.txt coreutils/description.coreutils-file-attributes.txt coreutils/description.coreutils-file-format.txt coreutils/description.coreutils-file-output-full.txt coreutils/description.coreutils-file-output-part.txt coreutils/description.coreutils-file-sort.txt coreutils/description.coreutils-file-special.txt coreutils/description.coreutils-file-summarize.txt coreutils/description.coreutils-line.txt coreutils/description.coreutils-numeric.txt coreutils/description.coreutils-operations.txt coreutils/description.coreutils-path.txt coreutils/description.coreutils-print.txt coreutils/description.coreutils-redirection.txt coreutils/description.txt coreutils/receipt coreutils/stuff/coreutils-8.25-i18n-2.patch coreutils/stuff/coreutils-fix-po.patch coreutils/stuff/ls.u coreutils/stuff/patches/README coreutils/stuff/patches/coreutils-8.25-i18n-2.patch coreutils/stuff/patches/coreutils-fix-po.patch coreutils/stuff/patches/series coreutils/stuff/patches/uname.u coreutils/stuff/sigcontext.h coreutils/stuff/uname.u libpng-dev/receipt libpng/receipt libpng12-dev/receipt libpng12/receipt libpng16/receipt libwebp-apps/receipt libwebp-dev/receipt libwebp/receipt libxml2-dev/receipt libxml2-python/receipt libxml2-tools/receipt libxml2/receipt
line diff
     1.1 --- a/attr-dev/receipt	Sat May 27 16:29:45 2017 +0300
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,19 +0,0 @@
     1.4 -# SliTaz package receipt.
     1.5 -
     1.6 -PACKAGE="attr-dev"
     1.7 -VERSION="2.4.47"
     1.8 -CATEGORY="development"
     1.9 -SHORT_DESC="Development files for attr."
    1.10 -MAINTAINER="rcx@zoominternet.net"
    1.11 -LICENSE="GPL2"
    1.12 -WEB_SITE="http://savannah.nongnu.org/projects/attr/"
    1.13 -HOST_ARCH="i486 arm"
    1.14 -
    1.15 -WANTED="attr"
    1.16 -DEPENDS="attr"
    1.17 -
    1.18 -# Rules to gen a SliTaz package suitable for Tazpkg.
    1.19 -genpkg_rules()
    1.20 -{
    1.21 -	cook_copy_files *.h *.la
    1.22 -}
     2.1 --- a/attr/receipt	Sat May 27 16:29:45 2017 +0300
     2.2 +++ b/attr/receipt	Sat May 27 16:55:17 2017 +0300
     2.3 @@ -1,9 +1,9 @@
     2.4 -# SliTaz package receipt.
     2.5 +# SliTaz package receipt v2.
     2.6  
     2.7  PACKAGE="attr"
     2.8  VERSION="2.4.47"
     2.9  CATEGORY="system-tools"
    2.10 -SHORT_DESC="Commands for Manipulating Filesystem Extended Attributes."
    2.11 +SHORT_DESC="Commands for Manipulating Filesystem Extended Attributes"
    2.12  MAINTAINER="rcx@zoominternet.net"
    2.13  LICENSE="GPL2"
    2.14  WEB_SITE="http://savannah.nongnu.org/projects/attr"
    2.15 @@ -12,13 +12,9 @@
    2.16  TARBALL="$PACKAGE-$VERSION.src.tar.gz"
    2.17  WGET_URL="http://download.savannah.gnu.org/releases/$PACKAGE/$TARBALL"
    2.18  
    2.19 -DEPENDS="glibc-base"
    2.20  BUILD_DEPENDS="autoconf automake m4 libtool gettext coreutils-operations"
    2.21 -
    2.22 -# When cross compiling auto-tools, gettext and m4 build system are used.
    2.23 -case "$ARCH" in
    2.24 -	arm) BUILD_DEPENDS="" ;;
    2.25 -esac
    2.26 +BUILD_DEPENDS_arm=" "
    2.27 +SPLIT="attr-dev"
    2.28  
    2.29  # Rules to configure and make the package.
    2.30  compile_rules()
    2.31 @@ -44,6 +40,8 @@
    2.32  # Rules to gen a SliTaz package suitable for Tazpkg.
    2.33  genpkg_rules()
    2.34  {
    2.35 -	cook_copy_folders bin
    2.36 -	cook_copy_files *.so*
    2.37 +	case $PACKAGE in
    2.38 +		attr) copy @std ;;
    2.39 +		attr-dev) copy @dev ;;
    2.40 +	esac
    2.41  }
     3.1 --- a/coreutils-character/description.txt	Sat May 27 16:29:45 2017 +0300
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,5 +0,0 @@
     3.4 -Coreutils: Core GNU (file, text, shell) utilities.
     3.5 -
     3.6 -  * expand:    convert tabs to spaces
     3.7 -  * tr:        translate or delete characters
     3.8 -  * unexpand:  convert spaces to tabs
     4.1 --- a/coreutils-character/receipt	Sat May 27 16:29:45 2017 +0300
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,30 +0,0 @@
     4.4 -# SliTaz package receipt.
     4.5 -
     4.6 -PACKAGE="coreutils-character"
     4.7 -VERSION="8.25"
     4.8 -CATEGORY="system-tools"
     4.9 -SHORT_DESC="GNU utilities that operate on characters."
    4.10 -MAINTAINER="rcx@zoominternet.net"
    4.11 -LICENSE="GPL3"
    4.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
    4.13 -
    4.14 -WANTED="coreutils"
    4.15 -DEPENDS="glibc-base"
    4.16 -
    4.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
    4.18 -genpkg_rules()
    4.19 -{
    4.20 -	cook_copy_files expand tr unexpand
    4.21 -}
    4.22 -
    4.23 -post_remove()
    4.24 -{
    4.25 -	# Restore all Busybox applets that have been replaced
    4.26 -	while read i; do
    4.27 -		busybox ln -s /bin/busybox "$1$i"
    4.28 -	done <<EOT
    4.29 -/usr/bin/expand
    4.30 -/usr/bin/tr
    4.31 -/usr/bin/unexpand
    4.32 -EOT
    4.33 -}
     5.1 --- a/coreutils-command/description.txt	Sat May 27 16:29:45 2017 +0300
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,11 +0,0 @@
     5.4 -Coreutils: Core GNU (file, text, shell) utilities.
     5.5 -
     5.6 -  * chroot:    run command or interactive shell with special root directory
     5.7 -  * env:       run a program in a modified environment
     5.8 -  * kill:      send signals to processes, or list signals
     5.9 -  * nice:      run a program with modified scheduling priority
    5.10 -  * nohup:     run a command immune to hangups, with output to a non-tty
    5.11 -  * sleep:     delay for a specified amount of time
    5.12 -  * stdbuf:    run command with modified buffering operations for its standard
    5.13 -               streams
    5.14 -  * timeout:   run a command with a time limit
     6.1 --- a/coreutils-command/receipt	Sat May 27 16:29:45 2017 +0300
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,43 +0,0 @@
     6.4 -# SliTaz package receipt.
     6.5 -
     6.6 -PACKAGE="coreutils-command"
     6.7 -VERSION="8.25"
     6.8 -CATEGORY="system-tools"
     6.9 -SHORT_DESC="GNU command utilities."
    6.10 -MAINTAINER="rcx@zoominternet.net"
    6.11 -LICENSE="GPL3"
    6.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
    6.13 -
    6.14 -WANTED="coreutils"
    6.15 -DEPENDS="glibc-base"
    6.16 -
    6.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
    6.18 -genpkg_rules()
    6.19 -{
    6.20 -	cook_copy_files env kill nice nohup sleep stdbuf timeout libstdbuf.so chroot
    6.21 -}
    6.22 -
    6.23 -post_install()
    6.24 -{
    6.25 -	# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
    6.26 -	# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
    6.27 -	rm "$1/bin/kill"     # for /usr/bin/kill
    6.28 -	rm "$1/bin/nice"     # for /usr/bin/nice
    6.29 -	rm "$1/bin/sleep"    # for /usr/bin/sleep
    6.30 -}
    6.31 -
    6.32 -post_remove()
    6.33 -{
    6.34 -	# Restore all Busybox applets that have been replaced
    6.35 -	while read i; do
    6.36 -		busybox ln -s /bin/busybox "$1$i"
    6.37 -	done <<EOT
    6.38 -/bin/kill
    6.39 -/bin/nice
    6.40 -/bin/sleep
    6.41 -/usr/bin/env
    6.42 -/usr/bin/nohup
    6.43 -/usr/bin/timeout
    6.44 -/usr/sbin/chroot
    6.45 -EOT
    6.46 -}
     7.1 --- a/coreutils-conditions/description.txt	Sat May 27 16:29:45 2017 +0300
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,7 +0,0 @@
     7.4 -Coreutils: Core GNU (file, text, shell) utilities.
     7.5 -
     7.6 -  * [          exit with the status determined by expression
     7.7 -  * expr:      evaluate expressions
     7.8 -  * false:     do nothing, unsuccessfully
     7.9 -  * test:      check file types and compare values
    7.10 -  * true:      do nothing, successfully
     8.1 --- a/coreutils-conditions/receipt	Sat May 27 16:29:45 2017 +0300
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,32 +0,0 @@
     8.4 -# SliTaz package receipt.
     8.5 -
     8.6 -PACKAGE="coreutils-conditions"
     8.7 -VERSION="8.25"
     8.8 -CATEGORY="system-tools"
     8.9 -SHORT_DESC="GNU utilities for conditions."
    8.10 -MAINTAINER="rcx@zoominternet.net"
    8.11 -LICENSE="GPL3"
    8.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
    8.13 -
    8.14 -WANTED="coreutils"
    8.15 -DEPENDS="glibc-base gmp"
    8.16 -
    8.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
    8.18 -genpkg_rules()
    8.19 -{
    8.20 -	cook_copy_files false true [ expr test
    8.21 -}
    8.22 -
    8.23 -post_remove()
    8.24 -{
    8.25 -	# Restore all Busybox applets that have been replaced
    8.26 -	while read i; do
    8.27 -		busybox ln -s /bin/busybox "$1$i"
    8.28 -	done <<EOT
    8.29 -/bin/false
    8.30 -/bin/true
    8.31 -/usr/bin/[
    8.32 -/usr/bin/expr
    8.33 -/usr/bin/test
    8.34 -EOT
    8.35 -}
     9.1 --- a/coreutils-context-system/description.txt	Sat May 27 16:29:45 2017 +0300
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,9 +0,0 @@
     9.4 -Coreutils: Core GNU (file, text, shell) utilities.
     9.5 -
     9.6 -  * chcon:     change file SELinux security context
     9.7 -  * date:      print or set the system date and time
     9.8 -  * hostid:    print the numeric identifier for the current host
     9.9 -  * nproc:     print the number of processing units available
    9.10 -  * runcon:    run command with specified SELinux security context
    9.11 -  * uname:     print system information
    9.12 -  * uptime:    tell how long the system has been running
    10.1 --- a/coreutils-context-system/receipt	Sat May 27 16:29:45 2017 +0300
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,31 +0,0 @@
    10.4 -# SliTaz package receipt.
    10.5 -
    10.6 -PACKAGE="coreutils-context-system"
    10.7 -VERSION="8.25"
    10.8 -CATEGORY="system-tools"
    10.9 -SHORT_DESC="GNU utilities related to the system context."
   10.10 -MAINTAINER="rcx@zoominternet.net"
   10.11 -LICENSE="GPL3"
   10.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   10.13 -
   10.14 -WANTED="coreutils"
   10.15 -DEPENDS="glibc-base"
   10.16 -
   10.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   10.18 -genpkg_rules()
   10.19 -{
   10.20 -	cook_copy_files date uname chcon hostid nproc runcon uptime
   10.21 -}
   10.22 -
   10.23 -post_remove()
   10.24 -{
   10.25 -	# Restore all Busybox applets that have been replaced
   10.26 -	while read i; do
   10.27 -		busybox ln -s /bin/busybox "$1$i"
   10.28 -	done <<EOT
   10.29 -/bin/date
   10.30 -/bin/uname
   10.31 -/usr/bin/hostid
   10.32 -/usr/bin/uptime
   10.33 -EOT
   10.34 -}
    11.1 --- a/coreutils-context-user/description.txt	Sat May 27 16:29:45 2017 +0300
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,10 +0,0 @@
    11.4 -Coreutils: Core GNU (file, text, shell) utilities.
    11.5 -
    11.6 -  * groups:    print the groups a user is in
    11.7 -  * id:        print real and effective user and group IDs
    11.8 -  * logname:   print user's login name
    11.9 -  * pinky:     lightweight finger
   11.10 -  * users:     print the user names of users currently logged in to the current
   11.11 -               host
   11.12 -  * who:       show who is logged on
   11.13 -  * whoami:    print effective user ID
    12.1 --- a/coreutils-context-user/receipt	Sat May 27 16:29:45 2017 +0300
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,33 +0,0 @@
    12.4 -# SliTaz package receipt.
    12.5 -
    12.6 -PACKAGE="coreutils-context-user"
    12.7 -VERSION="8.25"
    12.8 -CATEGORY="system-tools"
    12.9 -SHORT_DESC="GNU utilities related to the user context."
   12.10 -MAINTAINER="rcx@zoominternet.net"
   12.11 -LICENSE="GPL3"
   12.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   12.13 -
   12.14 -WANTED="coreutils"
   12.15 -DEPENDS="glibc-base"
   12.16 -
   12.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   12.18 -genpkg_rules()
   12.19 -{
   12.20 -	cook_copy_files groups id logname pinky users who whoami
   12.21 -}
   12.22 -
   12.23 -post_remove()
   12.24 -{
   12.25 -	# Restore all Busybox applets that have been replaced
   12.26 -	while read i; do
   12.27 -		busybox ln -s /bin/busybox "$1$i"
   12.28 -	done <<EOT
   12.29 -/usr/bin/groups
   12.30 -/usr/bin/id
   12.31 -/usr/bin/logname
   12.32 -/usr/bin/users
   12.33 -/usr/bin/who
   12.34 -/usr/bin/whoami
   12.35 -EOT
   12.36 -}
    13.1 --- a/coreutils-context-working/description.txt	Sat May 27 16:29:45 2017 +0300
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,6 +0,0 @@
    13.4 -Coreutils: Core GNU (file, text, shell) utilities.
    13.5 -
    13.6 -  * printenv:  print all or part of environment
    13.7 -  * pwd:       print name of current/working directory
    13.8 -  * stty:      change and print terminal line settings
    13.9 -  * tty:       print the file name of the terminal connected to standard input
    14.1 --- a/coreutils-context-working/receipt	Sat May 27 16:29:45 2017 +0300
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,38 +0,0 @@
    14.4 -# SliTaz package receipt.
    14.5 -
    14.6 -PACKAGE="coreutils-context-working"
    14.7 -VERSION="8.25"
    14.8 -CATEGORY="system-tools"
    14.9 -SHORT_DESC="GNU utilities related to the working context."
   14.10 -MAINTAINER="rcx@zoominternet.net"
   14.11 -LICENSE="GPL3"
   14.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   14.13 -
   14.14 -WANTED="coreutils"
   14.15 -DEPENDS="glibc-base"
   14.16 -
   14.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   14.18 -genpkg_rules()
   14.19 -{
   14.20 -	cook_copy_files pwd stty printenv tty
   14.21 -}
   14.22 -
   14.23 -post_install()
   14.24 -{
   14.25 -	# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
   14.26 -	# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
   14.27 -	rm "$1/bin/printenv" # for /usr/bin/printenv
   14.28 -}
   14.29 -
   14.30 -post_remove()
   14.31 -{
   14.32 -	# Restore all Busybox applets that have been replaced
   14.33 -	while read i; do
   14.34 -		busybox ln -s /bin/busybox "$1$i"
   14.35 -	done <<EOT
   14.36 -/bin/printenv
   14.37 -/bin/pwd
   14.38 -/bin/stty
   14.39 -/usr/bin/tty
   14.40 -EOT
   14.41 -}
    15.1 --- a/coreutils-directory/description.txt	Sat May 27 16:29:45 2017 +0300
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,6 +0,0 @@
    15.4 -Coreutils: Core GNU (file, text, shell) utilities.
    15.5 -
    15.6 -  * dir:       list directory contents
    15.7 -  * dircolors: color setup for ls
    15.8 -  * ls:        list directory contents
    15.9 -  * vdir:      list directory contents
    16.1 --- a/coreutils-directory/receipt	Sat May 27 16:29:45 2017 +0300
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,28 +0,0 @@
    16.4 -# SliTaz package receipt.
    16.5 -
    16.6 -PACKAGE="coreutils-directory"
    16.7 -VERSION="8.25"
    16.8 -CATEGORY="system-tools"
    16.9 -SHORT_DESC="GNU utilities that list directories."
   16.10 -MAINTAINER="rcx@zoominternet.net"
   16.11 -LICENSE="GPL3"
   16.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   16.13 -
   16.14 -WANTED="coreutils"
   16.15 -DEPENDS="glibc-base attr libcap"
   16.16 -
   16.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   16.18 -genpkg_rules()
   16.19 -{
   16.20 -	cook_copy_files ls dir dircolors vdir
   16.21 -}
   16.22 -
   16.23 -post_remove()
   16.24 -{
   16.25 -	# Restore all Busybox applets that have been replaced
   16.26 -	while read i; do
   16.27 -		busybox ln -s /bin/busybox "$1$i"
   16.28 -	done <<EOT
   16.29 -/bin/ls
   16.30 -EOT
   16.31 -}
    17.1 --- a/coreutils-disk/description.txt	Sat May 27 16:29:45 2017 +0300
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,7 +0,0 @@
    17.4 -Coreutils: Core GNU (file, text, shell) utilities.
    17.5 -
    17.6 -  * df:        report file system disk space usage
    17.7 -  * du:        estimate file space usage
    17.8 -  * stat:      display file or file system status
    17.9 -  * sync:      synchronize cached writes to persistent storage
   17.10 -  * truncate:  shrink or extend the size of a file to the specified size
    18.1 --- a/coreutils-disk/receipt	Sat May 27 16:29:45 2017 +0300
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,38 +0,0 @@
    18.4 -# SliTaz package receipt.
    18.5 -
    18.6 -PACKAGE="coreutils-disk"
    18.7 -VERSION="8.25"
    18.8 -CATEGORY="system-tools"
    18.9 -SHORT_DESC="GNU utilities that work with disks."
   18.10 -MAINTAINER="rcx@zoominternet.net"
   18.11 -LICENSE="GPL3"
   18.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   18.13 -
   18.14 -WANTED="coreutils"
   18.15 -DEPENDS="glibc-base"
   18.16 -
   18.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   18.18 -genpkg_rules()
   18.19 -{
   18.20 -	cook_copy_files df sync du stat truncate
   18.21 -}
   18.22 -
   18.23 -post_install()
   18.24 -{
   18.25 -	# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
   18.26 -	# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
   18.27 -	rm "$1/bin/stat"     # for /usr/bin/stat
   18.28 -}
   18.29 -
   18.30 -post_remove()
   18.31 -{
   18.32 -	# Restore all Busybox applets that have been replaced
   18.33 -	while read i; do
   18.34 -		busybox ln -s /bin/busybox "$1$i"
   18.35 -	done <<EOT
   18.36 -/bin/df
   18.37 -/bin/stat
   18.38 -/bin/sync
   18.39 -/usr/bin/du
   18.40 -EOT
   18.41 -}
    19.1 --- a/coreutils-file-attributes/description.txt	Sat May 27 16:29:45 2017 +0300
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,6 +0,0 @@
    19.4 -Coreutils: Core GNU (file, text, shell) utilities.
    19.5 -
    19.6 -  * chgrp:     change group ownership
    19.7 -  * chmod:     change file mode bits
    19.8 -  * chown:     change file owner and group
    19.9 -  * touch:     change file timestamps
    20.1 --- a/coreutils-file-attributes/receipt	Sat May 27 16:29:45 2017 +0300
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,38 +0,0 @@
    20.4 -# SliTaz package receipt.
    20.5 -
    20.6 -PACKAGE="coreutils-file-attributes"
    20.7 -VERSION="8.25"
    20.8 -CATEGORY="system-tools"
    20.9 -SHORT_DESC="GNU utilities that change file attributes."
   20.10 -MAINTAINER="rcx@zoominternet.net"
   20.11 -LICENSE="GPL3"
   20.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   20.13 -
   20.14 -WANTED="coreutils"
   20.15 -DEPENDS="glibc-base"
   20.16 -
   20.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   20.18 -genpkg_rules()
   20.19 -{
   20.20 -	cook_copy_files chgrp chmod chown touch
   20.21 -}
   20.22 -
   20.23 -post_install()
   20.24 -{
   20.25 -	# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
   20.26 -	# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
   20.27 -	rm "$1/bin/touch"    # for /usr/bin/touch
   20.28 -}
   20.29 -
   20.30 -post_remove()
   20.31 -{
   20.32 -	# Restore all Busybox applets that have been replaced
   20.33 -	while read i; do
   20.34 -		busybox ln -s /bin/busybox "$1$i"
   20.35 -	done <<EOT
   20.36 -/bin/chgrp
   20.37 -/bin/chmod
   20.38 -/bin/chown
   20.39 -/bin/touch
   20.40 -EOT
   20.41 -}
    21.1 --- a/coreutils-file-format/description.txt	Sat May 27 16:29:45 2017 +0300
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,5 +0,0 @@
    21.4 -Coreutils: Core GNU (file, text, shell) utilities.
    21.5 -
    21.6 -  * fmt:       simple optimal text formatter
    21.7 -  * fold:      wrap each input line to fit in specified width
    21.8 -  * pr:        convert text files for printing
    22.1 --- a/coreutils-file-format/receipt	Sat May 27 16:29:45 2017 +0300
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,28 +0,0 @@
    22.4 -# SliTaz package receipt.
    22.5 -
    22.6 -PACKAGE="coreutils-file-format"
    22.7 -VERSION="8.25"
    22.8 -CATEGORY="system-tools"
    22.9 -SHORT_DESC="GNU utilities that format file contents."
   22.10 -MAINTAINER="rcx@zoominternet.net"
   22.11 -LICENSE="GPL3"
   22.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   22.13 -
   22.14 -WANTED="coreutils"
   22.15 -DEPENDS="glibc-base"
   22.16 -
   22.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   22.18 -genpkg_rules()
   22.19 -{
   22.20 -	cook_copy_files fmt fold pr
   22.21 -}
   22.22 -
   22.23 -post_remove()
   22.24 -{
   22.25 -	# Restore all Busybox applets that have been replaced
   22.26 -	while read i; do
   22.27 -		busybox ln -s /bin/busybox "$1$i"
   22.28 -	done <<EOT
   22.29 -/usr/bin/fold
   22.30 -EOT
   22.31 -}
    23.1 --- a/coreutils-file-output-full/description.txt	Sat May 27 16:29:45 2017 +0300
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,8 +0,0 @@
    23.4 -Coreutils: Core GNU (file, text, shell) utilities.
    23.5 -
    23.6 -  * base32:    base32 encode/decode data and print to standard output
    23.7 -  * base64:    base64 encode/decode data and print to standard output
    23.8 -  * cat:       concatenate files and print on the standard output
    23.9 -  * nl:        number lines of files
   23.10 -  * od:        dump files in octal and other formats
   23.11 -  * tac:       concatenate and print files in reverse
    24.1 --- a/coreutils-file-output-full/receipt	Sat May 27 16:29:45 2017 +0300
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,38 +0,0 @@
    24.4 -# SliTaz package receipt.
    24.5 -
    24.6 -PACKAGE="coreutils-file-output-full"
    24.7 -VERSION="8.25"
    24.8 -CATEGORY="system-tools"
    24.9 -SHORT_DESC="GNU utilities that output entire files."
   24.10 -MAINTAINER="rcx@zoominternet.net"
   24.11 -LICENSE="GPL3"
   24.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   24.13 -
   24.14 -WANTED="coreutils"
   24.15 -DEPENDS="glibc-base"
   24.16 -
   24.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   24.18 -genpkg_rules()
   24.19 -{
   24.20 -	cook_copy_files cat base32 base64 nl od tac
   24.21 -}
   24.22 -
   24.23 -post_install()
   24.24 -{
   24.25 -	# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
   24.26 -	# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
   24.27 -	rm "$1/bin/base64"   # for /usr/bin/base64
   24.28 -}
   24.29 -
   24.30 -post_remove()
   24.31 -{
   24.32 -	# Restore all Busybox applets that have been replaced
   24.33 -	while read i; do
   24.34 -		busybox ln -s /bin/busybox "$1$i"
   24.35 -	done <<EOT
   24.36 -/bin/base64
   24.37 -/bin/cat
   24.38 -/usr/bin/od
   24.39 -/usr/bin/tac
   24.40 -EOT
   24.41 -}
    25.1 --- a/coreutils-file-output-part/description.txt	Sat May 27 16:29:45 2017 +0300
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,6 +0,0 @@
    25.4 -Coreutils: Core GNU (file, text, shell) utilities.
    25.5 -
    25.6 -  * csplit:    split a file into sections determined by context lines
    25.7 -  * head:      output the first part of files
    25.8 -  * split:     split a file into pieces
    25.9 -  * tail:      output the last part of files
    26.1 --- a/coreutils-file-output-part/receipt	Sat May 27 16:29:45 2017 +0300
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,30 +0,0 @@
    26.4 -# SliTaz package receipt.
    26.5 -
    26.6 -PACKAGE="coreutils-file-output-part"
    26.7 -VERSION="8.25"
    26.8 -CATEGORY="system-tools"
    26.9 -SHORT_DESC="GNU utilities that output file parts."
   26.10 -MAINTAINER="rcx@zoominternet.net"
   26.11 -LICENSE="GPL3"
   26.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   26.13 -
   26.14 -WANTED="coreutils"
   26.15 -DEPENDS="glibc-base"
   26.16 -
   26.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   26.18 -genpkg_rules()
   26.19 -{
   26.20 -	cook_copy_files csplit head split tail
   26.21 -}
   26.22 -
   26.23 -post_remove()
   26.24 -{
   26.25 -	# Restore all Busybox applets that have been replaced
   26.26 -	while read i; do
   26.27 -		busybox ln -s /bin/busybox "$1$i"
   26.28 -	done <<EOT
   26.29 -/usr/bin/head
   26.30 -/usr/bin/split
   26.31 -/usr/bin/tail
   26.32 -EOT
   26.33 -}
    27.1 --- a/coreutils-file-sort/description.txt	Sat May 27 16:29:45 2017 +0300
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,8 +0,0 @@
    27.4 -Coreutils: Core GNU (file, text, shell) utilities.
    27.5 -
    27.6 -  * comm:      compare two sorted files line by line
    27.7 -  * ptx:       produce a permuted index of file contents
    27.8 -  * shuf:      generate random permutations
    27.9 -  * sort:      sort lines of text files
   27.10 -  * tsort:     perform topological sort
   27.11 -  * uniq:      report or omit repeated lines
    28.1 --- a/coreutils-file-sort/receipt	Sat May 27 16:29:45 2017 +0300
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,30 +0,0 @@
    28.4 -# SliTaz package receipt.
    28.5 -
    28.6 -PACKAGE="coreutils-file-sort"
    28.7 -VERSION="8.25"
    28.8 -CATEGORY="system-tools"
    28.9 -SHORT_DESC="GNU utilities that operate on sorted files."
   28.10 -MAINTAINER="rcx@zoominternet.net"
   28.11 -LICENSE="GPL3"
   28.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   28.13 -
   28.14 -WANTED="coreutils"
   28.15 -DEPENDS="glibc-base"
   28.16 -
   28.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   28.18 -genpkg_rules()
   28.19 -{
   28.20 -	cook_copy_files comm ptx shuf sort tsort uniq
   28.21 -}
   28.22 -
   28.23 -post_remove()
   28.24 -{
   28.25 -	# Restore all Busybox applets that have been replaced
   28.26 -	while read i; do
   28.27 -		busybox ln -s /bin/busybox "$1$i"
   28.28 -	done <<EOT
   28.29 -/usr/bin/comm
   28.30 -/usr/bin/sort
   28.31 -/usr/bin/uniq
   28.32 -EOT
   28.33 -}
    29.1 --- a/coreutils-file-special/description.txt	Sat May 27 16:29:45 2017 +0300
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,12 +0,0 @@
    29.4 -Coreutils: Core GNU (file, text, shell) utilities.
    29.5 -
    29.6 -  * link:      call the link function to create a link to a file
    29.7 -  * ln:        make links between files
    29.8 -  * mkdir:     make directories
    29.9 -  * mkfifo:    make FIFOs (named pipes)
   29.10 -  * mknod:     make block or character special files
   29.11 -  * mktemp:    create a temporary file or directory
   29.12 -  * readlink:  print resolved symbolic links or canonical file names
   29.13 -  * realpath:  print the resolved path
   29.14 -  * rmdir:     remove empty directories
   29.15 -  * unlink:    call the unlink function to remove the specified file
    30.1 --- a/coreutils-file-special/receipt	Sat May 27 16:29:45 2017 +0300
    30.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.3 @@ -1,42 +0,0 @@
    30.4 -# SliTaz package receipt.
    30.5 -
    30.6 -PACKAGE="coreutils-file-special"
    30.7 -VERSION="8.25"
    30.8 -CATEGORY="system-tools"
    30.9 -SHORT_DESC="GNU utilities that work with special file types."
   30.10 -MAINTAINER="rcx@zoominternet.net"
   30.11 -LICENSE="GPL3"
   30.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   30.13 -
   30.14 -WANTED="coreutils"
   30.15 -DEPENDS="glibc-base"
   30.16 -
   30.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   30.18 -genpkg_rules()
   30.19 -{
   30.20 -	cook_copy_files ln mkdir mknod rmdir link mkfifo mktemp readlink realpath \
   30.21 -		unlink
   30.22 -}
   30.23 -
   30.24 -post_install()
   30.25 -{
   30.26 -	# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
   30.27 -	# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
   30.28 -	rm "$1/bin/mktemp"   # for /usr/bin/mktemp
   30.29 -}
   30.30 -
   30.31 -post_remove()
   30.32 -{
   30.33 -	# Restore all Busybox applets that have been replaced
   30.34 -	while read i; do
   30.35 -		busybox ln -s /bin/busybox "$1$i"
   30.36 -	done <<EOT
   30.37 -/bin/ln
   30.38 -/bin/mkdir
   30.39 -/bin/mknod
   30.40 -/bin/mktemp
   30.41 -/bin/rmdir
   30.42 -/usr/bin/mkfifo
   30.43 -/usr/bin/realpath
   30.44 -EOT
   30.45 -}
    31.1 --- a/coreutils-file-summarize/description.txt	Sat May 27 16:29:45 2017 +0300
    31.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.3 @@ -1,11 +0,0 @@
    31.4 -Coreutils: Core GNU (file, text, shell) utilities.
    31.5 -
    31.6 -  * cksum:     checksum and count the bytes in a file
    31.7 -  * md5sum:    compute and check MD5 message digest
    31.8 -  * sha1sum:   compute and check SHA1 message digest
    31.9 -  * sha224sum: compute and check SHA224 message digest
   31.10 -  * sha256sum: compute and check SHA256 message digest
   31.11 -  * sha384sum: compute and check SHA384 message digest
   31.12 -  * sha512sum: compute and check SHA512 message digest
   31.13 -  * sum:       checksum and count the blocks in a file
   31.14 -  * wc:        print newline, word, and byte counts for each file
    32.1 --- a/coreutils-file-summarize/receipt	Sat May 27 16:29:45 2017 +0300
    32.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.3 @@ -1,35 +0,0 @@
    32.4 -# SliTaz package receipt.
    32.5 -
    32.6 -PACKAGE="coreutils-file-summarize"
    32.7 -VERSION="8.25"
    32.8 -CATEGORY="system-tools"
    32.9 -SHORT_DESC="GNU utilities that summarize files."
   32.10 -MAINTAINER="rcx@zoominternet.net"
   32.11 -LICENSE="GPL3"
   32.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   32.13 -
   32.14 -WANTED="coreutils"
   32.15 -DEPENDS="glibc-base"
   32.16 -
   32.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   32.18 -genpkg_rules()
   32.19 -{
   32.20 -	cook_copy_files cksum md5sum sha1sum sha224sum sha256sum sha384sum \
   32.21 -		sha512sum sum wc
   32.22 -}
   32.23 -
   32.24 -post_remove()
   32.25 -{
   32.26 -	# Restore all Busybox applets that have been replaced
   32.27 -	while read i; do
   32.28 -		busybox ln -s /bin/busybox "$1$i"
   32.29 -	done <<EOT
   32.30 -/usr/bin/cksum
   32.31 -/usr/bin/md5sum
   32.32 -/usr/bin/sha1sum
   32.33 -/usr/bin/sha256sum
   32.34 -/usr/bin/sha512sum
   32.35 -/usr/bin/sum
   32.36 -/usr/bin/wc
   32.37 -EOT
   32.38 -}
    33.1 --- a/coreutils-line/description.txt	Sat May 27 16:29:45 2017 +0300
    33.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.3 @@ -1,5 +0,0 @@
    33.4 -Coreutils: Core GNU (file, text, shell) utilities.
    33.5 -
    33.6 -  * cut:       remove sections from each line of files
    33.7 -  * join:      join lines of two files on a common field
    33.8 -  * paste:     merge lines of files
    34.1 --- a/coreutils-line/receipt	Sat May 27 16:29:45 2017 +0300
    34.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.3 @@ -1,28 +0,0 @@
    34.4 -# SliTaz package receipt.
    34.5 -
    34.6 -PACKAGE="coreutils-line"
    34.7 -VERSION="8.25"
    34.8 -CATEGORY="system-tools"
    34.9 -SHORT_DESC="GNU utilities that operate on fields within a line."
   34.10 -MAINTAINER="rcx@zoominternet.net"
   34.11 -LICENSE="GPL3"
   34.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   34.13 -
   34.14 -WANTED="coreutils"
   34.15 -DEPENDS="glibc-base"
   34.16 -
   34.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   34.18 -genpkg_rules()
   34.19 -{
   34.20 -	cook_copy_files cut join paste
   34.21 -}
   34.22 -
   34.23 -post_remove()
   34.24 -{
   34.25 -	# Restore all Busybox applets that have been replaced
   34.26 -	while read i; do
   34.27 -		busybox ln -s /bin/busybox "$1$i"
   34.28 -	done <<EOT
   34.29 -/usr/bin/cut
   34.30 -EOT
   34.31 -}
    35.1 --- a/coreutils-numeric/description.txt	Sat May 27 16:29:45 2017 +0300
    35.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.3 @@ -1,4 +0,0 @@
    35.4 -Coreutils: Core GNU (file, text, shell) utilities.
    35.5 -
    35.6 -  * factor:    factor numbers
    35.7 -  * seq:       print a sequence of numbers
    36.1 --- a/coreutils-numeric/receipt	Sat May 27 16:29:45 2017 +0300
    36.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.3 @@ -1,28 +0,0 @@
    36.4 -# SliTaz package receipt.
    36.5 -
    36.6 -PACKAGE="coreutils-numeric"
    36.7 -VERSION="8.25"
    36.8 -CATEGORY="system-tools"
    36.9 -SHORT_DESC="GNU numeric utilities."
   36.10 -MAINTAINER="rcx@zoominternet.net"
   36.11 -LICENSE="GPL3"
   36.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   36.13 -
   36.14 -WANTED="coreutils"
   36.15 -DEPENDS="glibc-base gmp"
   36.16 -
   36.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   36.18 -genpkg_rules()
   36.19 -{
   36.20 -	cook_copy_files factor seq
   36.21 -}
   36.22 -
   36.23 -post_remove()
   36.24 -{
   36.25 -	# Restore all Busybox applets that have been replaced
   36.26 -	while read i; do
   36.27 -		busybox ln -s /bin/busybox "$1$i"
   36.28 -	done <<EOT
   36.29 -/usr/bin/seq
   36.30 -EOT
   36.31 -}
    37.1 --- a/coreutils-operations/description.txt	Sat May 27 16:29:45 2017 +0300
    37.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.3 @@ -1,7 +0,0 @@
    37.4 -Coreutils: Core GNU (file, text, shell) utilities.
    37.5 -
    37.6 -  * cp:        copy files and directories
    37.7 -  * dd:        convert and copy a file
    37.8 -  * install:   copy files and set attributes
    37.9 -  * mv:        move (rename) files
   37.10 -  * shred:     overwrite a file to hide its contents, and optionally delete it
    38.1 --- a/coreutils-operations/receipt	Sat May 27 16:29:45 2017 +0300
    38.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.3 @@ -1,31 +0,0 @@
    38.4 -# SliTaz package receipt.
    38.5 -
    38.6 -PACKAGE="coreutils-operations"
    38.7 -VERSION="8.25"
    38.8 -CATEGORY="system-tools"
    38.9 -SHORT_DESC="GNU utilities that perform basic operations."
   38.10 -MAINTAINER="rcx@zoominternet.net"
   38.11 -LICENSE="GPL3"
   38.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   38.13 -
   38.14 -WANTED="coreutils"
   38.15 -DEPENDS="glibc-base acl attr"
   38.16 -
   38.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   38.18 -genpkg_rules()
   38.19 -{
   38.20 -	cook_copy_files cp dd mv install shred
   38.21 -}
   38.22 -
   38.23 -post_remove()
   38.24 -{
   38.25 -	# Restore all Busybox applets that have been replaced
   38.26 -	while read i; do
   38.27 -		busybox ln -s /bin/busybox "$1$i"
   38.28 -	done <<EOT
   38.29 -/bin/cp
   38.30 -/bin/dd
   38.31 -/bin/mv
   38.32 -/usr/bin/install
   38.33 -EOT
   38.34 -}
    39.1 --- a/coreutils-path/description.txt	Sat May 27 16:29:45 2017 +0300
    39.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.3 @@ -1,5 +0,0 @@
    39.4 -Coreutils: Core GNU (file, text, shell) utilities.
    39.5 -
    39.6 -  * basename:  strip directory and suffix from filenames
    39.7 -  * dirname:   strip last component from file name
    39.8 -  * pathchk:   check whether file names are valid or portable
    40.1 --- a/coreutils-path/receipt	Sat May 27 16:29:45 2017 +0300
    40.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.3 @@ -1,29 +0,0 @@
    40.4 -# SliTaz package receipt.
    40.5 -
    40.6 -PACKAGE="coreutils-path"
    40.7 -VERSION="8.25"
    40.8 -CATEGORY="system-tools"
    40.9 -SHORT_DESC="GNU utilities that perform path manipulation."
   40.10 -MAINTAINER="rcx@zoominternet.net"
   40.11 -LICENSE="GPL3"
   40.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   40.13 -
   40.14 -WANTED="coreutils"
   40.15 -DEPENDS="glibc-base"
   40.16 -
   40.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   40.18 -genpkg_rules()
   40.19 -{
   40.20 -	cook_copy_files basename dirname pathchk
   40.21 -}
   40.22 -
   40.23 -post_remove()
   40.24 -{
   40.25 -	# Restore all Busybox applets that have been replaced
   40.26 -	while read i; do
   40.27 -		busybox ln -s /bin/busybox "$1$i"
   40.28 -	done <<EOT
   40.29 -/usr/bin/basename
   40.30 -/usr/bin/dirname
   40.31 -EOT
   40.32 -}
    41.1 --- a/coreutils-print/description.txt	Sat May 27 16:29:45 2017 +0300
    41.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.3 @@ -1,6 +0,0 @@
    41.4 -Coreutils: Core GNU (file, text, shell) utilities.
    41.5 -
    41.6 -  * echo:      display a line of text
    41.7 -  * numfmt:    convert numbers from/to human-readable strings
    41.8 -  * printf:    format and print data
    41.9 -  * yes:       output a string repeatedly until killed
    42.1 --- a/coreutils-print/receipt	Sat May 27 16:29:45 2017 +0300
    42.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.3 @@ -1,30 +0,0 @@
    42.4 -# SliTaz package receipt.
    42.5 -
    42.6 -PACKAGE="coreutils-print"
    42.7 -VERSION="8.25"
    42.8 -CATEGORY="system-tools"
    42.9 -SHORT_DESC="GNU utilities that print text."
   42.10 -MAINTAINER="rcx@zoominternet.net"
   42.11 -LICENSE="GPL3"
   42.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   42.13 -
   42.14 -WANTED="coreutils"
   42.15 -DEPENDS="glibc-base"
   42.16 -
   42.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   42.18 -genpkg_rules()
   42.19 -{
   42.20 -	cook_copy_files echo numfmt printf yes
   42.21 -}
   42.22 -
   42.23 -post_remove()
   42.24 -{
   42.25 -	# Restore all Busybox applets that have been replaced
   42.26 -	while read i; do
   42.27 -		busybox ln -s /bin/busybox "$1$i"
   42.28 -	done <<EOT
   42.29 -/bin/echo
   42.30 -/bin/printf
   42.31 -/bin/yes
   42.32 -EOT
   42.33 -}
    43.1 --- a/coreutils-redirection/description.txt	Sat May 27 16:29:45 2017 +0300
    43.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.3 @@ -1,3 +0,0 @@
    43.4 -Coreutils: Core GNU (file, text, shell) utilities.
    43.5 -
    43.6 -  * tee:       read from standard input and write to standard output and files
    44.1 --- a/coreutils-redirection/receipt	Sat May 27 16:29:45 2017 +0300
    44.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.3 @@ -1,28 +0,0 @@
    44.4 -# SliTaz package receipt.
    44.5 -
    44.6 -PACKAGE="coreutils-redirection"
    44.7 -VERSION="8.25"
    44.8 -CATEGORY="system-tools"
    44.9 -SHORT_DESC="GNU utilities that work with disks."
   44.10 -MAINTAINER="rcx@zoominternet.net"
   44.11 -LICENSE="GPL3"
   44.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   44.13 -
   44.14 -WANTED="coreutils"
   44.15 -DEPENDS="glibc-base"
   44.16 -
   44.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   44.18 -genpkg_rules()
   44.19 -{
   44.20 -	cook_copy_files tee
   44.21 -}
   44.22 -
   44.23 -post_remove()
   44.24 -{
   44.25 -	# Restore all Busybox applets that have been replaced
   44.26 -	while read i; do
   44.27 -		busybox ln -s /bin/busybox "$1$i"
   44.28 -	done <<EOT
   44.29 -/usr/bin/tee
   44.30 -EOT
   44.31 -}
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/coreutils/description.coreutils-character.txt	Sat May 27 16:55:17 2017 +0300
    45.3 @@ -0,0 +1,5 @@
    45.4 +Coreutils: Core GNU (file, text, shell) utilities.
    45.5 +
    45.6 +  * expand:    convert tabs to spaces
    45.7 +  * tr:        translate or delete characters
    45.8 +  * unexpand:  convert spaces to tabs
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/coreutils/description.coreutils-command.txt	Sat May 27 16:55:17 2017 +0300
    46.3 @@ -0,0 +1,11 @@
    46.4 +Coreutils: Core GNU (file, text, shell) utilities.
    46.5 +
    46.6 +  * chroot:    run command or interactive shell with special root directory
    46.7 +  * env:       run a program in a modified environment
    46.8 +  * kill:      send signals to processes, or list signals
    46.9 +  * nice:      run a program with modified scheduling priority
   46.10 +  * nohup:     run a command immune to hangups, with output to a non-tty
   46.11 +  * sleep:     delay for a specified amount of time
   46.12 +  * stdbuf:    run command with modified buffering operations for its standard
   46.13 +               streams
   46.14 +  * timeout:   run a command with a time limit
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/coreutils/description.coreutils-conditions.txt	Sat May 27 16:55:17 2017 +0300
    47.3 @@ -0,0 +1,7 @@
    47.4 +Coreutils: Core GNU (file, text, shell) utilities.
    47.5 +
    47.6 +  * [          exit with the status determined by expression
    47.7 +  * expr:      evaluate expressions
    47.8 +  * false:     do nothing, unsuccessfully
    47.9 +  * test:      check file types and compare values
   47.10 +  * true:      do nothing, successfully
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/coreutils/description.coreutils-context-system.txt	Sat May 27 16:55:17 2017 +0300
    48.3 @@ -0,0 +1,9 @@
    48.4 +Coreutils: Core GNU (file, text, shell) utilities.
    48.5 +
    48.6 +  * chcon:     change file SELinux security context
    48.7 +  * date:      print or set the system date and time
    48.8 +  * hostid:    print the numeric identifier for the current host
    48.9 +  * nproc:     print the number of processing units available
   48.10 +  * runcon:    run command with specified SELinux security context
   48.11 +  * uname:     print system information
   48.12 +  * uptime:    tell how long the system has been running
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/coreutils/description.coreutils-context-user.txt	Sat May 27 16:55:17 2017 +0300
    49.3 @@ -0,0 +1,10 @@
    49.4 +Coreutils: Core GNU (file, text, shell) utilities.
    49.5 +
    49.6 +  * groups:    print the groups a user is in
    49.7 +  * id:        print real and effective user and group IDs
    49.8 +  * logname:   print user's login name
    49.9 +  * pinky:     lightweight finger
   49.10 +  * users:     print the user names of users currently logged in to the current
   49.11 +               host
   49.12 +  * who:       show who is logged on
   49.13 +  * whoami:    print effective user ID
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/coreutils/description.coreutils-context-working.txt	Sat May 27 16:55:17 2017 +0300
    50.3 @@ -0,0 +1,6 @@
    50.4 +Coreutils: Core GNU (file, text, shell) utilities.
    50.5 +
    50.6 +  * printenv:  print all or part of environment
    50.7 +  * pwd:       print name of current/working directory
    50.8 +  * stty:      change and print terminal line settings
    50.9 +  * tty:       print the file name of the terminal connected to standard input
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/coreutils/description.coreutils-directory.txt	Sat May 27 16:55:17 2017 +0300
    51.3 @@ -0,0 +1,6 @@
    51.4 +Coreutils: Core GNU (file, text, shell) utilities.
    51.5 +
    51.6 +  * dir:       list directory contents
    51.7 +  * dircolors: color setup for ls
    51.8 +  * ls:        list directory contents
    51.9 +  * vdir:      list directory contents
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/coreutils/description.coreutils-disk.txt	Sat May 27 16:55:17 2017 +0300
    52.3 @@ -0,0 +1,7 @@
    52.4 +Coreutils: Core GNU (file, text, shell) utilities.
    52.5 +
    52.6 +  * df:        report file system disk space usage
    52.7 +  * du:        estimate file space usage
    52.8 +  * stat:      display file or file system status
    52.9 +  * sync:      synchronize cached writes to persistent storage
   52.10 +  * truncate:  shrink or extend the size of a file to the specified size
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/coreutils/description.coreutils-file-attributes.txt	Sat May 27 16:55:17 2017 +0300
    53.3 @@ -0,0 +1,6 @@
    53.4 +Coreutils: Core GNU (file, text, shell) utilities.
    53.5 +
    53.6 +  * chgrp:     change group ownership
    53.7 +  * chmod:     change file mode bits
    53.8 +  * chown:     change file owner and group
    53.9 +  * touch:     change file timestamps
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/coreutils/description.coreutils-file-format.txt	Sat May 27 16:55:17 2017 +0300
    54.3 @@ -0,0 +1,5 @@
    54.4 +Coreutils: Core GNU (file, text, shell) utilities.
    54.5 +
    54.6 +  * fmt:       simple optimal text formatter
    54.7 +  * fold:      wrap each input line to fit in specified width
    54.8 +  * pr:        convert text files for printing
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/coreutils/description.coreutils-file-output-full.txt	Sat May 27 16:55:17 2017 +0300
    55.3 @@ -0,0 +1,8 @@
    55.4 +Coreutils: Core GNU (file, text, shell) utilities.
    55.5 +
    55.6 +  * base32:    base32 encode/decode data and print to standard output
    55.7 +  * base64:    base64 encode/decode data and print to standard output
    55.8 +  * cat:       concatenate files and print on the standard output
    55.9 +  * nl:        number lines of files
   55.10 +  * od:        dump files in octal and other formats
   55.11 +  * tac:       concatenate and print files in reverse
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/coreutils/description.coreutils-file-output-part.txt	Sat May 27 16:55:17 2017 +0300
    56.3 @@ -0,0 +1,6 @@
    56.4 +Coreutils: Core GNU (file, text, shell) utilities.
    56.5 +
    56.6 +  * csplit:    split a file into sections determined by context lines
    56.7 +  * head:      output the first part of files
    56.8 +  * split:     split a file into pieces
    56.9 +  * tail:      output the last part of files
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/coreutils/description.coreutils-file-sort.txt	Sat May 27 16:55:17 2017 +0300
    57.3 @@ -0,0 +1,8 @@
    57.4 +Coreutils: Core GNU (file, text, shell) utilities.
    57.5 +
    57.6 +  * comm:      compare two sorted files line by line
    57.7 +  * ptx:       produce a permuted index of file contents
    57.8 +  * shuf:      generate random permutations
    57.9 +  * sort:      sort lines of text files
   57.10 +  * tsort:     perform topological sort
   57.11 +  * uniq:      report or omit repeated lines
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/coreutils/description.coreutils-file-special.txt	Sat May 27 16:55:17 2017 +0300
    58.3 @@ -0,0 +1,12 @@
    58.4 +Coreutils: Core GNU (file, text, shell) utilities.
    58.5 +
    58.6 +  * link:      call the link function to create a link to a file
    58.7 +  * ln:        make links between files
    58.8 +  * mkdir:     make directories
    58.9 +  * mkfifo:    make FIFOs (named pipes)
   58.10 +  * mknod:     make block or character special files
   58.11 +  * mktemp:    create a temporary file or directory
   58.12 +  * readlink:  print resolved symbolic links or canonical file names
   58.13 +  * realpath:  print the resolved path
   58.14 +  * rmdir:     remove empty directories
   58.15 +  * unlink:    call the unlink function to remove the specified file
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/coreutils/description.coreutils-file-summarize.txt	Sat May 27 16:55:17 2017 +0300
    59.3 @@ -0,0 +1,11 @@
    59.4 +Coreutils: Core GNU (file, text, shell) utilities.
    59.5 +
    59.6 +  * cksum:     checksum and count the bytes in a file
    59.7 +  * md5sum:    compute and check MD5 message digest
    59.8 +  * sha1sum:   compute and check SHA1 message digest
    59.9 +  * sha224sum: compute and check SHA224 message digest
   59.10 +  * sha256sum: compute and check SHA256 message digest
   59.11 +  * sha384sum: compute and check SHA384 message digest
   59.12 +  * sha512sum: compute and check SHA512 message digest
   59.13 +  * sum:       checksum and count the blocks in a file
   59.14 +  * wc:        print newline, word, and byte counts for each file
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/coreutils/description.coreutils-line.txt	Sat May 27 16:55:17 2017 +0300
    60.3 @@ -0,0 +1,5 @@
    60.4 +Coreutils: Core GNU (file, text, shell) utilities.
    60.5 +
    60.6 +  * cut:       remove sections from each line of files
    60.7 +  * join:      join lines of two files on a common field
    60.8 +  * paste:     merge lines of files
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/coreutils/description.coreutils-numeric.txt	Sat May 27 16:55:17 2017 +0300
    61.3 @@ -0,0 +1,4 @@
    61.4 +Coreutils: Core GNU (file, text, shell) utilities.
    61.5 +
    61.6 +  * factor:    factor numbers
    61.7 +  * seq:       print a sequence of numbers
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/coreutils/description.coreutils-operations.txt	Sat May 27 16:55:17 2017 +0300
    62.3 @@ -0,0 +1,8 @@
    62.4 +Coreutils: Core GNU (file, text, shell) utilities.
    62.5 +
    62.6 +  * cp:        copy files and directories
    62.7 +  * dd:        convert and copy a file
    62.8 +  * install:   copy files and set attributes
    62.9 +  * mv:        move (rename) files
   62.10 +  * rm:        removes files or directories
   62.11 +  * shred:     overwrite a file to hide its contents, and optionally delete it
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/coreutils/description.coreutils-path.txt	Sat May 27 16:55:17 2017 +0300
    63.3 @@ -0,0 +1,5 @@
    63.4 +Coreutils: Core GNU (file, text, shell) utilities.
    63.5 +
    63.6 +  * basename:  strip directory and suffix from filenames
    63.7 +  * dirname:   strip last component from file name
    63.8 +  * pathchk:   check whether file names are valid or portable
    64.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.2 +++ b/coreutils/description.coreutils-print.txt	Sat May 27 16:55:17 2017 +0300
    64.3 @@ -0,0 +1,6 @@
    64.4 +Coreutils: Core GNU (file, text, shell) utilities.
    64.5 +
    64.6 +  * echo:      display a line of text
    64.7 +  * numfmt:    convert numbers from/to human-readable strings
    64.8 +  * printf:    format and print data
    64.9 +  * yes:       output a string repeatedly until killed
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/coreutils/description.coreutils-redirection.txt	Sat May 27 16:55:17 2017 +0300
    65.3 @@ -0,0 +1,3 @@
    65.4 +Coreutils: Core GNU (file, text, shell) utilities.
    65.5 +
    65.6 +  * tee:       read from standard input and write to standard output and files
    66.1 --- a/coreutils/description.txt	Sat May 27 16:29:45 2017 +0300
    66.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.3 @@ -1,17 +0,0 @@
    66.4 -Coreutils: Core GNU (file, text, shell) utilities.
    66.5 -
    66.6 -  * base64:    base64 encode/decode data and print to standard output
    66.7 -  * cp:        copy files and directories
    66.8 -  * csplit:    split a file into sections determined by context lines
    66.9 -  * factor:    factor numbers
   66.10 -  * fmt:       simple optimal text formatter
   66.11 -  * groups:    print the groups a user is in
   66.12 -  * join:      join lines of two files on a common field
   66.13 -  * od:        dump files in octal and other formats
   66.14 -  * paste:     merge lines of files
   66.15 -  * ptx:       produce a permuted index of file contents
   66.16 -  * shred:     overwrite a file to hide its contents, and optionally delete it
   66.17 -  * shuf:      generate random permutations
   66.18 -  * split:     split a file into pieces
   66.19 -  * users:     print the user names of users currently logged in to the current
   66.20 -               host
    67.1 --- a/coreutils/receipt	Sat May 27 16:29:45 2017 +0300
    67.2 +++ b/coreutils/receipt	Sat May 27 16:55:17 2017 +0300
    67.3 @@ -1,9 +1,9 @@
    67.4 -# SliTaz package receipt.
    67.5 +# SliTaz package receipt v2.
    67.6  
    67.7  PACKAGE="coreutils"
    67.8  VERSION="8.25"
    67.9  CATEGORY="meta"
   67.10 -SHORT_DESC="Utilities for using and setting the basic system."
   67.11 +SHORT_DESC="Utilities for using and setting the basic system"
   67.12  MAINTAINER="pankso@slitaz.org"
   67.13  LICENSE="GPL3"
   67.14  WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   67.15 @@ -12,6 +12,7 @@
   67.16  WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL"
   67.17  
   67.18  SIBLINGS="coreutils-multicall"
   67.19 +BUILD_DEPENDS="automake autoconf gettext xz libcap-dev gmp-dev patch"
   67.20  SPLIT="coreutils-character coreutils-command coreutils-conditions coreutils-\
   67.21  context-system coreutils-context-user coreutils-context-working coreutils-\
   67.22  directory coreutils-disk coreutils-file-attributes coreutils-file-format \
   67.23 @@ -19,18 +20,11 @@
   67.24  coreutils-file-special coreutils-file-summarize coreutils-line coreutils-\
   67.25  numeric coreutils-operations coreutils-path coreutils-print coreutils-\
   67.26  redirection"
   67.27 -DEPENDS="glibc-base acl attr gmp $SPLIT"
   67.28 -BUILD_DEPENDS="automake autoconf gettext xz libcap-dev gmp-dev patch"
   67.29  
   67.30  # Rules to configure and make the package.
   67.31  compile_rules()
   67.32  {
   67.33 -	# LFS: Coreutils Internationalization Fixes Patch
   67.34 -	patch -Np1 -i $stuff/coreutils-8.25-i18n-2.patch
   67.35 -	# SliTaz: show extended info touching CPU via uname
   67.36 -	patch  -p1 -i $stuff/uname.u
   67.37 -	# SliTaz: fix translations, especially deprecated symbol '\v'
   67.38 -	patch  -p1 -i $stuff/coreutils-fix-po.patch
   67.39 +	# Rebuild fixed translations
   67.40  	msgfmt po/nb.po -o po/nb.gmo
   67.41  	msgfmt po/sl.po -o po/sl.gmo
   67.42  
   67.43 @@ -53,3 +47,125 @@
   67.44  		$install/usr/share/man/man8/chroot.8
   67.45  	sed -i 's|"1"|"8"|' $install/usr/share/man/man8/chroot.8
   67.46  }
   67.47 +
   67.48 +# Rules to gen a SliTaz package suitable for Tazpkg.
   67.49 +genpkg_rules()
   67.50 +{
   67.51 +	case $PACKAGE in
   67.52 +		coreutils)
   67.53 +			DEPENDS="$SPLIT" ;;
   67.54 +		coreutils-character)
   67.55 +			copy expand tr unexpand
   67.56 +			CAT="system-tools|operate on characters"
   67.57 +			DEPENDS="glibc-base" ;;
   67.58 +		coreutils-command)
   67.59 +			copy env kill nice nohup sleep stdbuf timeout libstdbuf.so chroot
   67.60 +			CAT="system-tools|commands"
   67.61 +			DEPENDS="glibc-base" ;;
   67.62 +		coreutils-conditions)
   67.63 +			copy false true [ expr test
   67.64 +			CAT="system-tools|conditions"
   67.65 +			DEPENDS="glibc-base gmp" ;;
   67.66 +		coreutils-context-system)
   67.67 +			copy date uname chcon hostid nproc runcon uptime
   67.68 +			CAT="system-tools|system context"
   67.69 +			DEPENDS="glibc-base" ;;
   67.70 +		coreutils-context-user)
   67.71 +			copy groups id logname pinky users who whoami
   67.72 +			CAT="system-tools|user context"
   67.73 +			DEPENDS="glibc-base" ;;
   67.74 +		coreutils-context-working)
   67.75 +			copy pwd stty printenv tty
   67.76 +			CAT="system-tools|working context"
   67.77 +			DEPENDS="glibc-base" ;;
   67.78 +		coreutils-directory)
   67.79 +			copy ls dir dircolors vdir
   67.80 +			CAT="system-tools|list directories"
   67.81 +			DEPENDS="glibc-base attr libcap" ;;
   67.82 +		coreutils-disk)
   67.83 +			copy df sync du stat truncate
   67.84 +			CAT="system-tools|work with disks"
   67.85 +			DEPENDS="glibc-base" ;;
   67.86 +		coreutils-file-attributes)
   67.87 +			copy chgrp chmod chown touch
   67.88 +			CAT="system-tools|change file attributes"
   67.89 +			DEPENDS="glibc-base" ;;
   67.90 +		coreutils-file-format)
   67.91 +			copy fmt fold pr
   67.92 +			CAT="system-tools|format file contents"
   67.93 +			DEPENDS="glibc-base" ;;
   67.94 +		coreutils-file-output-full)
   67.95 +			copy cat base32 base64 nl od tac
   67.96 +			CAT="system-tools|output entire files"
   67.97 +			DEPENDS="glibc-base" ;;
   67.98 +		coreutils-file-output-part)
   67.99 +			copy csplit head split tail
  67.100 +			CAT="system-tools|output file parts"
  67.101 +			DEPENDS="glibc-base" ;;
  67.102 +		coreutils-file-sort)
  67.103 +			copy comm ptx shuf sort tsort uniq
  67.104 +			CAT="system-tools|operate on sorted files"
  67.105 +			DEPENDS="glibc-base" ;;
  67.106 +		coreutils-file-special)
  67.107 +			copy ln mkdir mknod rmdir link mkfifo mktemp readlink realpath unlink
  67.108 +			CAT="system-tools|work with special file types"
  67.109 +			DEPENDS="glibc-base" ;;
  67.110 +		coreutils-file-summarize)
  67.111 +			copy cksum md5sum sha1sum sha224sum sha256sum sha384sum sha512sum sum wc
  67.112 +			CAT="system-tools|summarize files"
  67.113 +			DEPENDS="glibc-base" ;;
  67.114 +		coreutils-line)
  67.115 +			copy cut join paste
  67.116 +			CAT="system-tools|operate on fields within a line"
  67.117 +			DEPENDS="glibc-base" ;;
  67.118 +		coreutils-numeric)
  67.119 +			copy factor seq
  67.120 +			CAT="system-tools|numeric"
  67.121 +			DEPENDS="glibc-base gmp" ;;
  67.122 +		coreutils-operations)
  67.123 +			copy cp dd mv install rm shred
  67.124 +			CAT="system-tools|perform basic operations"
  67.125 +			DEPENDS="glibc-base acl attr" ;;
  67.126 +		coreutils-path)
  67.127 +			copy basename dirname pathchk
  67.128 +			CAT="system-tools|perform path manipulation"
  67.129 +			DEPENDS="glibc-base" ;;
  67.130 +		coreutils-print)
  67.131 +			copy echo numfmt printf yes
  67.132 +			CAT="system-tools|print text"
  67.133 +			DEPENDS="glibc-base" ;;
  67.134 +		coreutils-redirection)
  67.135 +			copy tee
  67.136 +			CAT="system-tools|redirection"
  67.137 +			DEPENDS="glibc-base" ;;
  67.138 +	esac
  67.139 +}
  67.140 +
  67.141 +# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
  67.142 +# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
  67.143 +post_install_coreutils_command()
  67.144 +{
  67.145 +	rm "$1/bin/kill"     # for /usr/bin/kill
  67.146 +	rm "$1/bin/nice"     # for /usr/bin/nice
  67.147 +	rm "$1/bin/sleep"    # for /usr/bin/sleep
  67.148 +}
  67.149 +post_install_coreutils_context_working()
  67.150 +{
  67.151 +	rm "$1/bin/printenv" # for /usr/bin/printenv
  67.152 +}
  67.153 +post_install_coreutils_disk()
  67.154 +{
  67.155 +	rm "$1/bin/stat"     # for /usr/bin/stat
  67.156 +}
  67.157 +post_install_coreutils_file_attributes()
  67.158 +{
  67.159 +	rm "$1/bin/touch"    # for /usr/bin/touch
  67.160 +}
  67.161 +post_install_coreutils_file_output_full()
  67.162 +{
  67.163 +	rm "$1/bin/base64"   # for /usr/bin/base64
  67.164 +}
  67.165 +post_install_coreutils_file_special()
  67.166 +{
  67.167 +	rm "$1/bin/mktemp"   # for /usr/bin/mktemp
  67.168 +}
    68.1 --- a/coreutils/stuff/coreutils-8.25-i18n-2.patch	Sat May 27 16:29:45 2017 +0300
    68.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.3 @@ -1,4790 +0,0 @@
    68.4 -Submitted by:            DJ Lucas (dj_AT_linuxfromscratch_DOT_org)
    68.5 -Date:                    2016-02-09
    68.6 -Initial Package Version: 8.25
    68.7 -Upstream Status:         Rejected
    68.8 -Origin:                  Based on Suse's i18n patches at https://build.opensuse.org/package/view_file/Base:System/coreutils/coreutils-i18n.patch
    68.9 -Description:             Fixes several i18n issues with various Coreutils programs
   68.10 -
   68.11 -diff -Naurp coreutils-8.25-orig/lib/linebuffer.h coreutils-8.25/lib/linebuffer.h
   68.12 ---- coreutils-8.25-orig/lib/linebuffer.h	2016-01-01 07:45:55.000000000 -0600
   68.13 -+++ coreutils-8.25/lib/linebuffer.h	2016-02-08 19:07:10.298944609 -0600
   68.14 -@@ -21,6 +21,11 @@
   68.15 - 
   68.16 - # include <stdio.h>
   68.17 - 
   68.18 -+/* Get mbstate_t.  */
   68.19 -+# if HAVE_WCHAR_H
   68.20 -+#  include <wchar.h>
   68.21 -+# endif
   68.22 -+
   68.23 - /* A 'struct linebuffer' holds a line of text. */
   68.24 - 
   68.25 - struct linebuffer
   68.26 -@@ -28,6 +33,9 @@ struct linebuffer
   68.27 -   size_t size;                  /* Allocated. */
   68.28 -   size_t length;                /* Used. */
   68.29 -   char *buffer;
   68.30 -+# if HAVE_WCHAR_H
   68.31 -+  mbstate_t state;
   68.32 -+# endif
   68.33 - };
   68.34 - 
   68.35 - /* Initialize linebuffer LINEBUFFER for use. */
   68.36 -diff -Naurp coreutils-8.25-orig/src/cut.c coreutils-8.25/src/cut.c
   68.37 ---- coreutils-8.25-orig/src/cut.c	2016-01-13 05:08:59.000000000 -0600
   68.38 -+++ coreutils-8.25/src/cut.c	2016-02-08 19:07:10.300944616 -0600
   68.39 -@@ -28,6 +28,11 @@
   68.40 - #include <assert.h>
   68.41 - #include <getopt.h>
   68.42 - #include <sys/types.h>
   68.43 -+
   68.44 -+/* Get mbstate_t, mbrtowc().  */
   68.45 -+#if HAVE_WCHAR_H
   68.46 -+# include <wchar.h>
   68.47 -+#endif
   68.48 - #include "system.h"
   68.49 - 
   68.50 - #include "error.h"
   68.51 -@@ -38,6 +43,18 @@
   68.52 - 
   68.53 - #include "set-fields.h"
   68.54 - 
   68.55 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
   68.56 -+   installation; work around this configuration error.        */
   68.57 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
   68.58 -+# undef MB_LEN_MAX
   68.59 -+# define MB_LEN_MAX 16
   68.60 -+#endif
   68.61 -+
   68.62 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
   68.63 -+#if HAVE_MBRTOWC && defined mbstate_t
   68.64 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
   68.65 -+#endif
   68.66 -+
   68.67 - /* The official name of this program (e.g., no 'g' prefix).  */
   68.68 - #define PROGRAM_NAME "cut"
   68.69 - 
   68.70 -@@ -54,6 +71,52 @@
   68.71 -     }									\
   68.72 -   while (0)
   68.73 - 
   68.74 -+/* Refill the buffer BUF to get a multibyte character. */
   68.75 -+#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM)                        \
   68.76 -+  do                                                                        \
   68.77 -+    {                                                                        \
   68.78 -+      if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM))        \
   68.79 -+        {                                                                \
   68.80 -+          memmove (BUF, BUFPOS, BUFLEN);                                \
   68.81 -+          BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \
   68.82 -+          BUFPOS = BUF;                                                        \
   68.83 -+        }                                                                \
   68.84 -+    }                                                                        \
   68.85 -+  while (0)
   68.86 -+
   68.87 -+/* Get wide character on BUFPOS. BUFPOS is not included after that.
   68.88 -+   If byte sequence is not valid as a character, CONVFAIL is true. Otherwise false. */
   68.89 -+#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \
   68.90 -+  do                                                                        \
   68.91 -+    {                                                                        \
   68.92 -+      mbstate_t state_bak;                                                \
   68.93 -+                                                                        \
   68.94 -+      if (BUFLEN < 1)                                                        \
   68.95 -+        {                                                                \
   68.96 -+          WC = WEOF;                                                        \
   68.97 -+          break;                                                        \
   68.98 -+        }                                                                \
   68.99 -+                                                                        \
  68.100 -+      /* Get a wide character. */                                        \
  68.101 -+      CONVFAIL = false;                                                        \
  68.102 -+      state_bak = STATE;                                                \
  68.103 -+      MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE);        \
  68.104 -+                                                                        \
  68.105 -+      switch (MBLENGTH)                                                        \
  68.106 -+        {                                                                \
  68.107 -+        case (size_t)-1:                                                \
  68.108 -+        case (size_t)-2:                                                \
  68.109 -+          CONVFAIL = true;                                                        \
  68.110 -+          STATE = state_bak;                                                \
  68.111 -+          /* Fall througn. */                                                \
  68.112 -+                                                                        \
  68.113 -+        case 0:                                                                \
  68.114 -+          MBLENGTH = 1;                                                        \
  68.115 -+          break;                                                        \
  68.116 -+        }                                                                \
  68.117 -+    }                                                                        \
  68.118 -+  while (0)
  68.119 -+
  68.120 - 
  68.121 - /* Pointer inside RP.  When checking if a byte or field is selected
  68.122 -    by a finite range, we check if it is between CURRENT_RP.LO
  68.123 -@@ -61,6 +124,9 @@
  68.124 -    CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */
  68.125 - static struct field_range_pair *current_rp;
  68.126 - 
  68.127 -+/* Length of the delimiter given as argument to -d.  */
  68.128 -+size_t delimlen;
  68.129 -+
  68.130 - /* This buffer is used to support the semantics of the -s option
  68.131 -    (or lack of same) when the specified field list includes (does
  68.132 -    not include) the first field.  In both of those cases, the entire
  68.133 -@@ -77,15 +143,25 @@ enum operating_mode
  68.134 -   {
  68.135 -     undefined_mode,
  68.136 - 
  68.137 --    /* Output characters that are in the given bytes. */
  68.138 -+    /* Output bytes that are at the given positions. */
  68.139 -     byte_mode,
  68.140 - 
  68.141 -+    /* Output characters that are at the given positions. */
  68.142 -+    character_mode,
  68.143 -+
  68.144 -     /* Output the given delimiter-separated fields. */
  68.145 -     field_mode
  68.146 -   };
  68.147 - 
  68.148 - static enum operating_mode operating_mode;
  68.149 - 
  68.150 -+/* If nonzero, when in byte mode, don't split multibyte characters.  */
  68.151 -+static int byte_mode_character_aware;
  68.152 -+
  68.153 -+/* If nonzero, the function for single byte locale is work
  68.154 -+   if this program runs on multibyte locale. */
  68.155 -+static int force_singlebyte_mode;
  68.156 -+
  68.157 - /* If true do not output lines containing no delimiter characters.
  68.158 -    Otherwise, all such lines are printed.  This option is valid only
  68.159 -    with field mode.  */
  68.160 -@@ -97,6 +173,9 @@ static bool complement;
  68.161 - 
  68.162 - /* The delimiter character for field mode. */
  68.163 - static unsigned char delim;
  68.164 -+#if HAVE_WCHAR_H
  68.165 -+static wchar_t wcdelim;
  68.166 -+#endif
  68.167 - 
  68.168 - /* The delimiter for each line/record. */
  68.169 - static unsigned char line_delim = '\n';
  68.170 -@@ -164,7 +243,7 @@ Print selected parts of lines from each
  68.171 -   -f, --fields=LIST       select only these fields;  also print any line\n\
  68.172 -                             that contains no delimiter character, unless\n\
  68.173 -                             the -s option is specified\n\
  68.174 --  -n                      (ignored)\n\
  68.175 -+  -n                      with -b: don't split multibyte characters\n\
  68.176 - "), stdout);
  68.177 -       fputs (_("\
  68.178 -       --complement        complement the set of selected bytes, characters\n\
  68.179 -@@ -280,6 +359,82 @@ cut_bytes (FILE *stream)
  68.180 -     }
  68.181 - }
  68.182 - 
  68.183 -+#if HAVE_MBRTOWC
  68.184 -+/* This function is in use for the following case.
  68.185 -+
  68.186 -+   1. Read from the stream STREAM, printing to standard output any selected
  68.187 -+   characters.
  68.188 -+
  68.189 -+   2. Read from stream STREAM, printing to standard output any selected bytes,
  68.190 -+   without splitting multibyte characters.  */
  68.191 -+
  68.192 -+static void
  68.193 -+cut_characters_or_cut_bytes_no_split (FILE *stream)
  68.194 -+{
  68.195 -+  size_t idx;                /* number of bytes or characters in the line so far. */
  68.196 -+  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
  68.197 -+  char *bufpos;                /* Next read position of BUF. */
  68.198 -+  size_t buflen;        /* The length of the byte sequence in buf. */
  68.199 -+  wint_t wc;                /* A gotten wide character. */
  68.200 -+  size_t mblength;        /* The byte size of a multibyte character which shows
  68.201 -+                           as same character as WC. */
  68.202 -+  mbstate_t state;        /* State of the stream. */
  68.203 -+  bool convfail = false;  /* true, when conversion failed. Otherwise false. */
  68.204 -+  /* Whether to begin printing delimiters between ranges for the current line.
  68.205 -+     Set after we've begun printing data corresponding to the first range.  */
  68.206 -+  bool print_delimiter = false;
  68.207 -+
  68.208 -+  idx = 0;
  68.209 -+  buflen = 0;
  68.210 -+  bufpos = buf;
  68.211 -+  memset (&state, '\0', sizeof(mbstate_t));
  68.212 -+
  68.213 -+  current_rp = frp;
  68.214 -+
  68.215 -+  while (1)
  68.216 -+    {
  68.217 -+      REFILL_BUFFER (buf, bufpos, buflen, stream);
  68.218 -+
  68.219 -+      GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail);
  68.220 -+      (void) convfail;  /* ignore unused */
  68.221 -+
  68.222 -+      if (wc == WEOF)
  68.223 -+        {
  68.224 -+          if (idx > 0)
  68.225 -+            putchar (line_delim);
  68.226 -+          break;
  68.227 -+        }
  68.228 -+      else if (wc == line_delim)
  68.229 -+        {
  68.230 -+          putchar (line_delim);
  68.231 -+          idx = 0;
  68.232 -+          print_delimiter = false;
  68.233 -+          current_rp = frp;
  68.234 -+        }
  68.235 -+      else
  68.236 -+        {
  68.237 -+          next_item (&idx);
  68.238 -+          if (print_kth (idx))
  68.239 -+            {
  68.240 -+              if (output_delimiter_specified)
  68.241 -+                {
  68.242 -+                  if (print_delimiter && is_range_start_index (idx))
  68.243 -+                    {
  68.244 -+                      fwrite (output_delimiter_string, sizeof (char),
  68.245 -+                              output_delimiter_length, stdout);
  68.246 -+                    }
  68.247 -+                  print_delimiter = true;
  68.248 -+                }
  68.249 -+              fwrite (bufpos, mblength, sizeof(char), stdout);
  68.250 -+            }
  68.251 -+        }
  68.252 -+
  68.253 -+      buflen -= mblength;
  68.254 -+      bufpos += mblength;
  68.255 -+    }
  68.256 -+}
  68.257 -+#endif
  68.258 -+
  68.259 - /* Read from stream STREAM, printing to standard output any selected fields.  */
  68.260 - 
  68.261 - static void
  68.262 -@@ -425,13 +580,211 @@ cut_fields (FILE *stream)
  68.263 -     }
  68.264 - }
  68.265 - 
  68.266 -+#if HAVE_MBRTOWC
  68.267 -+static void
  68.268 -+cut_fields_mb (FILE *stream)
  68.269 -+{
  68.270 -+  int c;
  68.271 -+  size_t field_idx;
  68.272 -+  int found_any_selected_field;
  68.273 -+  int buffer_first_field;
  68.274 -+  int empty_input;
  68.275 -+  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
  68.276 -+  char *bufpos;                /* Next read position of BUF. */
  68.277 -+  size_t buflen;        /* The length of the byte sequence in buf. */
  68.278 -+  wint_t wc = 0;        /* A gotten wide character. */
  68.279 -+  size_t mblength;        /* The byte size of a multibyte character which shows
  68.280 -+                           as same character as WC. */
  68.281 -+  mbstate_t state;        /* State of the stream. */
  68.282 -+  bool convfail = false;  /* true, when conversion failed. Otherwise false. */
  68.283 -+
  68.284 -+  current_rp = frp;
  68.285 -+
  68.286 -+  found_any_selected_field = 0;
  68.287 -+  field_idx = 1;
  68.288 -+  bufpos = buf;
  68.289 -+  buflen = 0;
  68.290 -+  memset (&state, '\0', sizeof(mbstate_t));
  68.291 -+
  68.292 -+  c = getc (stream);
  68.293 -+  empty_input = (c == EOF);
  68.294 -+  if (c != EOF)
  68.295 -+  {
  68.296 -+    ungetc (c, stream);
  68.297 -+    wc = 0;
  68.298 -+  }
  68.299 -+  else
  68.300 -+    wc = WEOF;
  68.301 -+
  68.302 -+  /* To support the semantics of the -s flag, we may have to buffer
  68.303 -+     all of the first field to determine whether it is `delimited.'
  68.304 -+     But that is unnecessary if all non-delimited lines must be printed
  68.305 -+     and the first field has been selected, or if non-delimited lines
  68.306 -+     must be suppressed and the first field has *not* been selected.
  68.307 -+     That is because a non-delimited line has exactly one field.  */
  68.308 -+  buffer_first_field = (suppress_non_delimited ^ !print_kth (1));
  68.309 -+
  68.310 -+  while (1)
  68.311 -+    {
  68.312 -+      if (field_idx == 1 && buffer_first_field)
  68.313 -+        {
  68.314 -+          int len = 0;
  68.315 -+
  68.316 -+          while (1)
  68.317 -+            {
  68.318 -+              REFILL_BUFFER (buf, bufpos, buflen, stream);
  68.319 -+
  68.320 -+              GET_NEXT_WC_FROM_BUFFER
  68.321 -+                (wc, bufpos, buflen, mblength, state, convfail);
  68.322 -+
  68.323 -+              if (wc == WEOF)
  68.324 -+                break;
  68.325 -+
  68.326 -+              field_1_buffer = xrealloc (field_1_buffer, len + mblength);
  68.327 -+              memcpy (field_1_buffer + len, bufpos, mblength);
  68.328 -+              len += mblength;
  68.329 -+              buflen -= mblength;
  68.330 -+              bufpos += mblength;
  68.331 -+
  68.332 -+              if (!convfail && (wc == line_delim || wc == wcdelim))
  68.333 -+                break;
  68.334 -+            }
  68.335 -+
  68.336 -+          if (len <= 0 && wc == WEOF)
  68.337 -+            break;
  68.338 -+
  68.339 -+          /* If the first field extends to the end of line (it is not
  68.340 -+             delimited) and we are printing all non-delimited lines,
  68.341 -+             print this one.  */
  68.342 -+          if (convfail || (!convfail && wc != wcdelim))
  68.343 -+            {
  68.344 -+              if (suppress_non_delimited)
  68.345 -+                {
  68.346 -+                  /* Empty.        */
  68.347 -+                }
  68.348 -+              else
  68.349 -+                {
  68.350 -+                  fwrite (field_1_buffer, sizeof (char), len, stdout);
  68.351 -+                  /* Make sure the output line is newline terminated.  */
  68.352 -+                  if (convfail || (!convfail && wc != line_delim))
  68.353 -+                    putchar (line_delim);
  68.354 -+                }
  68.355 -+              continue;
  68.356 -+            }
  68.357 -+
  68.358 -+          if (print_kth (1))
  68.359 -+            {
  68.360 -+              /* Print the field, but not the trailing delimiter.  */
  68.361 -+              fwrite (field_1_buffer, sizeof (char), len - 1, stdout);
  68.362 -+              found_any_selected_field = 1;
  68.363 -+            }
  68.364 -+          next_item (&field_idx);
  68.365 -+        }
  68.366 -+
  68.367 -+      if (wc != WEOF)
  68.368 -+        {
  68.369 -+          if (print_kth (field_idx))
  68.370 -+            {
  68.371 -+              if (found_any_selected_field)
  68.372 -+                {
  68.373 -+                  fwrite (output_delimiter_string, sizeof (char),
  68.374 -+                          output_delimiter_length, stdout);
  68.375 -+                }
  68.376 -+              found_any_selected_field = 1;
  68.377 -+            }
  68.378 -+
  68.379 -+          while (1)
  68.380 -+            {
  68.381 -+              REFILL_BUFFER (buf, bufpos, buflen, stream);
  68.382 -+
  68.383 -+              GET_NEXT_WC_FROM_BUFFER
  68.384 -+                (wc, bufpos, buflen, mblength, state, convfail);
  68.385 -+
  68.386 -+              if (wc == WEOF)
  68.387 -+                break;
  68.388 -+              else if (!convfail && (wc == wcdelim || wc == line_delim))
  68.389 -+                {
  68.390 -+                  buflen -= mblength;
  68.391 -+                  bufpos += mblength;
  68.392 -+                  break;
  68.393 -+                }
  68.394 -+
  68.395 -+              if (print_kth (field_idx))
  68.396 -+                fwrite (bufpos, mblength, sizeof(char), stdout);
  68.397 -+
  68.398 -+              buflen -= mblength;
  68.399 -+              bufpos += mblength;
  68.400 -+            }
  68.401 -+        }
  68.402 -+
  68.403 -+      if ((!convfail || wc == line_delim) && buflen < 1)
  68.404 -+        wc = WEOF;
  68.405 -+
  68.406 -+      if (!convfail && wc == wcdelim)
  68.407 -+        next_item (&field_idx);
  68.408 -+      else if (wc == WEOF || (!convfail && wc == line_delim))
  68.409 -+        {
  68.410 -+          if (found_any_selected_field
  68.411 -+              || (!empty_input && !(suppress_non_delimited && field_idx == 1)))
  68.412 -+            putchar (line_delim);
  68.413 -+          if (wc == WEOF)
  68.414 -+            break;
  68.415 -+          field_idx = 1;
  68.416 -+          current_rp = frp;
  68.417 -+          found_any_selected_field = 0;
  68.418 -+        }
  68.419 -+    }
  68.420 -+}
  68.421 -+#endif
  68.422 -+
  68.423 - static void
  68.424 - cut_stream (FILE *stream)
  68.425 - {
  68.426 --  if (operating_mode == byte_mode)
  68.427 --    cut_bytes (stream);
  68.428 -+#if HAVE_MBRTOWC
  68.429 -+  if (MB_CUR_MAX > 1 && !force_singlebyte_mode)
  68.430 -+    {
  68.431 -+      switch (operating_mode)
  68.432 -+        {
  68.433 -+        case byte_mode:
  68.434 -+          if (byte_mode_character_aware)
  68.435 -+            cut_characters_or_cut_bytes_no_split (stream);
  68.436 -+          else
  68.437 -+            cut_bytes (stream);
  68.438 -+          break;
  68.439 -+
  68.440 -+        case character_mode:
  68.441 -+          cut_characters_or_cut_bytes_no_split (stream);
  68.442 -+          break;
  68.443 -+
  68.444 -+        case field_mode:
  68.445 -+          if (delimlen == 1)
  68.446 -+            {
  68.447 -+              /* Check if we have utf8 multibyte locale, so we can use this
  68.448 -+                 optimization because of uniqueness of characters, which is
  68.449 -+                 not true for e.g. SJIS */
  68.450 -+              char * loc = setlocale(LC_CTYPE, NULL);
  68.451 -+              if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") ||
  68.452 -+                  strstr (loc, "UTF8") || strstr (loc, "utf8")))
  68.453 -+                {
  68.454 -+                  cut_fields (stream);
  68.455 -+                  break;
  68.456 -+                }
  68.457 -+            }
  68.458 -+          cut_fields_mb (stream);
  68.459 -+          break;
  68.460 -+
  68.461 -+        default:
  68.462 -+          abort ();
  68.463 -+        }
  68.464 -+    }
  68.465 -   else
  68.466 --    cut_fields (stream);
  68.467 -+#endif
  68.468 -+    {
  68.469 -+      if (operating_mode == field_mode)
  68.470 -+        cut_fields (stream);
  68.471 -+      else
  68.472 -+        cut_bytes (stream);
  68.473 -+    }
  68.474 - }
  68.475 - 
  68.476 - /* Process file FILE to standard output.
  68.477 -@@ -483,6 +836,7 @@ main (int argc, char **argv)
  68.478 -   bool ok;
  68.479 -   bool delim_specified = false;
  68.480 -   char *spec_list_string IF_LINT ( = NULL);
  68.481 -+  char mbdelim[MB_LEN_MAX + 1];
  68.482 - 
  68.483 -   initialize_main (&argc, &argv);
  68.484 -   set_program_name (argv[0]);
  68.485 -@@ -505,7 +859,6 @@ main (int argc, char **argv)
  68.486 -       switch (optc)
  68.487 -         {
  68.488 -         case 'b':
  68.489 --        case 'c':
  68.490 -           /* Build the byte list. */
  68.491 -           if (operating_mode != undefined_mode)
  68.492 -             FATAL_ERROR (_("only one type of list may be specified"));
  68.493 -@@ -513,6 +866,14 @@ main (int argc, char **argv)
  68.494 -           spec_list_string = optarg;
  68.495 -           break;
  68.496 - 
  68.497 -+        case 'c':
  68.498 -+          /* Build the character list. */
  68.499 -+          if (operating_mode != undefined_mode)
  68.500 -+            FATAL_ERROR (_("only one type of list may be specified"));
  68.501 -+          operating_mode = character_mode;
  68.502 -+          spec_list_string = optarg;
  68.503 -+          break;
  68.504 -+
  68.505 -         case 'f':
  68.506 -           /* Build the field list. */
  68.507 -           if (operating_mode != undefined_mode)
  68.508 -@@ -524,10 +885,38 @@ main (int argc, char **argv)
  68.509 -         case 'd':
  68.510 -           /* New delimiter. */
  68.511 -           /* Interpret -d '' to mean 'use the NUL byte as the delimiter.'  */
  68.512 --          if (optarg[0] != '\0' && optarg[1] != '\0')
  68.513 --            FATAL_ERROR (_("the delimiter must be a single character"));
  68.514 --          delim = optarg[0];
  68.515 --          delim_specified = true;
  68.516 -+            {
  68.517 -+#if HAVE_MBRTOWC
  68.518 -+              if(MB_CUR_MAX > 1)
  68.519 -+                {
  68.520 -+                  mbstate_t state;
  68.521 -+
  68.522 -+                  memset (&state, '\0', sizeof(mbstate_t));
  68.523 -+                  delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state);
  68.524 -+
  68.525 -+                  if (delimlen == (size_t)-1 || delimlen == (size_t)-2)
  68.526 -+                    ++force_singlebyte_mode;
  68.527 -+                  else
  68.528 -+                    {
  68.529 -+                      delimlen = (delimlen < 1) ? 1 : delimlen;
  68.530 -+                      if (wcdelim != L'\0' && *(optarg + delimlen) != '\0')
  68.531 -+                        FATAL_ERROR (_("the delimiter must be a single character"));
  68.532 -+                      memcpy (mbdelim, optarg, delimlen);
  68.533 -+                      mbdelim[delimlen] = '\0';
  68.534 -+                      if (delimlen == 1)
  68.535 -+                        delim = *optarg;
  68.536 -+                    }
  68.537 -+                }
  68.538 -+
  68.539 -+              if (MB_CUR_MAX <= 1 || force_singlebyte_mode)
  68.540 -+#endif
  68.541 -+                {
  68.542 -+                  if (optarg[0] != '\0' && optarg[1] != '\0')
  68.543 -+                    FATAL_ERROR (_("the delimiter must be a single character"));
  68.544 -+                  delim = (unsigned char) optarg[0];
  68.545 -+                }
  68.546 -+            delim_specified = true;
  68.547 -+          }
  68.548 -           break;
  68.549 - 
  68.550 -         case OUTPUT_DELIMITER_OPTION:
  68.551 -@@ -540,6 +929,7 @@ main (int argc, char **argv)
  68.552 -           break;
  68.553 - 
  68.554 -         case 'n':
  68.555 -+          byte_mode_character_aware = 1;
  68.556 -           break;
  68.557 - 
  68.558 -         case 's':
  68.559 -@@ -579,15 +969,34 @@ main (int argc, char **argv)
  68.560 -               | (complement ? SETFLD_COMPLEMENT : 0) );
  68.561 - 
  68.562 -   if (!delim_specified)
  68.563 --    delim = '\t';
  68.564 -+    {
  68.565 -+      delim = '\t';
  68.566 -+#ifdef HAVE_MBRTOWC
  68.567 -+      wcdelim = L'\t';
  68.568 -+      mbdelim[0] = '\t';
  68.569 -+      mbdelim[1] = '\0';
  68.570 -+      delimlen = 1;
  68.571 -+#endif
  68.572 -+    }
  68.573 - 
  68.574 -   if (output_delimiter_string == NULL)
  68.575 -     {
  68.576 --      static char dummy[2];
  68.577 --      dummy[0] = delim;
  68.578 --      dummy[1] = '\0';
  68.579 --      output_delimiter_string = dummy;
  68.580 --      output_delimiter_length = 1;
  68.581 -+#ifdef HAVE_MBRTOWC
  68.582 -+      if (MB_CUR_MAX > 1 && !force_singlebyte_mode)
  68.583 -+        {
  68.584 -+          output_delimiter_string = xstrdup(mbdelim);
  68.585 -+          output_delimiter_length = delimlen;
  68.586 -+        }
  68.587 -+
  68.588 -+      if (MB_CUR_MAX <= 1 || force_singlebyte_mode)
  68.589 -+#endif
  68.590 -+        {
  68.591 -+          static char dummy[2];
  68.592 -+          dummy[0] = delim;
  68.593 -+          dummy[1] = '\0';
  68.594 -+          output_delimiter_string = dummy;
  68.595 -+          output_delimiter_length = 1;
  68.596 -+        }
  68.597 -     }
  68.598 - 
  68.599 -   if (optind == argc)
  68.600 -diff -Naurp coreutils-8.25-orig/src/expand.c coreutils-8.25/src/expand.c
  68.601 ---- coreutils-8.25-orig/src/expand.c	2016-01-01 07:48:50.000000000 -0600
  68.602 -+++ coreutils-8.25/src/expand.c	2016-02-08 19:07:10.301944619 -0600
  68.603 -@@ -37,12 +37,34 @@
  68.604 - #include <stdio.h>
  68.605 - #include <getopt.h>
  68.606 - #include <sys/types.h>
  68.607 -+
  68.608 -+/* Get mbstate_t, mbrtowc(), wcwidth(). */
  68.609 -+#if HAVE_WCHAR_H
  68.610 -+# include <wchar.h>
  68.611 -+#endif
  68.612 -+
  68.613 -+/* Get iswblank(). */
  68.614 -+#if HAVE_WCTYPE_H
  68.615 -+# include <wctype.h>
  68.616 -+#endif
  68.617 -+
  68.618 - #include "system.h"
  68.619 - #include "error.h"
  68.620 - #include "fadvise.h"
  68.621 - #include "quote.h"
  68.622 - #include "xstrndup.h"
  68.623 - 
  68.624 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
  68.625 -+   installation; work around this configuration error.  */
  68.626 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
  68.627 -+# define MB_LEN_MAX 16
  68.628 -+#endif
  68.629 -+
  68.630 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
  68.631 -+#if HAVE_MBRTOWC && defined mbstate_t
  68.632 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
  68.633 -+#endif
  68.634 -+
  68.635 - /* The official name of this program (e.g., no 'g' prefix).  */
  68.636 - #define PROGRAM_NAME "expand"
  68.637 - 
  68.638 -@@ -357,6 +379,142 @@ expand (void)
  68.639 -     }
  68.640 - }
  68.641 - 
  68.642 -+#if HAVE_MBRTOWC
  68.643 -+static void
  68.644 -+expand_multibyte (void)
  68.645 -+{
  68.646 -+  FILE *fp;			/* Input strem. */
  68.647 -+  mbstate_t i_state;		/* Current shift state of the input stream. */
  68.648 -+  mbstate_t i_state_bak;	/* Back up the I_STATE. */
  68.649 -+  mbstate_t o_state;		/* Current shift state of the output stream. */
  68.650 -+  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
  68.651 -+  char *bufpos = buf;			/* Next read position of BUF. */
  68.652 -+  size_t buflen = 0;		/* The length of the byte sequence in buf. */
  68.653 -+  wchar_t wc;			/* A gotten wide character. */
  68.654 -+  size_t mblength;		/* The byte size of a multibyte character
  68.655 -+				   which shows as same character as WC. */
  68.656 -+  int tab_index = 0;		/* Index in `tab_list' of next tabstop. */
  68.657 -+  int column = 0;		/* Column on screen of the next char. */
  68.658 -+  int next_tab_column;		/* Column the next tab stop is on. */
  68.659 -+  int convert = 1;		/* If nonzero, perform translations. */
  68.660 -+
  68.661 -+  fp = next_file ((FILE *) NULL);
  68.662 -+  if (fp == NULL)
  68.663 -+    return;
  68.664 -+
  68.665 -+  memset (&o_state, '\0', sizeof(mbstate_t));
  68.666 -+  memset (&i_state, '\0', sizeof(mbstate_t));
  68.667 -+
  68.668 -+  for (;;)
  68.669 -+    {
  68.670 -+      /* Refill the buffer BUF. */
  68.671 -+      if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp))
  68.672 -+	{
  68.673 -+	  memmove (buf, bufpos, buflen);
  68.674 -+	  buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp);
  68.675 -+	  bufpos = buf;
  68.676 -+	}
  68.677 -+
  68.678 -+      /* No character is left in BUF. */
  68.679 -+      if (buflen < 1)
  68.680 -+	{
  68.681 -+	  fp = next_file (fp);
  68.682 -+
  68.683 -+	  if (fp == NULL)
  68.684 -+	    break;		/* No more files. */
  68.685 -+	  else
  68.686 -+	    {
  68.687 -+	      memset (&i_state, '\0', sizeof(mbstate_t));
  68.688 -+	      continue;
  68.689 -+	    }
  68.690 -+	}
  68.691 -+
  68.692 -+      /* Get a wide character. */
  68.693 -+      i_state_bak = i_state;
  68.694 -+      mblength = mbrtowc (&wc, bufpos, buflen, &i_state);
  68.695 -+
  68.696 -+      switch (mblength)
  68.697 -+	{
  68.698 -+	case (size_t)-1:	/* illegal byte sequence. */
  68.699 -+	case (size_t)-2:
  68.700 -+	  mblength = 1;
  68.701 -+	  i_state = i_state_bak;
  68.702 -+	  if (convert)
  68.703 -+	    {
  68.704 -+	      ++column;
  68.705 -+	      if (convert_entire_line == 0 && !isblank(*bufpos))
  68.706 -+		convert = 0;
  68.707 -+	    }
  68.708 -+	  putchar (*bufpos);
  68.709 -+	  break;
  68.710 -+
  68.711 -+	case 0:		/* null. */
  68.712 -+	  mblength = 1;
  68.713 -+	  if (convert && convert_entire_line == 0)
  68.714 -+	    convert = 0;
  68.715 -+	  putchar ('\0');
  68.716 -+	  break;
  68.717 -+
  68.718 -+	default:
  68.719 -+	  if (wc == L'\n')   /* LF. */
  68.720 -+	    {
  68.721 -+	      tab_index = 0;
  68.722 -+	      column = 0;
  68.723 -+	      convert = 1;
  68.724 -+	      putchar ('\n');
  68.725 -+	    }
  68.726 -+	  else if (wc == L'\t' && convert)	/* Tab. */
  68.727 -+	    {
  68.728 -+	      if (tab_size == 0)
  68.729 -+		{
  68.730 -+		  /* Do not let tab_index == first_free_tab;
  68.731 -+		     stop when it is 1 less. */
  68.732 -+		  while (tab_index < first_free_tab - 1
  68.733 -+		      && column >= tab_list[tab_index])
  68.734 -+		    tab_index++;
  68.735 -+		  next_tab_column = tab_list[tab_index];
  68.736 -+		  if (tab_index < first_free_tab - 1)
  68.737 -+		    tab_index++;
  68.738 -+		  if (column >= next_tab_column)
  68.739 -+		    next_tab_column = column + 1;
  68.740 -+		}
  68.741 -+	      else
  68.742 -+		next_tab_column = column + tab_size - column % tab_size;
  68.743 -+
  68.744 -+	      while (column < next_tab_column)
  68.745 -+		{
  68.746 -+		  putchar (' ');
  68.747 -+		  ++column;
  68.748 -+		}
  68.749 -+	    }
  68.750 -+	  else  /* Others. */
  68.751 -+	    {
  68.752 -+	      if (convert)
  68.753 -+		{
  68.754 -+		  if (wc == L'\b')
  68.755 -+		    {
  68.756 -+		      if (column > 0)
  68.757 -+			--column;
  68.758 -+		    }
  68.759 -+		  else
  68.760 -+		    {
  68.761 -+		      int width;		/* The width of WC. */
  68.762 -+
  68.763 -+		      width = wcwidth (wc);
  68.764 -+		      column += (width > 0) ? width : 0;
  68.765 -+		      if (convert_entire_line == 0 && !iswblank(wc))
  68.766 -+			convert = 0;
  68.767 -+		    }
  68.768 -+		}
  68.769 -+	      fwrite (bufpos, sizeof(char), mblength, stdout);
  68.770 -+	    }
  68.771 -+	}
  68.772 -+      buflen -= mblength;
  68.773 -+      bufpos += mblength;
  68.774 -+    }
  68.775 -+}
  68.776 -+#endif
  68.777 -+
  68.778 - int
  68.779 - main (int argc, char **argv)
  68.780 - {
  68.781 -@@ -421,7 +579,12 @@ main (int argc, char **argv)
  68.782 - 
  68.783 -   file_list = (optind < argc ? &argv[optind] : stdin_argv);
  68.784 - 
  68.785 --  expand ();
  68.786 -+#if HAVE_MBRTOWC
  68.787 -+  if (MB_CUR_MAX > 1)
  68.788 -+    expand_multibyte ();
  68.789 -+  else
  68.790 -+#endif
  68.791 -+    expand ();
  68.792 - 
  68.793 -   if (have_read_stdin && fclose (stdin) != 0)
  68.794 -     error (EXIT_FAILURE, errno, "-");
  68.795 -diff -Naurp coreutils-8.25-orig/src/fold.c coreutils-8.25/src/fold.c
  68.796 ---- coreutils-8.25-orig/src/fold.c	2016-01-01 07:48:50.000000000 -0600
  68.797 -+++ coreutils-8.25/src/fold.c	2016-02-08 19:07:10.302944622 -0600
  68.798 -@@ -22,11 +22,33 @@
  68.799 - #include <getopt.h>
  68.800 - #include <sys/types.h>
  68.801 - 
  68.802 -+/* Get mbstate_t, mbrtowc(), wcwidth().  */
  68.803 -+#if HAVE_WCHAR_H
  68.804 -+# include <wchar.h>
  68.805 -+#endif
  68.806 -+
  68.807 -+/* Get iswprint(), iswblank(), wcwidth().  */
  68.808 -+#if HAVE_WCTYPE_H
  68.809 -+# include <wctype.h>
  68.810 -+#endif
  68.811 -+
  68.812 - #include "system.h"
  68.813 - #include "error.h"
  68.814 - #include "fadvise.h"
  68.815 - #include "xdectoint.h"
  68.816 - 
  68.817 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
  68.818 -+      installation; work around this configuration error.  */
  68.819 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
  68.820 -+# undef MB_LEN_MAX
  68.821 -+# define MB_LEN_MAX 16
  68.822 -+#endif
  68.823 -+
  68.824 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
  68.825 -+#if HAVE_MBRTOWC && defined mbstate_t
  68.826 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
  68.827 -+#endif
  68.828 -+
  68.829 - #define TAB_WIDTH 8
  68.830 - 
  68.831 - /* The official name of this program (e.g., no 'g' prefix).  */
  68.832 -@@ -34,20 +56,41 @@
  68.833 - 
  68.834 - #define AUTHORS proper_name ("David MacKenzie")
  68.835 - 
  68.836 -+#define FATAL_ERROR(Message)                                            \
  68.837 -+  do                                                                    \
  68.838 -+    {                                                                   \
  68.839 -+      error (0, 0, (Message));                                          \
  68.840 -+      usage (2);                                                        \
  68.841 -+    }                                                                   \
  68.842 -+  while (0)
  68.843 -+
  68.844 -+enum operating_mode
  68.845 -+{
  68.846 -+  /* Fold texts by columns that are at the given positions. */
  68.847 -+  column_mode,
  68.848 -+
  68.849 -+  /* Fold texts by bytes that are at the given positions. */
  68.850 -+  byte_mode,
  68.851 -+
  68.852 -+  /* Fold texts by characters that are at the given positions. */
  68.853 -+  character_mode,
  68.854 -+};
  68.855 -+
  68.856 -+/* The argument shows current mode. (Default: column_mode) */
  68.857 -+static enum operating_mode operating_mode;
  68.858 -+
  68.859 - /* If nonzero, try to break on whitespace. */
  68.860 - static bool break_spaces;
  68.861 - 
  68.862 --/* If nonzero, count bytes, not column positions. */
  68.863 --static bool count_bytes;
  68.864 --
  68.865 - /* If nonzero, at least one of the files we read was standard input. */
  68.866 - static bool have_read_stdin;
  68.867 - 
  68.868 --static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::";
  68.869 -+static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::";
  68.870 - 
  68.871 - static struct option const longopts[] =
  68.872 - {
  68.873 -   {"bytes", no_argument, NULL, 'b'},
  68.874 -+  {"characters", no_argument, NULL, 'c'},
  68.875 -   {"spaces", no_argument, NULL, 's'},
  68.876 -   {"width", required_argument, NULL, 'w'},
  68.877 -   {GETOPT_HELP_OPTION_DECL},
  68.878 -@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing t
  68.879 - 
  68.880 -       fputs (_("\
  68.881 -   -b, --bytes         count bytes rather than columns\n\
  68.882 -+  -c, --characters    count characters rather than columns\n\
  68.883 -   -s, --spaces        break at spaces\n\
  68.884 -   -w, --width=WIDTH   use WIDTH columns instead of 80\n\
  68.885 - "), stdout);
  68.886 -@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing t
  68.887 - static size_t
  68.888 - adjust_column (size_t column, char c)
  68.889 - {
  68.890 --  if (!count_bytes)
  68.891 -+  if (operating_mode != byte_mode)
  68.892 -     {
  68.893 -       if (c == '\b')
  68.894 -         {
  68.895 -@@ -115,30 +159,14 @@ adjust_column (size_t column, char c)
  68.896 -    to stdout, with maximum line length WIDTH.
  68.897 -    Return true if successful.  */
  68.898 - 
  68.899 --static bool
  68.900 --fold_file (char const *filename, size_t width)
  68.901 -+static void
  68.902 -+fold_text (FILE *istream, size_t width, int *saved_errno)
  68.903 - {
  68.904 --  FILE *istream;
  68.905 -   int c;
  68.906 -   size_t column = 0;		/* Screen column where next char will go. */
  68.907 -   size_t offset_out = 0;	/* Index in 'line_out' for next char. */
  68.908 -   static char *line_out = NULL;
  68.909 -   static size_t allocated_out = 0;
  68.910 --  int saved_errno;
  68.911 --
  68.912 --  if (STREQ (filename, "-"))
  68.913 --    {
  68.914 --      istream = stdin;
  68.915 --      have_read_stdin = true;
  68.916 --    }
  68.917 --  else
  68.918 --    istream = fopen (filename, "r");
  68.919 --
  68.920 --  if (istream == NULL)
  68.921 --    {
  68.922 --      error (0, errno, "%s", quotef (filename));
  68.923 --      return false;
  68.924 --    }
  68.925 - 
  68.926 -   fadvise (istream, FADVISE_SEQUENTIAL);
  68.927 - 
  68.928 -@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t
  68.929 -               bool found_blank = false;
  68.930 -               size_t logical_end = offset_out;
  68.931 - 
  68.932 -+              /* If LINE_OUT has no wide character,
  68.933 -+                 put a new wide character in LINE_OUT
  68.934 -+                 if column is bigger than width. */
  68.935 -+              if (offset_out == 0)
  68.936 -+                {
  68.937 -+                  line_out[offset_out++] = c;
  68.938 -+                  continue;
  68.939 -+                }
  68.940 -+
  68.941 -               /* Look for the last blank. */
  68.942 -               while (logical_end)
  68.943 -                 {
  68.944 -@@ -214,11 +251,221 @@ fold_file (char const *filename, size_t
  68.945 -       line_out[offset_out++] = c;
  68.946 -     }
  68.947 - 
  68.948 --  saved_errno = errno;
  68.949 -+  *saved_errno = errno;
  68.950 -+
  68.951 -+  if (offset_out)
  68.952 -+    fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
  68.953 -+
  68.954 -+}
  68.955 -+
  68.956 -+#if HAVE_MBRTOWC
  68.957 -+static void
  68.958 -+fold_multibyte_text (FILE *istream, size_t width, int *saved_errno)
  68.959 -+{
  68.960 -+  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
  68.961 -+  size_t buflen = 0;        /* The length of the byte sequence in buf. */
  68.962 -+  char *bufpos = buf;         /* Next read position of BUF. */
  68.963 -+  wint_t wc;                /* A gotten wide character. */
  68.964 -+  size_t mblength;        /* The byte size of a multibyte character which shows
  68.965 -+                           as same character as WC. */
  68.966 -+  mbstate_t state, state_bak;        /* State of the stream. */
  68.967 -+  int convfail = 0;                /* 1, when conversion is failed. Otherwise 0. */
  68.968 -+
  68.969 -+  static char *line_out = NULL;
  68.970 -+  size_t offset_out = 0;        /* Index in `line_out' for next char. */
  68.971 -+  static size_t allocated_out = 0;
  68.972 -+
  68.973 -+  int increment;
  68.974 -+  size_t column = 0;
  68.975 -+
  68.976 -+  size_t last_blank_pos;
  68.977 -+  size_t last_blank_column;
  68.978 -+  int is_blank_seen;
  68.979 -+  int last_blank_increment = 0;
  68.980 -+  int is_bs_following_last_blank;
  68.981 -+  size_t bs_following_last_blank_num;
  68.982 -+  int is_cr_after_last_blank;
  68.983 -+
  68.984 -+#define CLEAR_FLAGS                                \
  68.985 -+   do                                                \
  68.986 -+     {                                                \
  68.987 -+        last_blank_pos = 0;                        \
  68.988 -+        last_blank_column = 0;                        \
  68.989 -+        is_blank_seen = 0;                        \
  68.990 -+        is_bs_following_last_blank = 0;                \
  68.991 -+        bs_following_last_blank_num = 0;        \
  68.992 -+        is_cr_after_last_blank = 0;                \
  68.993 -+     }                                                \
  68.994 -+   while (0)
  68.995 -+
  68.996 -+#define START_NEW_LINE                        \
  68.997 -+   do                                        \
  68.998 -+     {                                        \
  68.999 -+      putchar ('\n');                        \
 68.1000 -+      column = 0;                        \
 68.1001 -+      offset_out = 0;                        \
 68.1002 -+      CLEAR_FLAGS;                        \
 68.1003 -+    }                                        \
 68.1004 -+   while (0)
 68.1005 -+
 68.1006 -+  CLEAR_FLAGS;
 68.1007 -+  memset (&state, '\0', sizeof(mbstate_t));
 68.1008 -+
 68.1009 -+  for (;; bufpos += mblength, buflen -= mblength)
 68.1010 -+    {
 68.1011 -+      if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream))
 68.1012 -+        {
 68.1013 -+          memmove (buf, bufpos, buflen);
 68.1014 -+          buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream);
 68.1015 -+          bufpos = buf;
 68.1016 -+        }
 68.1017 -+
 68.1018 -+      if (buflen < 1)
 68.1019 -+        break;
 68.1020 -+
 68.1021 -+      /* Get a wide character. */
 68.1022 -+      state_bak = state;
 68.1023 -+      mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state);
 68.1024 -+
 68.1025 -+      switch (mblength)
 68.1026 -+        {
 68.1027 -+        case (size_t)-1:
 68.1028 -+        case (size_t)-2:
 68.1029 -+          convfail++;
 68.1030 -+          state = state_bak;
 68.1031 -+          /* Fall through. */
 68.1032 -+
 68.1033 -+        case 0:
 68.1034 -+          mblength = 1;
 68.1035 -+          break;
 68.1036 -+        }
 68.1037 -+
 68.1038 -+rescan:
 68.1039 -+      if (operating_mode == byte_mode)                        /* byte mode */
 68.1040 -+        increment = mblength;
 68.1041 -+      else if (operating_mode == character_mode)        /* character mode */
 68.1042 -+        increment = 1;
 68.1043 -+      else                                                /* column mode */
 68.1044 -+        {
 68.1045 -+          if (convfail)
 68.1046 -+            increment = 1;
 68.1047 -+          else
 68.1048 -+            {
 68.1049 -+              switch (wc)
 68.1050 -+                {
 68.1051 -+                case L'\n':
 68.1052 -+                  fwrite (line_out, sizeof(char), offset_out, stdout);
 68.1053 -+                  START_NEW_LINE;
 68.1054 -+                  continue;
 68.1055 -+
 68.1056 -+                case L'\b':
 68.1057 -+                  increment = (column > 0) ? -1 : 0;
 68.1058 -+                  break;
 68.1059 -+
 68.1060 -+                case L'\r':
 68.1061 -+                  increment = -1 * column;
 68.1062 -+                  break;
 68.1063 -+
 68.1064 -+                case L'\t':
 68.1065 -+                  increment = 8 - column % 8;
 68.1066 -+                  break;
 68.1067 -+
 68.1068 -+                default:
 68.1069 -+                  increment = wcwidth (wc);
 68.1070 -+                  increment = (increment < 0) ? 0 : increment;
 68.1071 -+                }
 68.1072 -+            }
 68.1073 -+        }
 68.1074 -+
 68.1075 -+      if (column + increment > width && break_spaces && last_blank_pos)
 68.1076 -+        {
 68.1077 -+          fwrite (line_out, sizeof(char), last_blank_pos, stdout);
 68.1078 -+          putchar ('\n');
 68.1079 -+
 68.1080 -+          offset_out = offset_out - last_blank_pos;
 68.1081 -+          column = column - last_blank_column + ((is_cr_after_last_blank)
 68.1082 -+              ? last_blank_increment : bs_following_last_blank_num);
 68.1083 -+          memmove (line_out, line_out + last_blank_pos, offset_out);
 68.1084 -+          CLEAR_FLAGS;
 68.1085 -+          goto rescan;
 68.1086 -+        }
 68.1087 -+
 68.1088 -+      if (column + increment > width && column != 0)
 68.1089 -+        {
 68.1090 -+          fwrite (line_out, sizeof(char), offset_out, stdout);
 68.1091 -+          START_NEW_LINE;
 68.1092 -+          goto rescan;
 68.1093 -+        }
 68.1094 -+
 68.1095 -+      if (allocated_out < offset_out + mblength)
 68.1096 -+        {
 68.1097 -+          line_out = X2REALLOC (line_out, &allocated_out);
 68.1098 -+        }
 68.1099 -+
 68.1100 -+      memcpy (line_out + offset_out, bufpos, mblength);
 68.1101 -+      offset_out += mblength;
 68.1102 -+      column += increment;
 68.1103 -+
 68.1104 -+      if (is_blank_seen && !convfail && wc == L'\r')
 68.1105 -+        is_cr_after_last_blank = 1;
 68.1106 -+
 68.1107 -+      if (is_bs_following_last_blank && !convfail && wc == L'\b')
 68.1108 -+        ++bs_following_last_blank_num;
 68.1109 -+      else
 68.1110 -+        is_bs_following_last_blank = 0;
 68.1111 -+
 68.1112 -+      if (break_spaces && !convfail && iswblank (wc))
 68.1113 -+        {
 68.1114 -+          last_blank_pos = offset_out;
 68.1115 -+          last_blank_column = column;
 68.1116 -+          is_blank_seen = 1;
 68.1117 -+          last_blank_increment = increment;
 68.1118 -+          is_bs_following_last_blank = 1;
 68.1119 -+          bs_following_last_blank_num = 0;
 68.1120 -+          is_cr_after_last_blank = 0;
 68.1121 -+        }
 68.1122 -+    }
 68.1123 -+
 68.1124 -+  *saved_errno = errno;
 68.1125 - 
 68.1126 -   if (offset_out)
 68.1127 -     fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
 68.1128 - 
 68.1129 -+}
 68.1130 -+#endif
 68.1131 -+
 68.1132 -+/* Fold file FILENAME, or standard input if FILENAME is "-",
 68.1133 -+   to stdout, with maximum line length WIDTH.
 68.1134 -+   Return 0 if successful, 1 if an error occurs. */
 68.1135 -+
 68.1136 -+static bool
 68.1137 -+fold_file (char const *filename, size_t width)
 68.1138 -+{
 68.1139 -+  FILE *istream;
 68.1140 -+  int saved_errno;
 68.1141 -+
 68.1142 -+  if (STREQ (filename, "-"))
 68.1143 -+    {
 68.1144 -+      istream = stdin;
 68.1145 -+      have_read_stdin = 1;
 68.1146 -+    }
 68.1147 -+  else
 68.1148 -+    istream = fopen (filename, "r");
 68.1149 -+
 68.1150 -+  if (istream == NULL)
 68.1151 -+    {
 68.1152 -+      error (0, errno, "%s", quotef (filename));
 68.1153 -+      return 1;
 68.1154 -+    }
 68.1155 -+
 68.1156 -+  /* Define how ISTREAM is being folded. */
 68.1157 -+#if HAVE_MBRTOWC
 68.1158 -+  if (MB_CUR_MAX > 1)
 68.1159 -+    fold_multibyte_text (istream, width, &saved_errno);
 68.1160 -+  else
 68.1161 -+#endif
 68.1162 -+    fold_text (istream, width, &saved_errno);
 68.1163 -+
 68.1164 -   if (ferror (istream))
 68.1165 -     {
 68.1166 -       error (0, saved_errno, "%s", quotef (filename));
 68.1167 -@@ -251,7 +498,8 @@ main (int argc, char **argv)
 68.1168 - 
 68.1169 -   atexit (close_stdout);
 68.1170 - 
 68.1171 --  break_spaces = count_bytes = have_read_stdin = false;
 68.1172 -+  operating_mode = column_mode;
 68.1173 -+  break_spaces = have_read_stdin = false;
 68.1174 - 
 68.1175 -   while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
 68.1176 -     {
 68.1177 -@@ -260,7 +508,15 @@ main (int argc, char **argv)
 68.1178 -       switch (optc)
 68.1179 -         {
 68.1180 -         case 'b':		/* Count bytes rather than columns. */
 68.1181 --          count_bytes = true;
 68.1182 -+          if (operating_mode != column_mode)
 68.1183 -+            FATAL_ERROR (_("only one way of folding may be specified"));
 68.1184 -+          operating_mode = byte_mode;
 68.1185 -+          break;
 68.1186 -+
 68.1187 -+        case 'c':
 68.1188 -+          if (operating_mode != column_mode)
 68.1189 -+            FATAL_ERROR (_("only one way of folding may be specified"));
 68.1190 -+          operating_mode = character_mode;
 68.1191 -           break;
 68.1192 - 
 68.1193 -         case 's':		/* Break at word boundaries. */
 68.1194 -diff -Naurp coreutils-8.25-orig/src/join.c coreutils-8.25/src/join.c
 68.1195 ---- coreutils-8.25-orig/src/join.c	2016-01-13 05:08:59.000000000 -0600
 68.1196 -+++ coreutils-8.25/src/join.c	2016-02-08 19:07:10.303944625 -0600
 68.1197 -@@ -22,18 +22,32 @@
 68.1198 - #include <sys/types.h>
 68.1199 - #include <getopt.h>
 68.1200 - 
 68.1201 -+/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth().  */
 68.1202 -+#if HAVE_WCHAR_H
 68.1203 -+# include <wchar.h>
 68.1204 -+#endif
 68.1205 -+
 68.1206 -+/* Get iswblank(), towupper.  */
 68.1207 -+#if HAVE_WCTYPE_H
 68.1208 -+# include <wctype.h>
 68.1209 -+#endif
 68.1210 -+
 68.1211 - #include "system.h"
 68.1212 - #include "error.h"
 68.1213 - #include "fadvise.h"
 68.1214 - #include "hard-locale.h"
 68.1215 - #include "linebuffer.h"
 68.1216 --#include "memcasecmp.h"
 68.1217 - #include "quote.h"
 68.1218 - #include "stdio--.h"
 68.1219 - #include "xmemcoll.h"
 68.1220 - #include "xstrtol.h"
 68.1221 - #include "argmatch.h"
 68.1222 - 
 68.1223 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
 68.1224 -+#if HAVE_MBRTOWC && defined mbstate_t
 68.1225 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
 68.1226 -+#endif
 68.1227 -+
 68.1228 - /* The official name of this program (e.g., no 'g' prefix).  */
 68.1229 - #define PROGRAM_NAME "join"
 68.1230 - 
 68.1231 -@@ -135,10 +149,12 @@ static struct outlist outlist_head;
 68.1232 - /* Last element in 'outlist', where a new element can be added.  */
 68.1233 - static struct outlist *outlist_end = &outlist_head;
 68.1234 - 
 68.1235 --/* Tab character separating fields.  If negative, fields are separated
 68.1236 --   by any nonempty string of blanks, otherwise by exactly one
 68.1237 --   tab character whose value (when cast to unsigned char) equals TAB.  */
 68.1238 --static int tab = -1;
 68.1239 -+/* Tab character separating fields.  If NULL, fields are separated
 68.1240 -+   by any nonempty string of blanks.  */
 68.1241 -+static char *tab = NULL;
 68.1242 -+
 68.1243 -+/* The number of bytes used for tab. */
 68.1244 -+static size_t tablen = 0;
 68.1245 - 
 68.1246 - /* If nonzero, check that the input is correctly ordered. */
 68.1247 - static enum
 68.1248 -@@ -275,13 +291,14 @@ xfields (struct line *line)
 68.1249 -   if (ptr == lim)
 68.1250 -     return;
 68.1251 - 
 68.1252 --  if (0 <= tab && tab != '\n')
 68.1253 -+  if (tab != NULL)
 68.1254 -     {
 68.1255 -+      unsigned char t = tab[0];
 68.1256 -       char *sep;
 68.1257 --      for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1)
 68.1258 -+      for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1)
 68.1259 -         extract_field (line, ptr, sep - ptr);
 68.1260 -     }
 68.1261 --  else if (tab < 0)
 68.1262 -+   else
 68.1263 -     {
 68.1264 -       /* Skip leading blanks before the first field.  */
 68.1265 -       while (field_sep (*ptr))
 68.1266 -@@ -305,6 +322,147 @@ xfields (struct line *line)
 68.1267 -   extract_field (line, ptr, lim - ptr);
 68.1268 - }
 68.1269 - 
 68.1270 -+#if HAVE_MBRTOWC
 68.1271 -+static void
 68.1272 -+xfields_multibyte (struct line *line)
 68.1273 -+{
 68.1274 -+  char *ptr = line->buf.buffer;
 68.1275 -+  char const *lim = ptr + line->buf.length - 1;
 68.1276 -+  wchar_t wc = 0;
 68.1277 -+  size_t mblength = 1;
 68.1278 -+  mbstate_t state, state_bak;
 68.1279 -+
 68.1280 -+  memset (&state, 0, sizeof (mbstate_t));
 68.1281 -+
 68.1282 -+  if (ptr >= lim)
 68.1283 -+    return;
 68.1284 -+
 68.1285 -+  if (tab != NULL)
 68.1286 -+    {
 68.1287 -+      char *sep = ptr;
 68.1288 -+      for (; ptr < lim; ptr = sep + mblength)
 68.1289 -+	{
 68.1290 -+	  sep = ptr;
 68.1291 -+	  while (sep < lim)
 68.1292 -+	    {
 68.1293 -+	      state_bak = state;
 68.1294 -+	      mblength = mbrtowc (&wc, sep, lim - sep + 1, &state);
 68.1295 -+
 68.1296 -+	      if (mblength == (size_t)-1 || mblength == (size_t)-2)
 68.1297 -+		{
 68.1298 -+		  mblength = 1;
 68.1299 -+		  state = state_bak;
 68.1300 -+		}
 68.1301 -+	      mblength = (mblength < 1) ? 1 : mblength;
 68.1302 -+
 68.1303 -+	      if (mblength == tablen && !memcmp (sep, tab, mblength))
 68.1304 -+		break;
 68.1305 -+	      else
 68.1306 -+		{
 68.1307 -+		  sep += mblength;
 68.1308 -+		  continue;
 68.1309 -+		}
 68.1310 -+	    }
 68.1311 -+
 68.1312 -+	  if (sep >= lim)
 68.1313 -+	    break;
 68.1314 -+
 68.1315 -+	  extract_field (line, ptr, sep - ptr);
 68.1316 -+	}
 68.1317 -+    }
 68.1318 -+  else
 68.1319 -+    {
 68.1320 -+      /* Skip leading blanks before the first field.  */
 68.1321 -+      while(ptr < lim)
 68.1322 -+      {
 68.1323 -+        state_bak = state;
 68.1324 -+        mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state);
 68.1325 -+
 68.1326 -+        if (mblength == (size_t)-1 || mblength == (size_t)-2)
 68.1327 -+          {
 68.1328 -+            mblength = 1;
 68.1329 -+            state = state_bak;
 68.1330 -+            break;
 68.1331 -+          }
 68.1332 -+        mblength = (mblength < 1) ? 1 : mblength;
 68.1333 -+
 68.1334 -+        if (!iswblank(wc) && wc != '\n')
 68.1335 -+          break;
 68.1336 -+        ptr += mblength;
 68.1337 -+      }
 68.1338 -+
 68.1339 -+      do
 68.1340 -+	{
 68.1341 -+	  char *sep;
 68.1342 -+	  state_bak = state;
 68.1343 -+	  mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state);
 68.1344 -+	  if (mblength == (size_t)-1 || mblength == (size_t)-2)
 68.1345 -+	    {
 68.1346 -+	      mblength = 1;
 68.1347 -+	      state = state_bak;
 68.1348 -+	      break;
 68.1349 -+	    }
 68.1350 -+	  mblength = (mblength < 1) ? 1 : mblength;
 68.1351 -+
 68.1352 -+	  sep = ptr + mblength;
 68.1353 -+	  while (sep < lim)
 68.1354 -+	    {
 68.1355 -+	      state_bak = state;
 68.1356 -+	      mblength = mbrtowc (&wc, sep, lim - sep + 1, &state);
 68.1357 -+	      if (mblength == (size_t)-1 || mblength == (size_t)-2)
 68.1358 -+		{
 68.1359 -+		  mblength = 1;
 68.1360 -+		  state = state_bak;
 68.1361 -+		  break;
 68.1362 -+		}
 68.1363 -+	      mblength = (mblength < 1) ? 1 : mblength;
 68.1364 -+
 68.1365 -+	      if (iswblank (wc) || wc == '\n')
 68.1366 -+		break;
 68.1367 -+
 68.1368 -+	      sep += mblength;
 68.1369 -+	    }
 68.1370 -+
 68.1371 -+	  extract_field (line, ptr, sep - ptr);
 68.1372 -+	  if (sep >= lim)
 68.1373 -+	    return;
 68.1374 -+
 68.1375 -+	  state_bak = state;
 68.1376 -+	  mblength = mbrtowc (&wc, sep, lim - sep + 1, &state);
 68.1377 -+	  if (mblength == (size_t)-1 || mblength == (size_t)-2)
 68.1378 -+	    {
 68.1379 -+	      mblength = 1;
 68.1380 -+	      state = state_bak;
 68.1381 -+	      break;
 68.1382 -+	    }
 68.1383 -+	  mblength = (mblength < 1) ? 1 : mblength;
 68.1384 -+
 68.1385 -+	  ptr = sep + mblength;
 68.1386 -+	  while (ptr < lim)
 68.1387 -+	    {
 68.1388 -+	      state_bak = state;
 68.1389 -+	      mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state);
 68.1390 -+	      if (mblength == (size_t)-1 || mblength == (size_t)-2)
 68.1391 -+		{
 68.1392 -+		  mblength = 1;
 68.1393 -+		  state = state_bak;
 68.1394 -+		  break;
 68.1395 -+		}
 68.1396 -+	      mblength = (mblength < 1) ? 1 : mblength;
 68.1397 -+
 68.1398 -+	      if (!iswblank (wc) && wc != '\n')
 68.1399 -+		break;
 68.1400 -+
 68.1401 -+	      ptr += mblength;
 68.1402 -+	    }
 68.1403 -+	}
 68.1404 -+      while (ptr < lim);
 68.1405 -+    }
 68.1406 -+
 68.1407 -+  extract_field (line, ptr, lim - ptr);
 68.1408 -+}
 68.1409 -+#endif
 68.1410 -+
 68.1411 - static void
 68.1412 - freeline (struct line *line)
 68.1413 - {
 68.1414 -@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct
 68.1415 -         size_t jf_1, size_t jf_2)
 68.1416 - {
 68.1417 -   /* Start of field to compare in each file.  */
 68.1418 --  char *beg1;
 68.1419 --  char *beg2;
 68.1420 --
 68.1421 --  size_t len1;
 68.1422 --  size_t len2;		/* Length of fields to compare.  */
 68.1423 -+  char *beg[2];
 68.1424 -+  char *copy[2];
 68.1425 -+  size_t len[2]; 	/* Length of fields to compare.  */
 68.1426 -   int diff;
 68.1427 -+  int i, j;
 68.1428 -+  int mallocd = 0;
 68.1429 - 
 68.1430 -   if (jf_1 < line1->nfields)
 68.1431 -     {
 68.1432 --      beg1 = line1->fields[jf_1].beg;
 68.1433 --      len1 = line1->fields[jf_1].len;
 68.1434 -+      beg[0] = line1->fields[jf_1].beg;
 68.1435 -+      len[0] = line1->fields[jf_1].len;
 68.1436 -     }
 68.1437 -   else
 68.1438 -     {
 68.1439 --      beg1 = NULL;
 68.1440 --      len1 = 0;
 68.1441 -+      beg[0] = NULL;
 68.1442 -+      len[0] = 0;
 68.1443 -     }
 68.1444 - 
 68.1445 -   if (jf_2 < line2->nfields)
 68.1446 -     {
 68.1447 --      beg2 = line2->fields[jf_2].beg;
 68.1448 --      len2 = line2->fields[jf_2].len;
 68.1449 -+      beg[1] = line2->fields[jf_2].beg;
 68.1450 -+      len[1] = line2->fields[jf_2].len;
 68.1451 -     }
 68.1452 -   else
 68.1453 -     {
 68.1454 --      beg2 = NULL;
 68.1455 --      len2 = 0;
 68.1456 -+      beg[1] = NULL;
 68.1457 -+      len[1] = 0;
 68.1458 -     }
 68.1459 - 
 68.1460 --  if (len1 == 0)
 68.1461 --    return len2 == 0 ? 0 : -1;
 68.1462 --  if (len2 == 0)
 68.1463 -+  if (len[0] == 0)
 68.1464 -+    return len[1] == 0 ? 0 : -1;
 68.1465 -+  if (len[1] == 0)
 68.1466 -     return 1;
 68.1467 - 
 68.1468 -   if (ignore_case)
 68.1469 -     {
 68.1470 --      /* FIXME: ignore_case does not work with NLS (in particular,
 68.1471 --         with multibyte chars).  */
 68.1472 --      diff = memcasecmp (beg1, beg2, MIN (len1, len2));
 68.1473 -+#ifdef HAVE_MBRTOWC
 68.1474 -+      if (MB_CUR_MAX > 1)
 68.1475 -+      {
 68.1476 -+        size_t mblength;
 68.1477 -+        wchar_t wc, uwc;
 68.1478 -+        mbstate_t state, state_bak;
 68.1479 -+
 68.1480 -+        memset (&state, '\0', sizeof (mbstate_t));
 68.1481 -+
 68.1482 -+        for (i = 0; i < 2; i++)
 68.1483 -+          {
 68.1484 -+            mallocd = 1;
 68.1485 -+            copy[i] = xmalloc (len[i] + 1);
 68.1486 -+            memset (copy[i], '\0',len[i] + 1);
 68.1487 -+
 68.1488 -+            for (j = 0; j < MIN (len[0], len[1]);)
 68.1489 -+              {
 68.1490 -+                state_bak = state;
 68.1491 -+                mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state);
 68.1492 -+
 68.1493 -+                switch (mblength)
 68.1494 -+                  {
 68.1495 -+                  case (size_t) -1:
 68.1496 -+                  case (size_t) -2:
 68.1497 -+                    state = state_bak;
 68.1498 -+                    /* Fall through */
 68.1499 -+                  case 0:
 68.1500 -+                    mblength = 1;
 68.1501 -+                    break;
 68.1502 -+
 68.1503 -+                  default:
 68.1504 -+                    uwc = towupper (wc);
 68.1505 -+
 68.1506 -+                    if (uwc != wc)
 68.1507 -+                      {
 68.1508 -+                        mbstate_t state_wc;
 68.1509 -+                        size_t mblen;
 68.1510 -+
 68.1511 -+                        memset (&state_wc, '\0', sizeof (mbstate_t));
 68.1512 -+                        mblen = wcrtomb (copy[i] + j, uwc, &state_wc);
 68.1513 -+                        assert (mblen != (size_t)-1);
 68.1514 -+                      }
 68.1515 -+                    else
 68.1516 -+                      memcpy (copy[i] + j, beg[i] + j, mblength);
 68.1517 -+                  }
 68.1518 -+                j += mblength;
 68.1519 -+              }
 68.1520 -+            copy[i][j] = '\0';
 68.1521 -+          }
 68.1522 -+      }
 68.1523 -+      else
 68.1524 -+#endif
 68.1525 -+      {
 68.1526 -+        for (i = 0; i < 2; i++)
 68.1527 -+          {
 68.1528 -+            mallocd = 1;
 68.1529 -+            copy[i] = xmalloc (len[i] + 1);
 68.1530 -+
 68.1531 -+            for (j = 0; j < MIN (len[0], len[1]); j++)
 68.1532 -+              copy[i][j] = toupper (beg[i][j]);
 68.1533 -+
 68.1534 -+            copy[i][j] = '\0';
 68.1535 -+          }
 68.1536 -+      }
 68.1537 -     }
 68.1538 -   else
 68.1539 -     {
 68.1540 --      if (hard_LC_COLLATE)
 68.1541 --        return xmemcoll (beg1, len1, beg2, len2);
 68.1542 --      diff = memcmp (beg1, beg2, MIN (len1, len2));
 68.1543 -+      copy[0] = beg[0];
 68.1544 -+      copy[1] = beg[1];
 68.1545 -+    }
 68.1546 -+
 68.1547 -+  if (hard_LC_COLLATE)
 68.1548 -+    {
 68.1549 -+      diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]);
 68.1550 -+
 68.1551 -+      if (mallocd)
 68.1552 -+        for (i = 0; i < 2; i++)
 68.1553 -+          free (copy[i]);
 68.1554 -+
 68.1555 -+      return diff;
 68.1556 -     }
 68.1557 -+  diff = memcmp (copy[0], copy[1], MIN (len[0], len[1]));
 68.1558 -+
 68.1559 -+  if (mallocd)
 68.1560 -+    for (i = 0; i < 2; i++)
 68.1561 -+      free (copy[i]);
 68.1562 -+
 68.1563 - 
 68.1564 -   if (diff)
 68.1565 -     return diff;
 68.1566 --  return len1 < len2 ? -1 : len1 != len2;
 68.1567 -+  return len[0] - len[1];
 68.1568 - }
 68.1569 - 
 68.1570 - /* Check that successive input lines PREV and CURRENT from input file
 68.1571 -@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep,
 68.1572 -     }
 68.1573 -   ++line_no[which - 1];
 68.1574 - 
 68.1575 -+#if HAVE_MBRTOWC
 68.1576 -+  if (MB_CUR_MAX > 1)
 68.1577 -+    xfields_multibyte (line);
 68.1578 -+  else
 68.1579 -+#endif
 68.1580 -   xfields (line);
 68.1581 - 
 68.1582 -   if (prevline[which - 1])
 68.1583 -@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *li
 68.1584 - 
 68.1585 - /* Output all the fields in line, other than the join field.  */
 68.1586 - 
 68.1587 -+#define PUT_TAB_CHAR							\
 68.1588 -+  do									\
 68.1589 -+    {									\
 68.1590 -+      (tab != NULL) ?							\
 68.1591 -+	fwrite(tab, sizeof(char), tablen, stdout) : putchar (' ');	\
 68.1592 -+    }									\
 68.1593 -+  while (0)
 68.1594 -+
 68.1595 - static void
 68.1596 - prfields (struct line const *line, size_t join_field, size_t autocount)
 68.1597 - {
 68.1598 -   size_t i;
 68.1599 -   size_t nfields = autoformat ? autocount : line->nfields;
 68.1600 --  char output_separator = tab < 0 ? ' ' : tab;
 68.1601 - 
 68.1602 -   for (i = 0; i < join_field && i < nfields; ++i)
 68.1603 -     {
 68.1604 --      putchar (output_separator);
 68.1605 -+      PUT_TAB_CHAR;
 68.1606 -       prfield (i, line);
 68.1607 -     }
 68.1608 -   for (i = join_field + 1; i < nfields; ++i)
 68.1609 -     {
 68.1610 --      putchar (output_separator);
 68.1611 -+      PUT_TAB_CHAR;
 68.1612 -       prfield (i, line);
 68.1613 -     }
 68.1614 - }
 68.1615 -@@ -591,7 +838,6 @@ static void
 68.1616 - prjoin (struct line const *line1, struct line const *line2)
 68.1617 - {
 68.1618 -   const struct outlist *outlist;
 68.1619 --  char output_separator = tab < 0 ? ' ' : tab;
 68.1620 -   size_t field;
 68.1621 -   struct line const *line;
 68.1622 - 
 68.1623 -@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct
 68.1624 -           o = o->next;
 68.1625 -           if (o == NULL)
 68.1626 -             break;
 68.1627 --          putchar (output_separator);
 68.1628 -+          PUT_TAB_CHAR;
 68.1629 -         }
 68.1630 -       putchar (eolchar);
 68.1631 -     }
 68.1632 -@@ -1103,21 +1349,46 @@ main (int argc, char **argv)
 68.1633 - 
 68.1634 -         case 't':
 68.1635 -           {
 68.1636 --            unsigned char newtab = optarg[0];
 68.1637 -+            char *newtab = NULL;
 68.1638 -+            size_t newtablen;
 68.1639 -+            newtab = xstrdup (optarg);
 68.1640 -+#if HAVE_MBRTOWC
 68.1641 -+            if (MB_CUR_MAX > 1)
 68.1642 -+              {
 68.1643 -+                mbstate_t state;
 68.1644 -+
 68.1645 -+                memset (&state, 0, sizeof (mbstate_t));
 68.1646 -+                newtablen = mbrtowc (NULL, newtab,
 68.1647 -+                                     strnlen (newtab, MB_LEN_MAX),
 68.1648 -+                                     &state);
 68.1649 -+                if (newtablen == (size_t) 0
 68.1650 -+                    || newtablen == (size_t) -1
 68.1651 -+                    || newtablen == (size_t) -2)
 68.1652 -+                  newtablen = 1;
 68.1653 -+              }
 68.1654 -+            else
 68.1655 -+#endif
 68.1656 -+              newtablen = 1;
 68.1657 -             if (! newtab)
 68.1658 --              newtab = '\n'; /* '' => process the whole line.  */
 68.1659 -+            {
 68.1660 -+              newtab = (char*)"\n"; /* '' => process the whole line.  */
 68.1661 -+            }
 68.1662 -             else if (optarg[1])
 68.1663 -               {
 68.1664 --                if (STREQ (optarg, "\\0"))
 68.1665 --                  newtab = '\0';
 68.1666 --                else
 68.1667 --                  error (EXIT_FAILURE, 0, _("multi-character tab %s"),
 68.1668 --                         quote (optarg));
 68.1669 -+                if (newtablen == 1 && newtab[1])
 68.1670 -+                {
 68.1671 -+                  if (STREQ (newtab, "\\0"))
 68.1672 -+                     newtab[0] = '\0';
 68.1673 -+                }
 68.1674 -+              }
 68.1675 -+            if (tab != NULL && strcmp (tab, newtab))
 68.1676 -+              {
 68.1677 -+                free (newtab);
 68.1678 -+                error (EXIT_FAILURE, 0, _("incompatible tabs"));
 68.1679 -               }
 68.1680 --            if (0 <= tab && tab != newtab)
 68.1681 --              error (EXIT_FAILURE, 0, _("incompatible tabs"));
 68.1682 -             tab = newtab;
 68.1683 --          }
 68.1684 -+            tablen = newtablen;
 68.1685 -+           }
 68.1686 -           break;
 68.1687 - 
 68.1688 -         case 'z':
 68.1689 -diff -Naurp coreutils-8.25-orig/src/pr.c coreutils-8.25/src/pr.c
 68.1690 ---- coreutils-8.25-orig/src/pr.c	2016-01-01 07:48:50.000000000 -0600
 68.1691 -+++ coreutils-8.25/src/pr.c	2016-02-08 19:07:10.306944635 -0600
 68.1692 -@@ -311,6 +311,24 @@
 68.1693 - 
 68.1694 - #include <getopt.h>
 68.1695 - #include <sys/types.h>
 68.1696 -+
 68.1697 -+/* Get MB_LEN_MAX.  */
 68.1698 -+#include <limits.h>
 68.1699 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
 68.1700 -+   installation; work around this configuration error.  */
 68.1701 -+#if !defined MB_LEN_MAX || MB_LEN_MAX == 1
 68.1702 -+# define MB_LEN_MAX 16
 68.1703 -+#endif
 68.1704 -+
 68.1705 -+/* Get MB_CUR_MAX.  */
 68.1706 -+#include <stdlib.h>
 68.1707 -+
 68.1708 -+/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
 68.1709 -+/* Get mbstate_t, mbrtowc(), wcwidth().  */
 68.1710 -+#if HAVE_WCHAR_H
 68.1711 -+# include <wchar.h>
 68.1712 -+#endif
 68.1713 -+
 68.1714 - #include "system.h"
 68.1715 - #include "error.h"
 68.1716 - #include "fadvise.h"
 68.1717 -@@ -323,6 +341,18 @@
 68.1718 - #include "xstrtol.h"
 68.1719 - #include "xdectoint.h"
 68.1720 - 
 68.1721 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
 68.1722 -+#if HAVE_MBRTOWC && defined mbstate_t
 68.1723 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
 68.1724 -+#endif
 68.1725 -+
 68.1726 -+#ifndef HAVE_DECL_WCWIDTH
 68.1727 -+"this configure-time declaration test was not run"
 68.1728 -+#endif
 68.1729 -+#if !HAVE_DECL_WCWIDTH
 68.1730 -+extern int wcwidth ();
 68.1731 -+#endif
 68.1732 -+
 68.1733 - /* The official name of this program (e.g., no 'g' prefix).  */
 68.1734 - #define PROGRAM_NAME "pr"
 68.1735 - 
 68.1736 -@@ -415,7 +445,20 @@ struct COLUMN
 68.1737 - 
 68.1738 - typedef struct COLUMN COLUMN;
 68.1739 - 
 68.1740 --static int char_to_clump (char c);
 68.1741 -+/* Funtion pointers to switch functions for single byte locale or for
 68.1742 -+   multibyte locale. If multibyte functions do not exist in your sysytem,
 68.1743 -+   these pointers always point the function for single byte locale. */
 68.1744 -+static void (*print_char) (char c);
 68.1745 -+static int (*char_to_clump) (char c);
 68.1746 -+
 68.1747 -+/* Functions for single byte locale. */
 68.1748 -+static void print_char_single (char c);
 68.1749 -+static int char_to_clump_single (char c);
 68.1750 -+
 68.1751 -+/* Functions for multibyte locale. */
 68.1752 -+static void print_char_multi (char c);
 68.1753 -+static int char_to_clump_multi (char c);
 68.1754 -+
 68.1755 - static bool read_line (COLUMN *p);
 68.1756 - static bool print_page (void);
 68.1757 - static bool print_stored (COLUMN *p);
 68.1758 -@@ -427,6 +470,7 @@ static void add_line_number (COLUMN *p);
 68.1759 - static void getoptnum (const char *n_str, int min, int *num,
 68.1760 -                        const char *errfmt);
 68.1761 - static void getoptarg (char *arg, char switch_char, char *character,
 68.1762 -+                       int *character_length, int *character_width,
 68.1763 -                        int *number);
 68.1764 - static void print_files (int number_of_files, char **av);
 68.1765 - static void init_parameters (int number_of_files);
 68.1766 -@@ -440,7 +484,6 @@ static void store_char (char c);
 68.1767 - static void pad_down (unsigned int lines);
 68.1768 - static void read_rest_of_line (COLUMN *p);
 68.1769 - static void skip_read (COLUMN *p, int column_number);
 68.1770 --static void print_char (char c);
 68.1771 - static void cleanup (void);
 68.1772 - static void print_sep_string (void);
 68.1773 - static void separator_string (const char *optarg_S);
 68.1774 -@@ -452,7 +495,7 @@ static COLUMN *column_vector;
 68.1775 -    we store the leftmost columns contiguously in buff.
 68.1776 -    To print a line from buff, get the index of the first character
 68.1777 -    from line_vector[i], and print up to line_vector[i + 1]. */
 68.1778 --static char *buff;
 68.1779 -+static unsigned char *buff;
 68.1780 - 
 68.1781 - /* Index of the position in buff where the next character
 68.1782 -    will be stored. */
 68.1783 -@@ -556,7 +599,7 @@ static int chars_per_column;
 68.1784 - static bool untabify_input = false;
 68.1785 - 
 68.1786 - /* (-e) The input tab character. */
 68.1787 --static char input_tab_char = '\t';
 68.1788 -+static char input_tab_char[MB_LEN_MAX] = "\t";
 68.1789 - 
 68.1790 - /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ...
 68.1791 -    where the leftmost column is 1. */
 68.1792 -@@ -566,7 +609,10 @@ static int chars_per_input_tab = 8;
 68.1793 - static bool tabify_output = false;
 68.1794 - 
 68.1795 - /* (-i) The output tab character. */
 68.1796 --static char output_tab_char = '\t';
 68.1797 -+static char output_tab_char[MB_LEN_MAX] = "\t";
 68.1798 -+
 68.1799 -+/* (-i) The byte length of output tab character. */
 68.1800 -+static int output_tab_char_length = 1;
 68.1801 - 
 68.1802 - /* (-i) The width of the output tab. */
 68.1803 - static int chars_per_output_tab = 8;
 68.1804 -@@ -636,7 +682,13 @@ static int line_number;
 68.1805 - static bool numbered_lines = false;
 68.1806 - 
 68.1807 - /* (-n) Character which follows each line number. */
 68.1808 --static char number_separator = '\t';
 68.1809 -+static char number_separator[MB_LEN_MAX] = "\t";
 68.1810 -+
 68.1811 -+/* (-n) The byte length of the character which follows each line number. */
 68.1812 -+static int number_separator_length = 1;
 68.1813 -+
 68.1814 -+/* (-n) The character width of the character which follows each line number. */
 68.1815 -+static int number_separator_width = 0;
 68.1816 - 
 68.1817 - /* (-n) line counting starts with 1st line of input file (not with 1st
 68.1818 -    line of 1st page printed). */
 68.1819 -@@ -689,6 +741,7 @@ static bool use_col_separator = false;
 68.1820 -    -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */
 68.1821 - static char *col_sep_string = (char *) "";
 68.1822 - static int col_sep_length = 0;
 68.1823 -+static int col_sep_width = 0;
 68.1824 - static char *column_separator = (char *) " ";
 68.1825 - static char *line_separator = (char *) "\t";
 68.1826 - 
 68.1827 -@@ -839,6 +892,13 @@ separator_string (const char *optarg_S)
 68.1828 -   col_sep_length = (int) strlen (optarg_S);
 68.1829 -   col_sep_string = xmalloc (col_sep_length + 1);
 68.1830 -   strcpy (col_sep_string, optarg_S);
 68.1831 -+
 68.1832 -+#if HAVE_MBRTOWC
 68.1833 -+  if (MB_CUR_MAX > 1)
 68.1834 -+    col_sep_width = mbswidth (col_sep_string, 0);
 68.1835 -+  else
 68.1836 -+#endif
 68.1837 -+    col_sep_width = col_sep_length;
 68.1838 - }
 68.1839 - 
 68.1840 - int
 68.1841 -@@ -863,6 +923,21 @@ main (int argc, char **argv)
 68.1842 - 
 68.1843 -   atexit (close_stdout);
 68.1844 - 
 68.1845 -+/* Define which functions are used, the ones for single byte locale or the ones
 68.1846 -+   for multibyte locale. */
 68.1847 -+#if HAVE_MBRTOWC
 68.1848 -+  if (MB_CUR_MAX > 1)
 68.1849 -+    {
 68.1850 -+      print_char = print_char_multi;
 68.1851 -+      char_to_clump = char_to_clump_multi;
 68.1852 -+    }
 68.1853 -+  else
 68.1854 -+#endif
 68.1855 -+    {
 68.1856 -+      print_char = print_char_single;
 68.1857 -+      char_to_clump = char_to_clump_single;
 68.1858 -+    }
 68.1859 -+
 68.1860 -   n_files = 0;
 68.1861 -   file_names = (argc > 1
 68.1862 -                 ? xmalloc ((argc - 1) * sizeof (char *))
 68.1863 -@@ -939,8 +1014,12 @@ main (int argc, char **argv)
 68.1864 -           break;
 68.1865 -         case 'e':
 68.1866 -           if (optarg)
 68.1867 --            getoptarg (optarg, 'e', &input_tab_char,
 68.1868 --                       &chars_per_input_tab);
 68.1869 -+            {
 68.1870 -+              int dummy_length, dummy_width;
 68.1871 -+
 68.1872 -+              getoptarg (optarg, 'e', input_tab_char, &dummy_length,
 68.1873 -+                         &dummy_width, &chars_per_input_tab);
 68.1874 -+            }
 68.1875 -           /* Could check tab width > 0. */
 68.1876 -           untabify_input = true;
 68.1877 -           break;
 68.1878 -@@ -953,8 +1032,12 @@ main (int argc, char **argv)
 68.1879 -           break;
 68.1880 -         case 'i':
 68.1881 -           if (optarg)
 68.1882 --            getoptarg (optarg, 'i', &output_tab_char,
 68.1883 --                       &chars_per_output_tab);
 68.1884 -+            {
 68.1885 -+              int dummy_width;
 68.1886 -+
 68.1887 -+              getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length,
 68.1888 -+                         &dummy_width, &chars_per_output_tab);
 68.1889 -+            }
 68.1890 -           /* Could check tab width > 0. */
 68.1891 -           tabify_output = true;
 68.1892 -           break;
 68.1893 -@@ -972,8 +1055,8 @@ main (int argc, char **argv)
 68.1894 -         case 'n':
 68.1895 -           numbered_lines = true;
 68.1896 -           if (optarg)
 68.1897 --            getoptarg (optarg, 'n', &number_separator,
 68.1898 --                       &chars_per_number);
 68.1899 -+            getoptarg (optarg, 'n', number_separator, &number_separator_length,
 68.1900 -+                       &number_separator_width, &chars_per_number);
 68.1901 -           break;
 68.1902 -         case 'N':
 68.1903 -           skip_count = false;
 68.1904 -@@ -997,7 +1080,7 @@ main (int argc, char **argv)
 68.1905 -           old_s = false;
 68.1906 -           /* Reset an additional input of -s, -S dominates -s */
 68.1907 -           col_sep_string = bad_cast ("");
 68.1908 --          col_sep_length = 0;
 68.1909 -+          col_sep_length = col_sep_width = 0;
 68.1910 -           use_col_separator = true;
 68.1911 -           if (optarg)
 68.1912 -             separator_string (optarg);
 68.1913 -@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, i
 68.1914 -    a number. */
 68.1915 - 
 68.1916 - static void
 68.1917 --getoptarg (char *arg, char switch_char, char *character, int *number)
 68.1918 -+getoptarg (char *arg, char switch_char, char *character, int *character_length,
 68.1919 -+           int *character_width, int *number)
 68.1920 - {
 68.1921 -   if (!ISDIGIT (*arg))
 68.1922 --    *character = *arg++;
 68.1923 -+    {
 68.1924 -+#ifdef HAVE_MBRTOWC
 68.1925 -+      if (MB_CUR_MAX > 1)        /* for multibyte locale. */
 68.1926 -+        {
 68.1927 -+          wchar_t wc;
 68.1928 -+          size_t mblength;
 68.1929 -+          int width;
 68.1930 -+          mbstate_t state = {'\0'};
 68.1931 -+
 68.1932 -+          mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state);
 68.1933 -+
 68.1934 -+          if (mblength == (size_t)-1 || mblength == (size_t)-2)
 68.1935 -+            {
 68.1936 -+              *character_length = 1;
 68.1937 -+              *character_width = 1;
 68.1938 -+            }
 68.1939 -+          else
 68.1940 -+            {
 68.1941 -+              *character_length = (mblength < 1) ? 1 : mblength;
 68.1942 -+              width = wcwidth (wc);
 68.1943 -+              *character_width = (width < 0) ? 0 : width;
 68.1944 -+            }
 68.1945 -+
 68.1946 -+          strncpy (character, arg, *character_length);
 68.1947 -+          arg += *character_length;
 68.1948 -+        }
 68.1949 -+      else                        /* for single byte locale. */
 68.1950 -+#endif
 68.1951 -+        {
 68.1952 -+          *character = *arg++;
 68.1953 -+          *character_length = 1;
 68.1954 -+          *character_width = 1;
 68.1955 -+        }
 68.1956 -+    }
 68.1957 -+
 68.1958 -   if (*arg)
 68.1959 -     {
 68.1960 -       long int tmp_long;
 68.1961 -@@ -1177,6 +1295,11 @@ static void
 68.1962 - init_parameters (int number_of_files)
 68.1963 - {
 68.1964 -   int chars_used_by_number = 0;
 68.1965 -+  int mb_len = 1;
 68.1966 -+#if HAVE_MBRTOWC
 68.1967 -+  if (MB_CUR_MAX > 1)
 68.1968 -+    mb_len = MB_LEN_MAX;
 68.1969 -+#endif
 68.1970 - 
 68.1971 -   lines_per_body = lines_per_page - lines_per_header - lines_per_footer;
 68.1972 -   if (lines_per_body <= 0)
 68.1973 -@@ -1214,7 +1337,7 @@ init_parameters (int number_of_files)
 68.1974 -           else
 68.1975 -             col_sep_string = column_separator;
 68.1976 - 
 68.1977 --          col_sep_length = 1;
 68.1978 -+          col_sep_length = col_sep_width = 1;
 68.1979 -           use_col_separator = true;
 68.1980 -         }
 68.1981 -       /* It's rather pointless to define a TAB separator with column
 68.1982 -@@ -1244,11 +1367,11 @@ init_parameters (int number_of_files)
 68.1983 -              + TAB_WIDTH (chars_per_input_tab, chars_per_number);   */
 68.1984 - 
 68.1985 -       /* Estimate chars_per_text without any margin and keep it constant. */
 68.1986 --      if (number_separator == '\t')
 68.1987 -+      if (number_separator[0] == '\t')
 68.1988 -         number_width = (chars_per_number
 68.1989 -                         + TAB_WIDTH (chars_per_default_tab, chars_per_number));
 68.1990 -       else
 68.1991 --        number_width = chars_per_number + 1;
 68.1992 -+        number_width = chars_per_number + number_separator_width;
 68.1993 - 
 68.1994 -       /* The number is part of the column width unless we are
 68.1995 -          printing files in parallel. */
 68.1996 -@@ -1257,7 +1380,7 @@ init_parameters (int number_of_files)
 68.1997 -     }
 68.1998 - 
 68.1999 -   chars_per_column = (chars_per_line - chars_used_by_number
 68.2000 --                      - (columns - 1) * col_sep_length) / columns;
 68.2001 -+                      - (columns - 1) * col_sep_width) / columns;
 68.2002 - 
 68.2003 -   if (chars_per_column < 1)
 68.2004 -     error (EXIT_FAILURE, 0, _("page width too narrow"));
 68.2005 -@@ -1275,7 +1398,7 @@ init_parameters (int number_of_files)
 68.2006 -      We've to use 8 as the lower limit, if we use chars_per_default_tab = 8
 68.2007 -      to expand a tab which is not an input_tab-char. */
 68.2008 -   free (clump_buff);
 68.2009 --  clump_buff = xmalloc (MAX (8, chars_per_input_tab));
 68.2010 -+  clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab));
 68.2011 - }
 68.2012 - 
 68.2013 - /* Open the necessary files,
 68.2014 -@@ -1383,7 +1506,7 @@ init_funcs (void)
 68.2015 - 
 68.2016 -   /* Enlarge p->start_position of first column to use the same form of
 68.2017 -      padding_not_printed with all columns. */
 68.2018 --  h = h + col_sep_length;
 68.2019 -+  h = h + col_sep_width;
 68.2020 - 
 68.2021 -   /* This loop takes care of all but the rightmost column. */
 68.2022 - 
 68.2023 -@@ -1417,7 +1540,7 @@ init_funcs (void)
 68.2024 -         }
 68.2025 -       else
 68.2026 -         {
 68.2027 --          h = h_next + col_sep_length;
 68.2028 -+          h = h_next + col_sep_width;
 68.2029 -           h_next = h + chars_per_column;
 68.2030 -         }
 68.2031 -     }
 68.2032 -@@ -1708,9 +1831,9 @@ static void
 68.2033 - align_column (COLUMN *p)
 68.2034 - {
 68.2035 -   padding_not_printed = p->start_position;
 68.2036 --  if (padding_not_printed - col_sep_length > 0)
 68.2037 -+  if (padding_not_printed - col_sep_width > 0)
 68.2038 -     {
 68.2039 --      pad_across_to (padding_not_printed - col_sep_length);
 68.2040 -+      pad_across_to (padding_not_printed - col_sep_width);
 68.2041 -       padding_not_printed = ANYWHERE;
 68.2042 -     }
 68.2043 - 
 68.2044 -@@ -1981,13 +2104,13 @@ store_char (char c)
 68.2045 -       /* May be too generous. */
 68.2046 -       buff = X2REALLOC (buff, &buff_allocated);
 68.2047 -     }
 68.2048 --  buff[buff_current++] = c;
 68.2049 -+  buff[buff_current++] = (unsigned char) c;
 68.2050 - }
 68.2051 - 
 68.2052 - static void
 68.2053 - add_line_number (COLUMN *p)
 68.2054 - {
 68.2055 --  int i;
 68.2056 -+  int i, j;
 68.2057 -   char *s;
 68.2058 -   int num_width;
 68.2059 - 
 68.2060 -@@ -2004,22 +2127,24 @@ add_line_number (COLUMN *p)
 68.2061 -       /* Tabification is assumed for multiple columns, also for n-separators,
 68.2062 -          but 'default n-separator = TAB' hasn't been given priority over
 68.2063 -          equal column_width also specified by POSIX. */
 68.2064 --      if (number_separator == '\t')
 68.2065 -+      if (number_separator[0] == '\t')
 68.2066 -         {
 68.2067 -           i = number_width - chars_per_number;
 68.2068 -           while (i-- > 0)
 68.2069 -             (p->char_func) (' ');
 68.2070 -         }
 68.2071 -       else
 68.2072 --        (p->char_func) (number_separator);
 68.2073 -+        for (j = 0; j < number_separator_length; j++)
 68.2074 -+          (p->char_func) (number_separator[j]);
 68.2075 -     }
 68.2076 -   else
 68.2077 -     /* To comply with POSIX, we avoid any expansion of default TAB
 68.2078 -        separator with a single column output. No column_width requirement
 68.2079 -        has to be considered. */
 68.2080 -     {
 68.2081 --      (p->char_func) (number_separator);
 68.2082 --      if (number_separator == '\t')
 68.2083 -+      for (j = 0; j < number_separator_length; j++)
 68.2084 -+        (p->char_func) (number_separator[j]);
 68.2085 -+      if (number_separator[0] == '\t')
 68.2086 -         output_position = POS_AFTER_TAB (chars_per_output_tab,
 68.2087 -                           output_position);
 68.2088 -     }
 68.2089 -@@ -2180,7 +2305,7 @@ print_white_space (void)
 68.2090 -   while (goal - h_old > 1
 68.2091 -          && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal)
 68.2092 -     {
 68.2093 --      putchar (output_tab_char);
 68.2094 -+      fwrite (output_tab_char, sizeof(char), output_tab_char_length, stdout);
 68.2095 -       h_old = h_new;
 68.2096 -     }
 68.2097 -   while (++h_old <= goal)
 68.2098 -@@ -2200,6 +2325,7 @@ print_sep_string (void)
 68.2099 - {
 68.2100 -   char *s;
 68.2101 -   int l = col_sep_length;
 68.2102 -+  int not_space_flag;
 68.2103 - 
 68.2104 -   s = col_sep_string;
 68.2105 - 
 68.2106 -@@ -2213,6 +2339,7 @@ print_sep_string (void)
 68.2107 -     {
 68.2108 -       for (; separators_not_printed > 0; --separators_not_printed)
 68.2109 -         {
 68.2110 -+          not_space_flag = 0;
 68.2111 -           while (l-- > 0)
 68.2112 -             {
 68.2113 -               /* 3 types of sep_strings: spaces only, spaces and chars,
 68.2114 -@@ -2226,12 +2353,15 @@ print_sep_string (void)
 68.2115 -                 }
 68.2116 -               else
 68.2117 -                 {
 68.2118 -+                  not_space_flag = 1;
 68.2119 -                   if (spaces_not_printed > 0)
 68.2120 -                     print_white_space ();
 68.2121 -                   putchar (*s++);
 68.2122 --                  ++output_position;
 68.2123 -                 }
 68.2124 -             }
 68.2125 -+          if (not_space_flag)
 68.2126 -+            output_position += col_sep_width;
 68.2127 -+
 68.2128 -           /* sep_string ends with some spaces */
 68.2129 -           if (spaces_not_printed > 0)
 68.2130 -             print_white_space ();
 68.2131 -@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clu
 68.2132 -    required number of tabs and spaces. */
 68.2133 - 
 68.2134 - static void
 68.2135 --print_char (char c)
 68.2136 -+print_char_single (char c)
 68.2137 - {
 68.2138 -   if (tabify_output)
 68.2139 -     {
 68.2140 -@@ -2283,6 +2413,74 @@ print_char (char c)
 68.2141 -   putchar (c);
 68.2142 - }
 68.2143 - 
 68.2144 -+#ifdef HAVE_MBRTOWC
 68.2145 -+static void
 68.2146 -+print_char_multi (char c)
 68.2147 -+{
 68.2148 -+  static size_t mbc_pos = 0;
 68.2149 -+  static char mbc[MB_LEN_MAX] = {'\0'};
 68.2150 -+  static mbstate_t state = {'\0'};
 68.2151 -+  mbstate_t state_bak;
 68.2152 -+  wchar_t wc;
 68.2153 -+  size_t mblength;
 68.2154 -+  int width;
 68.2155 -+
 68.2156 -+  if (tabify_output)
 68.2157 -+    {
 68.2158 -+      state_bak = state;
 68.2159 -+      mbc[mbc_pos++] = c;
 68.2160 -+      mblength = mbrtowc (&wc, mbc, mbc_pos, &state);
 68.2161 -+
 68.2162 -+      while (mbc_pos > 0)
 68.2163 -+        {
 68.2164 -+          switch (mblength)
 68.2165 -+            {
 68.2166 -+            case (size_t)-2:
 68.2167 -+              state = state_bak;
 68.2168 -+              return;
 68.2169 -+
 68.2170 -+            case (size_t)-1:
 68.2171 -+              state = state_bak;
 68.2172 -+              ++output_position;
 68.2173 -+              putchar (mbc[0]);
 68.2174 -+              memmove (mbc, mbc + 1, MB_CUR_MAX - 1);
 68.2175 -+              --mbc_pos;
 68.2176 -+              break;
 68.2177 -+
 68.2178 -+            case 0:
 68.2179 -+              mblength = 1;
 68.2180 -+
 68.2181 -+            default:
 68.2182 -+              if (wc == L' ')
 68.2183 -+                {
 68.2184 -+                  memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength);
 68.2185 -+                  --mbc_pos;
 68.2186 -+                  ++spaces_not_printed;
 68.2187 -+                  return;
 68.2188 -+                }
 68.2189 -+              else if (spaces_not_printed > 0)
 68.2190 -+                print_white_space ();
 68.2191 -+
 68.2192 -+              /* Nonprintables are assumed to have width 0, except L'\b'. */
 68.2193 -+              if ((width = wcwidth (wc)) < 1)
 68.2194 -+                {
 68.2195 -+                  if (wc == L'\b')
 68.2196 -+                    --output_position;
 68.2197 -+                }
 68.2198 -+              else
 68.2199 -+                output_position += width;
 68.2200 -+
 68.2201 -+              fwrite (mbc, sizeof(char), mblength, stdout);
 68.2202 -+              memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength);
 68.2203 -+              mbc_pos -= mblength;
 68.2204 -+            }
 68.2205 -+        }
 68.2206 -+      return;
 68.2207 -+    }
 68.2208 -+  putchar (c);
 68.2209 -+}
 68.2210 -+#endif
 68.2211 -+
 68.2212 - /* Skip to page PAGE before printing.
 68.2213 -    PAGE may be larger than total number of pages. */
 68.2214 - 
 68.2215 -@@ -2462,9 +2660,9 @@ read_line (COLUMN *p)
 68.2216 -           align_empty_cols = false;
 68.2217 -         }
 68.2218 - 
 68.2219 --      if (padding_not_printed - col_sep_length > 0)
 68.2220 -+      if (padding_not_printed - col_sep_width > 0)
 68.2221 -         {
 68.2222 --          pad_across_to (padding_not_printed - col_sep_length);
 68.2223 -+          pad_across_to (padding_not_printed - col_sep_width);
 68.2224 -           padding_not_printed = ANYWHERE;
 68.2225 -         }
 68.2226 - 
 68.2227 -@@ -2534,7 +2732,7 @@ print_stored (COLUMN *p)
 68.2228 -   int i;
 68.2229 - 
 68.2230 -   int line = p->current_line++;
 68.2231 --  char *first = &buff[line_vector[line]];
 68.2232 -+  unsigned char *first = &buff[line_vector[line]];
 68.2233 -   /* FIXME
 68.2234 -      UMR: Uninitialized memory read:
 68.2235 -      * This is occurring while in:
 68.2236 -@@ -2546,7 +2744,7 @@ print_stored (COLUMN *p)
 68.2237 -      xmalloc        [xmalloc.c:94]
 68.2238 -      init_store_cols [pr.c:1648]
 68.2239 -      */
 68.2240 --  char *last = &buff[line_vector[line + 1]];
 68.2241 -+  unsigned char *last = &buff[line_vector[line + 1]];
 68.2242 - 
 68.2243 -   pad_vertically = true;
 68.2244 - 
 68.2245 -@@ -2565,9 +2763,9 @@ print_stored (COLUMN *p)
 68.2246 -         }
 68.2247 -     }
 68.2248 - 
 68.2249 --  if (padding_not_printed - col_sep_length > 0)
 68.2250 -+  if (padding_not_printed - col_sep_width > 0)
 68.2251 -     {
 68.2252 --      pad_across_to (padding_not_printed - col_sep_length);
 68.2253 -+      pad_across_to (padding_not_printed - col_sep_width);
 68.2254 -       padding_not_printed = ANYWHERE;
 68.2255 -     }
 68.2256 - 
 68.2257 -@@ -2580,8 +2778,8 @@ print_stored (COLUMN *p)
 68.2258 -   if (spaces_not_printed == 0)
 68.2259 -     {
 68.2260 -       output_position = p->start_position + end_vector[line];
 68.2261 --      if (p->start_position - col_sep_length == chars_per_margin)
 68.2262 --        output_position -= col_sep_length;
 68.2263 -+      if (p->start_position - col_sep_width == chars_per_margin)
 68.2264 -+        output_position -= col_sep_width;
 68.2265 -     }
 68.2266 - 
 68.2267 -   return true;
 68.2268 -@@ -2600,7 +2798,7 @@ print_stored (COLUMN *p)
 68.2269 -    number of characters is 1.) */
 68.2270 - 
 68.2271 - static int
 68.2272 --char_to_clump (char c)
 68.2273 -+char_to_clump_single (char c)
 68.2274 - {
 68.2275 -   unsigned char uc = c;
 68.2276 -   char *s = clump_buff;
 68.2277 -@@ -2610,10 +2808,10 @@ char_to_clump (char c)
 68.2278 -   int chars;
 68.2279 -   int chars_per_c = 8;
 68.2280 - 
 68.2281 --  if (c == input_tab_char)
 68.2282 -+  if (c == input_tab_char[0])
 68.2283 -     chars_per_c = chars_per_input_tab;
 68.2284 - 
 68.2285 --  if (c == input_tab_char || c == '\t')
 68.2286 -+  if (c == input_tab_char[0] || c == '\t')
 68.2287 -     {
 68.2288 -       width = TAB_WIDTH (chars_per_c, input_position);
 68.2289 - 
 68.2290 -@@ -2694,6 +2892,164 @@ char_to_clump (char c)
 68.2291 -   return chars;
 68.2292 - }
 68.2293 - 
 68.2294 -+#ifdef HAVE_MBRTOWC
 68.2295 -+static int
 68.2296 -+char_to_clump_multi (char c)
 68.2297 -+{
 68.2298 -+  static size_t mbc_pos = 0;
 68.2299 -+  static char mbc[MB_LEN_MAX] = {'\0'};
 68.2300 -+  static mbstate_t state = {'\0'};
 68.2301 -+  mbstate_t state_bak;
 68.2302 -+  wchar_t wc;
 68.2303 -+  size_t mblength;
 68.2304 -+  int wc_width;
 68.2305 -+  register char *s = clump_buff;
 68.2306 -+  register int i, j;
 68.2307 -+  char esc_buff[4];
 68.2308 -+  int width;
 68.2309 -+  int chars;
 68.2310 -+  int chars_per_c = 8;
 68.2311 -+
 68.2312 -+  state_bak = state;
 68.2313 -+  mbc[mbc_pos++] = c;
 68.2314 -+  mblength = mbrtowc (&wc, mbc, mbc_pos, &state);
 68.2315 -+
 68.2316 -+  width = 0;
 68.2317 -+  chars = 0;
 68.2318 -+  while (mbc_pos > 0)
 68.2319 -+    {
 68.2320 -+      switch (mblength)
 68.2321 -+        {
 68.2322 -+        case (size_t)-2:
 68.2323 -+          state = state_bak;
 68.2324 -+          return 0;
 68.2325 -+
 68.2326 -+        case (size_t)-1:
 68.2327 -+          state = state_bak;
 68.2328 -+          mblength = 1;
 68.2329 -+
 68.2330 -+          if (use_esc_sequence || use_cntrl_prefix)
 68.2331 -+            {
 68.2332 -+              width = +4;
 68.2333 -+              chars = +4;
 68.2334 -+              *s++ = '\\';
 68.2335 -+              sprintf (esc_buff, "%03o", (unsigned char) mbc[0]);
 68.2336 -+              for (i = 0; i <= 2; ++i)
 68.2337 -+                *s++ = (int) esc_buff[i];
 68.2338 -+            }
 68.2339 -+          else
 68.2340 -+            {
 68.2341 -+              width += 1;
 68.2342 -+              chars += 1;
 68.2343 -+              *s++ = mbc[0];
 68.2344 -+            }
 68.2345 -+          break;
 68.2346 -+
 68.2347 -+        case 0:
 68.2348 -+          mblength = 1;
 68.2349 -+                /* Fall through */
 68.2350 -+
 68.2351 -+        default:
 68.2352 -+          if (memcmp (mbc, input_tab_char, mblength) == 0)
 68.2353 -+            chars_per_c = chars_per_input_tab;
 68.2354 -+
 68.2355 -+          if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t')
 68.2356 -+            {
 68.2357 -+              int  width_inc;
 68.2358 -+
 68.2359 -+              width_inc = TAB_WIDTH (chars_per_c, input_position);
 68.2360 -+              width += width_inc;
 68.2361 -+
 68.2362 -+              if (untabify_input)
 68.2363 -+                {
 68.2364 -+                  for (i = width_inc; i; --i)
 68.2365 -+                    *s++ = ' ';
 68.2366 -+                  chars += width_inc;
 68.2367 -+                }
 68.2368 -+              else
 68.2369 -+                {
 68.2370 -+                  for (i = 0; i <  mblength; i++)
 68.2371 -+                    *s++ = mbc[i];
 68.2372 -+                  chars += mblength;
 68.2373 -+                }
 68.2374 -+            }
 68.2375 -+          else if ((wc_width = wcwidth (wc)) < 1)
 68.2376 -+            {
 68.2377 -+              if (use_esc_sequence)
 68.2378 -+                {
 68.2379 -+                  for (i = 0; i < mblength; i++)
 68.2380 -+                    {
 68.2381 -+                      width += 4;
 68.2382 -+                      chars += 4;
 68.2383 -+                      *s++ = '\\';
 68.2384 -+                      sprintf (esc_buff, "%03o", (unsigned char) mbc[i]);
 68.2385 -+                      for (j = 0; j <= 2; ++j)
 68.2386 -+                        *s++ = (int) esc_buff[j];
 68.2387 -+                    }
 68.2388 -+                }
 68.2389 -+              else if (use_cntrl_prefix)
 68.2390 -+                {
 68.2391 -+                  if (wc < 0200)
 68.2392 -+                    {
 68.2393 -+                      width += 2;
 68.2394 -+                      chars += 2;
 68.2395 -+                      *s++ = '^';
 68.2396 -+                      *s++ = wc ^ 0100;
 68.2397 -+                    }
 68.2398 -+                  else
 68.2399 -+                    {
 68.2400 -+                      for (i = 0; i < mblength; i++)
 68.2401 -+                        {
 68.2402 -+                          width += 4;
 68.2403 -+                          chars += 4;
 68.2404 -+                          *s++ = '\\';
 68.2405 -+                          sprintf (esc_buff, "%03o", (unsigned char) mbc[i]);
 68.2406 -+                          for (j = 0; j <= 2; ++j)
 68.2407 -+                            *s++ = (int) esc_buff[j];
 68.2408 -+                        }
 68.2409 -+                    }
 68.2410 -+                }
 68.2411 -+              else if (wc == L'\b')
 68.2412 -+                {
 68.2413 -+                  width += -1;
 68.2414 -+                  chars += 1;
 68.2415 -+                  *s++ = c;
 68.2416 -+                }
 68.2417 -+              else
 68.2418 -+                {
 68.2419 -+                  width += 0;
 68.2420 -+                  chars += mblength;
 68.2421 -+                  for (i = 0; i < mblength; i++)
 68.2422 -+                    *s++ = mbc[i];
 68.2423 -+                }
 68.2424 -+            }
 68.2425 -+          else
 68.2426 -+            {
 68.2427 -+              width += wc_width;
 68.2428 -+              chars += mblength;
 68.2429 -+              for (i = 0; i < mblength; i++)
 68.2430 -+                *s++ = mbc[i];
 68.2431 -+            }
 68.2432 -+        }
 68.2433 -+      memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength);
 68.2434 -+      mbc_pos -= mblength;
 68.2435 -+    }
 68.2436 -+
 68.2437 -+  /* Too many backspaces must put us in position 0 -- never negative. */
 68.2438 -+  if (width < 0 && input_position == 0)
 68.2439 -+    {
 68.2440 -+      chars = 0;
 68.2441 -+      input_position = 0;
 68.2442 -+    }
 68.2443 -+  else if (width < 0 && input_position <= -width)
 68.2444 -+    input_position = 0;
 68.2445 -+  else
 68.2446 -+   input_position += width;
 68.2447 -+
 68.2448 -+  return chars;
 68.2449 -+}
 68.2450 -+#endif
 68.2451 -+
 68.2452 - /* We've just printed some files and need to clean up things before
 68.2453 -    looking for more options and printing the next batch of files.
 68.2454 - 
 68.2455 -diff -Naurp coreutils-8.25-orig/src/sort.c coreutils-8.25/src/sort.c
 68.2456 ---- coreutils-8.25-orig/src/sort.c	2016-01-16 13:09:33.000000000 -0600
 68.2457 -+++ coreutils-8.25/src/sort.c	2016-02-08 19:07:10.310944648 -0600
 68.2458 -@@ -29,6 +29,14 @@
 68.2459 - #include <sys/wait.h>
 68.2460 - #include <signal.h>
 68.2461 - #include <assert.h>
 68.2462 -+#if HAVE_WCHAR_H
 68.2463 -+# include <wchar.h>
 68.2464 -+#endif
 68.2465 -+/* Get isw* functions. */
 68.2466 -+#if HAVE_WCTYPE_H
 68.2467 -+# include <wctype.h>
 68.2468 -+#endif
 68.2469 -+
 68.2470 - #include "system.h"
 68.2471 - #include "argmatch.h"
 68.2472 - #include "error.h"
 68.2473 -@@ -163,14 +171,39 @@ static int decimal_point;
 68.2474 - /* Thousands separator; if -1, then there isn't one.  */
 68.2475 - static int thousands_sep;
 68.2476 - 
 68.2477 -+/* True if -f is specified.  */
 68.2478 -+static bool folding;
 68.2479 -+
 68.2480 - /* Nonzero if the corresponding locales are hard.  */
 68.2481 - static bool hard_LC_COLLATE;
 68.2482 --#if HAVE_NL_LANGINFO
 68.2483 -+#if HAVE_LANGINFO_CODESET
 68.2484 - static bool hard_LC_TIME;
 68.2485 - #endif
 68.2486 - 
 68.2487 - #define NONZERO(x) ((x) != 0)
 68.2488 - 
 68.2489 -+/* get a multibyte character's byte length. */
 68.2490 -+#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE)                        \
 68.2491 -+  do                                                                        \
 68.2492 -+    {                                                                        \
 68.2493 -+      wchar_t wc;                                                        \
 68.2494 -+      mbstate_t state_bak;                                                \
 68.2495 -+                                                                        \
 68.2496 -+      state_bak = STATE;                                                \
 68.2497 -+      mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE);                        \
 68.2498 -+                                                                        \
 68.2499 -+      switch (MBLENGTH)                                                        \
 68.2500 -+        {                                                                \
 68.2501 -+        case (size_t)-1:                                                \
 68.2502 -+        case (size_t)-2:                                                \
 68.2503 -+          STATE = state_bak;                                                \
 68.2504 -+                /* Fall through. */                                        \
 68.2505 -+        case 0:                                                                \
 68.2506 -+          MBLENGTH = 1;                                                        \
 68.2507 -+      }                                                                        \
 68.2508 -+    }                                                                        \
 68.2509 -+  while (0)
 68.2510 -+
 68.2511 - /* The kind of blanks for '-b' to skip in various options. */
 68.2512 - enum blanktype { bl_start, bl_end, bl_both };
 68.2513 - 
 68.2514 -@@ -344,13 +377,11 @@ static bool reverse;
 68.2515 -    they were read if all keys compare equal.  */
 68.2516 - static bool stable;
 68.2517 - 
 68.2518 --/* If TAB has this value, blanks separate fields.  */
 68.2519 --enum { TAB_DEFAULT = CHAR_MAX + 1 };
 68.2520 --
 68.2521 --/* Tab character separating fields.  If TAB_DEFAULT, then fields are
 68.2522 -+/* Tab character separating fields.  If tab_length is 0, then fields are
 68.2523 -    separated by the empty string between a non-blank character and a blank
 68.2524 -    character. */
 68.2525 --static int tab = TAB_DEFAULT;
 68.2526 -+static char tab[MB_LEN_MAX + 1];
 68.2527 -+static size_t tab_length = 0;
 68.2528 - 
 68.2529 - /* Flag to remove consecutive duplicate lines from the output.
 68.2530 -    Only the last of a sequence of equal lines will be output. */
 68.2531 -@@ -810,6 +841,46 @@ reap_all (void)
 68.2532 -     reap (-1);
 68.2533 - }
 68.2534 - 
 68.2535 -+/* Function pointers. */
 68.2536 -+static void
 68.2537 -+(*inittables) (void);
 68.2538 -+static char *
 68.2539 -+(*begfield) (const struct line*, const struct keyfield *);
 68.2540 -+static char *
 68.2541 -+(*limfield) (const struct line*, const struct keyfield *);
 68.2542 -+static void
 68.2543 -+(*skipblanks) (char **ptr, char *lim);
 68.2544 -+static int
 68.2545 -+(*getmonth) (char const *, size_t, char **);
 68.2546 -+static int
 68.2547 -+(*keycompare) (const struct line *, const struct line *);
 68.2548 -+static int
 68.2549 -+(*numcompare) (const char *, const char *);
 68.2550 -+
 68.2551 -+/* Test for white space multibyte character.
 68.2552 -+   Set LENGTH the byte length of investigated multibyte character. */
 68.2553 -+#if HAVE_MBRTOWC
 68.2554 -+static int
 68.2555 -+ismbblank (const char *str, size_t len, size_t *length)
 68.2556 -+{
 68.2557 -+  size_t mblength;
 68.2558 -+  wchar_t wc;
 68.2559 -+  mbstate_t state;
 68.2560 -+
 68.2561 -+  memset (&state, '\0', sizeof(mbstate_t));
 68.2562 -+  mblength = mbrtowc (&wc, str, len, &state);
 68.2563 -+
 68.2564 -+  if (mblength == (size_t)-1 || mblength == (size_t)-2)
 68.2565 -+    {
 68.2566 -+      *length = 1;
 68.2567 -+      return 0;
 68.2568 -+    }
 68.2569 -+
 68.2570 -+  *length = (mblength < 1) ? 1 : mblength;
 68.2571 -+  return iswblank (wc) || wc == '\n';
 68.2572 -+}
 68.2573 -+#endif
 68.2574 -+
 68.2575 - /* Clean up any remaining temporary files.  */
 68.2576 - 
 68.2577 - static void
 68.2578 -@@ -1254,7 +1325,7 @@ zaptemp (char const *name)
 68.2579 -   free (node);
 68.2580 - }
 68.2581 - 
 68.2582 --#if HAVE_NL_LANGINFO
 68.2583 -+#if HAVE_LANGINFO_CODESET
 68.2584 - 
 68.2585 - static int
 68.2586 - struct_month_cmp (void const *m1, void const *m2)
 68.2587 -@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void c
 68.2588 - /* Initialize the character class tables. */
 68.2589 - 
 68.2590 - static void
 68.2591 --inittables (void)
 68.2592 -+inittables_uni (void)
 68.2593 - {
 68.2594 -   size_t i;
 68.2595 - 
 68.2596 -@@ -1281,7 +1352,7 @@ inittables (void)
 68.2597 -       fold_toupper[i] = toupper (i);
 68.2598 -     }
 68.2599 - 
 68.2600 --#if HAVE_NL_LANGINFO
 68.2601 -+#if HAVE_LANGINFO_CODESET
 68.2602 -   /* If we're not in the "C" locale, read different names for months.  */
 68.2603 -   if (hard_LC_TIME)
 68.2604 -     {
 68.2605 -@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char con
 68.2606 -     xstrtol_fatal (e, oi, c, long_options, s);
 68.2607 - }
 68.2608 - 
 68.2609 -+#if HAVE_MBRTOWC
 68.2610 -+static void
 68.2611 -+inittables_mb (void)
 68.2612 -+{
 68.2613 -+  int i, j, k, l;
 68.2614 -+  char *name, *s, *lc_time, *lc_ctype;
 68.2615 -+  size_t s_len, mblength;
 68.2616 -+  char mbc[MB_LEN_MAX];
 68.2617 -+  wchar_t wc, pwc;
 68.2618 -+  mbstate_t state_mb, state_wc;
 68.2619 -+
 68.2620 -+  lc_time = setlocale (LC_TIME, "");
 68.2621 -+  if (lc_time)
 68.2622 -+    lc_time = xstrdup (lc_time);
 68.2623 -+
 68.2624 -+  lc_ctype = setlocale (LC_CTYPE, "");
 68.2625 -+  if (lc_ctype)
 68.2626 -+    lc_ctype = xstrdup (lc_ctype);
 68.2627 -+
 68.2628 -+  if (lc_time && lc_ctype)
 68.2629 -+    /* temporarily set LC_CTYPE to match LC_TIME, so that we can convert
 68.2630 -+     * the names of months to upper case */
 68.2631 -+    setlocale (LC_CTYPE, lc_time);
 68.2632 -+
 68.2633 -+  for (i = 0; i < MONTHS_PER_YEAR; i++)
 68.2634 -+    {
 68.2635 -+      s = (char *) nl_langinfo (ABMON_1 + i);
 68.2636 -+      s_len = strlen (s);
 68.2637 -+      monthtab[i].name = name = (char *) xmalloc (s_len + 1);
 68.2638 -+      monthtab[i].val = i + 1;
 68.2639 -+
 68.2640 -+      memset (&state_mb, '\0', sizeof (mbstate_t));
 68.2641 -+      memset (&state_wc, '\0', sizeof (mbstate_t));
 68.2642 -+
 68.2643 -+      for (j = 0; j < s_len;)
 68.2644 -+        {
 68.2645 -+          if (!ismbblank (s + j, s_len - j, &mblength))
 68.2646 -+            break;
 68.2647 -+          j += mblength;
 68.2648 -+        }
 68.2649 -+
 68.2650 -+      for (k = 0; j < s_len;)
 68.2651 -+        {
 68.2652 -+          mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb);
 68.2653 -+          assert (mblength != (size_t)-1 && mblength != (size_t)-2);
 68.2654 -+          if (mblength == 0)
 68.2655 -+            break;
 68.2656 -+
 68.2657 -+          pwc = towupper (wc);
 68.2658 -+          if (pwc == wc)
 68.2659 -+            {
 68.2660 -+              memcpy (mbc, s + j, mblength);
 68.2661 -+              j += mblength;
 68.2662 -+            }
 68.2663 -+          else
 68.2664 -+            {
 68.2665 -+              j += mblength;
 68.2666 -+              mblength = wcrtomb (mbc, pwc, &state_wc);
 68.2667 -+              assert (mblength != (size_t)0 && mblength != (size_t)-1);
 68.2668 -+            }
 68.2669 -+
 68.2670 -+          for (l = 0; l < mblength; l++)
 68.2671 -+            name[k++] = mbc[l];
 68.2672 -+        }
 68.2673 -+      name[k] = '\0';
 68.2674 -+    }
 68.2675 -+  qsort ((void *) monthtab, MONTHS_PER_YEAR,
 68.2676 -+      sizeof (struct month), struct_month_cmp);
 68.2677 -+
 68.2678 -+  if (lc_time && lc_ctype)
 68.2679 -+    /* restore the original locales */
 68.2680 -+    setlocale (LC_CTYPE, lc_ctype);
 68.2681 -+
 68.2682 -+  free (lc_ctype);
 68.2683 -+  free (lc_time);
 68.2684 -+}
 68.2685 -+#endif
 68.2686 -+
 68.2687 - /* Specify the amount of main memory to use when sorting.  */
 68.2688 - static void
 68.2689 - specify_sort_size (int oi, char c, char const *s)
 68.2690 -@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf
 68.2691 -    by KEY in LINE. */
 68.2692 - 
 68.2693 - static char *
 68.2694 --begfield (struct line const *line, struct keyfield const *key)
 68.2695 -+begfield_uni (const struct line *line, const struct keyfield *key)
 68.2696 - {
 68.2697 -   char *ptr = line->text, *lim = ptr + line->length - 1;
 68.2698 -   size_t sword = key->sword;
 68.2699 -@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struc
 68.2700 -   /* The leading field separator itself is included in a field when -t
 68.2701 -      is absent.  */
 68.2702 - 
 68.2703 --  if (tab != TAB_DEFAULT)
 68.2704 -+  if (tab_length)
 68.2705 -     while (ptr < lim && sword--)
 68.2706 -       {
 68.2707 --        while (ptr < lim && *ptr != tab)
 68.2708 -+        while (ptr < lim && *ptr != tab[0])
 68.2709 -           ++ptr;
 68.2710 -         if (ptr < lim)
 68.2711 -           ++ptr;
 68.2712 -@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struc
 68.2713 -   return ptr;
 68.2714 - }
 68.2715 - 
 68.2716 -+#if HAVE_MBRTOWC
 68.2717 -+static char *
 68.2718 -+begfield_mb (const struct line *line, const struct keyfield *key)
 68.2719 -+{
 68.2720 -+  int i;
 68.2721 -+  char *ptr = line->text, *lim = ptr + line->length - 1;
 68.2722 -+  size_t sword = key->sword;
 68.2723 -+  size_t schar = key->schar;
 68.2724 -+  size_t mblength;
 68.2725 -+  mbstate_t state;
 68.2726 -+
 68.2727 -+  memset (&state, '\0', sizeof(mbstate_t));
 68.2728 -+
 68.2729 -+  if (tab_length)
 68.2730 -+    while (ptr < lim && sword--)
 68.2731 -+      {
 68.2732 -+        while (ptr < lim && memcmp (ptr, tab, tab_length) != 0)
 68.2733 -+          {
 68.2734 -+            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 68.2735 -+            ptr += mblength;
 68.2736 -+          }
 68.2737 -+        if (ptr < lim)
 68.2738 -+          {
 68.2739 -+            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 68.2740 -+            ptr += mblength;
 68.2741 -+          }
 68.2742 -+      }
 68.2743 -+  else
 68.2744 -+    while (ptr < lim && sword--)
 68.2745 -+      {
 68.2746 -+        while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
 68.2747 -+          ptr += mblength;
 68.2748 -+        if (ptr < lim)
 68.2749 -+          {
 68.2750 -+            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 68.2751 -+            ptr += mblength;
 68.2752 -+          }
 68.2753 -+        while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength))
 68.2754 -+          ptr += mblength;
 68.2755 -+      }
 68.2756 -+
 68.2757 -+  if (key->skipsblanks)
 68.2758 -+    while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
 68.2759 -+      ptr += mblength;
 68.2760 -+
 68.2761 -+  for (i = 0; i < schar; i++)
 68.2762 -+    {
 68.2763 -+      GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 68.2764 -+
 68.2765 -+      if (ptr + mblength > lim)
 68.2766 -+        break;
 68.2767 -+      else
 68.2768 -+        ptr += mblength;
 68.2769 -+    }
 68.2770 -+
 68.2771 -+  return ptr;
 68.2772 -+}
 68.2773 -+#endif
 68.2774 -+
 68.2775 - /* Return the limit of (a pointer to the first character after) the field
 68.2776 -    in LINE specified by KEY. */
 68.2777 - 
 68.2778 - static char *
 68.2779 --limfield (struct line const *line, struct keyfield const *key)
 68.2780 -+limfield_uni (const struct line *line, const struct keyfield *key)
 68.2781 - {
 68.2782 -   char *ptr = line->text, *lim = ptr + line->length - 1;
 68.2783 -   size_t eword = key->eword, echar = key->echar;
 68.2784 -@@ -1653,10 +1861,10 @@ limfield (struct line const *line, struc
 68.2785 -      'beginning' is the first character following the delimiting TAB.
 68.2786 -      Otherwise, leave PTR pointing at the first 'blank' character after
 68.2787 -      the preceding field.  */
 68.2788 --  if (tab != TAB_DEFAULT)
 68.2789 -+  if (tab_length)
 68.2790 -     while (ptr < lim && eword--)
 68.2791 -       {
 68.2792 --        while (ptr < lim && *ptr != tab)
 68.2793 -+        while (ptr < lim && *ptr != tab[0])
 68.2794 -           ++ptr;
 68.2795 -         if (ptr < lim && (eword || echar))
 68.2796 -           ++ptr;
 68.2797 -@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struc
 68.2798 -      */
 68.2799 - 
 68.2800 -   /* Make LIM point to the end of (one byte past) the current field.  */
 68.2801 --  if (tab != TAB_DEFAULT)
 68.2802 -+  if (tab_length)
 68.2803 -     {
 68.2804 -       char *newlim;
 68.2805 --      newlim = memchr (ptr, tab, lim - ptr);
 68.2806 -+      newlim = memchr (ptr, tab[0], lim - ptr);
 68.2807 -       if (newlim)
 68.2808 -         lim = newlim;
 68.2809 -     }
 68.2810 -@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struc
 68.2811 -   return ptr;
 68.2812 - }
 68.2813 - 
 68.2814 -+#if HAVE_MBRTOWC
 68.2815 -+static char *
 68.2816 -+limfield_mb (const struct line *line, const struct keyfield *key)
 68.2817 -+{
 68.2818 -+  char *ptr = line->text, *lim = ptr + line->length - 1;
 68.2819 -+  size_t eword = key->eword, echar = key->echar;
 68.2820 -+  int i;
 68.2821 -+  size_t mblength;
 68.2822 -+  mbstate_t state;
 68.2823 -+
 68.2824 -+  if (echar == 0)
 68.2825 -+    eword++; /* skip all of end field. */
 68.2826 -+
 68.2827 -+  memset (&state, '\0', sizeof(mbstate_t));
 68.2828 -+
 68.2829 -+  if (tab_length)
 68.2830 -+    while (ptr < lim && eword--)
 68.2831 -+      {
 68.2832 -+        while (ptr < lim && memcmp (ptr, tab, tab_length) != 0)
 68.2833 -+          {
 68.2834 -+            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 68.2835 -+            ptr += mblength;
 68.2836 -+          }
 68.2837 -+        if (ptr < lim && (eword | echar))
 68.2838 -+          {
 68.2839 -+            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 68.2840 -+            ptr += mblength;
 68.2841 -+          }
 68.2842 -+      }
 68.2843 -+  else
 68.2844 -+    while (ptr < lim && eword--)
 68.2845 -+      {
 68.2846 -+        while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
 68.2847 -+          ptr += mblength;
 68.2848 -+        if (ptr < lim)
 68.2849 -+          {
 68.2850 -+            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 68.2851 -+            ptr += mblength;
 68.2852 -+          }
 68.2853 -+        while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength))
 68.2854 -+          ptr += mblength;
 68.2855 -+      }
 68.2856 -+
 68.2857 -+
 68.2858 -+# ifdef POSIX_UNSPECIFIED
 68.2859 -+  /* Make LIM point to the end of (one byte past) the current field.  */
 68.2860 -+  if (tab_length)
 68.2861 -+    {
 68.2862 -+      char *newlim, *p;
 68.2863 -+
 68.2864 -+      newlim = NULL;
 68.2865 -+      for (p = ptr; p < lim;)
 68.2866 -+         {
 68.2867 -+          if (memcmp (p, tab, tab_length) == 0)
 68.2868 -+            {
 68.2869 -+              newlim = p;
 68.2870 -+              break;
 68.2871 -+            }
 68.2872 -+
 68.2873 -+          GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 68.2874 -+          p += mblength;
 68.2875 -+        }
 68.2876 -+    }
 68.2877 -+  else
 68.2878 -+    {
 68.2879 -+      char *newlim;
 68.2880 -+      newlim = ptr;
 68.2881 -+
 68.2882 -+      while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength))
 68.2883 -+        newlim += mblength;
 68.2884 -+      if (ptr < lim)
 68.2885 -+        {
 68.2886 -+          GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 68.2887 -+          ptr += mblength;
 68.2888 -+        }
 68.2889 -+      while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength))
 68.2890 -+        newlim += mblength;
 68.2891 -+      lim = newlim;
 68.2892 -+    }
 68.2893 -+# endif
 68.2894 -+
 68.2895 -+  if (echar != 0)
 68.2896 -+  {
 68.2897 -+    /* If we're skipping leading blanks, don't start counting characters
 68.2898 -+     *      until after skipping past any leading blanks.  */
 68.2899 -+    if (key->skipeblanks)
 68.2900 -+      while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
 68.2901 -+        ptr += mblength;
 68.2902 -+
 68.2903 -+    memset (&state, '\0', sizeof(mbstate_t));
 68.2904 -+
 68.2905 -+    /* Advance PTR by ECHAR (if possible), but no further than LIM.  */
 68.2906 -+    for (i = 0; i < echar; i++)
 68.2907 -+     {
 68.2908 -+        GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 68.2909 -+
 68.2910 -+        if (ptr + mblength > lim)
 68.2911 -+          break;
 68.2912 -+        else
 68.2913 -+          ptr += mblength;
 68.2914 -+      }
 68.2915 -+  }
 68.2916 -+
 68.2917 -+  return ptr;
 68.2918 -+}
 68.2919 -+#endif
 68.2920 -+
 68.2921 -+static void
 68.2922 -+skipblanks_uni (char **ptr, char *lim)
 68.2923 -+{
 68.2924 -+  while (*ptr < lim && blanks[to_uchar (**ptr)])
 68.2925 -+    ++(*ptr);
 68.2926 -+}
 68.2927 -+
 68.2928 -+#if HAVE_MBRTOWC
 68.2929 -+static void
 68.2930 -+skipblanks_mb (char **ptr, char *lim)
 68.2931 -+{
 68.2932 -+  size_t mblength;
 68.2933 -+  while (*ptr < lim && ismbblank (*ptr, lim - *ptr, &mblength))
 68.2934 -+    (*ptr) += mblength;
 68.2935 -+}
 68.2936 -+#endif
 68.2937 -+
 68.2938 - /* Fill BUF reading from FP, moving buf->left bytes from the end
 68.2939 -    of buf->buf to the beginning first.  If EOF is reached and the
 68.2940 -    file wasn't terminated by a newline, supply one.  Set up BUF's line
 68.2941 -@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, c
 68.2942 -                   else
 68.2943 -                     {
 68.2944 -                       if (key->skipsblanks)
 68.2945 --                        while (blanks[to_uchar (*line_start)])
 68.2946 --                          line_start++;
 68.2947 -+                        {
 68.2948 -+#if HAVE_MBRTOWC
 68.2949 -+                          if (MB_CUR_MAX > 1)
 68.2950 -+                            {
 68.2951 -+                              size_t mblength;
 68.2952 -+                              while (line_start < line->keylim &&
 68.2953 -+                                     ismbblank (line_start,
 68.2954 -+                                                line->keylim - line_start,
 68.2955 -+                                                &mblength))
 68.2956 -+                                line_start += mblength;
 68.2957 -+                            }
 68.2958 -+                          else
 68.2959 -+#endif
 68.2960 -+                          while (blanks[to_uchar (*line_start)])
 68.2961 -+                            line_start++;
 68.2962 -+                        }
 68.2963 -                       line->keybeg = line_start;
 68.2964 -                     }
 68.2965 -                 }
 68.2966 -@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char co
 68.2967 -    hideously fast. */
 68.2968 - 
 68.2969 - static int
 68.2970 --numcompare (char const *a, char const *b)
 68.2971 -+numcompare_uni (const char *a, const char *b)
 68.2972 - {
 68.2973 -   while (blanks[to_uchar (*a)])
 68.2974 -     a++;
 68.2975 -@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b
 68.2976 -   return strnumcmp (a, b, decimal_point, thousands_sep);
 68.2977 - }
 68.2978 - 
 68.2979 -+#if HAVE_MBRTOWC
 68.2980 -+static int
 68.2981 -+numcompare_mb (const char *a, const char *b)
 68.2982 -+{
 68.2983 -+  size_t mblength, len;
 68.2984 -+  len = strlen (a); /* okay for UTF-8 */
 68.2985 -+  while (*a && ismbblank (a, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength))
 68.2986 -+    {
 68.2987 -+      a += mblength;
 68.2988 -+      len -= mblength;
 68.2989 -+    }
 68.2990 -+  len = strlen (b); /* okay for UTF-8 */
 68.2991 -+  while (*b && ismbblank (b, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength))
 68.2992 -+    b += mblength;
 68.2993 -+
 68.2994 -+  return strnumcmp (a, b, decimal_point, thousands_sep);
 68.2995 -+}
 68.2996 -+#endif /* HAV_EMBRTOWC */
 68.2997 -+
 68.2998 - /* Work around a problem whereby the long double value returned by glibc's
 68.2999 -    strtold ("NaN", ...) contains uninitialized bits: clear all bytes of
 68.3000 -    A and B before calling strtold.  FIXME: remove this function once
 68.3001 -@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char
 68.3002 -    Return 0 if the name in S is not recognized.  */
 68.3003 - 
 68.3004 - static int
 68.3005 --getmonth (char const *month, char **ea)
 68.3006 -+getmonth_uni (char const *month, size_t len, char **ea)
 68.3007 - {
 68.3008 -   size_t lo = 0;
 68.3009 -   size_t hi = MONTHS_PER_YEAR;
 68.3010 -@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, stru
 68.3011 -           char saved = *lim;
 68.3012 -           *lim = '\0';
 68.3013 - 
 68.3014 --          while (blanks[to_uchar (*beg)])
 68.3015 --            beg++;
 68.3016 -+          skipblanks (&beg, lim);
 68.3017 - 
 68.3018 -           char *tighter_lim = beg;
 68.3019 - 
 68.3020 -           if (lim < beg)
 68.3021 -             tighter_lim = lim;
 68.3022 -           else if (key->month)
 68.3023 --            getmonth (beg, &tighter_lim);
 68.3024 -+            getmonth (beg, lim-beg, &tighter_lim);
 68.3025 -           else if (key->general_numeric)
 68.3026 -             ignore_value (strtold (beg, &tighter_lim));
 68.3027 -           else if (key->numeric || key->human_numeric)
 68.3028 -@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gke
 68.3029 -       bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key)
 68.3030 -                                  && !(key->schar || key->echar);
 68.3031 -       bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y  */
 68.3032 --      if (!gkey_only && tab == TAB_DEFAULT && !line_offset
 68.3033 -+      if (!gkey_only && !tab_length && !line_offset
 68.3034 -           && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned))
 68.3035 -               || (!key->skipsblanks && key->schar)
 68.3036 -               || (!key->skipeblanks && key->echar)))
 68.3037 -@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gke
 68.3038 -     error (0, 0, _("option '-r' only applies to last-resort comparison"));
 68.3039 - }
 68.3040 - 
 68.3041 -+#if HAVE_MBRTOWC
 68.3042 -+static int
 68.3043 -+getmonth_mb (const char *s, size_t len, char **ea)
 68.3044 -+{
 68.3045 -+  char *month;
 68.3046 -+  register size_t i;
 68.3047 -+  register int lo = 0, hi = MONTHS_PER_YEAR, result;
 68.3048 -+  char *tmp;
 68.3049 -+  size_t wclength, mblength;
 68.3050 -+  const char *pp;
 68.3051 -+  const wchar_t *wpp;
 68.3052 -+  wchar_t *month_wcs;
 68.3053 -+  mbstate_t state;
 68.3054 -+
 68.3055 -+  while (len > 0 && ismbblank (s, len, &mblength))
 68.3056 -+    {
 68.3057 -+      s += mblength;
 68.3058 -+      len -= mblength;
 68.3059 -+    }
 68.3060 -+
 68.3061 -+  if (len == 0)
 68.3062 -+    return 0;
 68.3063 -+
 68.3064 -+  if (SIZE_MAX - len < 1)
 68.3065 -+    xalloc_die ();
 68.3066 -+
 68.3067 -+  month = (char *) xnmalloc (len + 1, MB_CUR_MAX);
 68.3068 -+
 68.3069 -+  pp = tmp = (char *) xnmalloc (len + 1, MB_CUR_MAX);
 68.3070 -+  memcpy (tmp, s, len);
 68.3071 -+  tmp[len] = '\0';
 68.3072 -+  wpp = month_wcs = (wchar_t *) xnmalloc (len + 1, sizeof (wchar_t));
 68.3073 -+  memset (&state, '\0', sizeof (mbstate_t));
 68.3074 -+
 68.3075 -+  wclength = mbsrtowcs (month_wcs, &pp, len + 1, &state);
 68.3076 -+  if (wclength == (size_t)-1 || pp != NULL)
 68.3077 -+    error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s));
 68.3078 -+
 68.3079 -+  for (i = 0; i < wclength; i++)
 68.3080 -+    {
 68.3081 -+      month_wcs[i] = towupper(month_wcs[i]);
 68.3082 -+      if (iswblank (month_wcs[i]))
 68.3083 -+        {
 68.3084 -+          month_wcs[i] = L'\0';
 68.3085 -+          break;
 68.3086 -+        }
 68.3087 -+    }
 68.3088 -+
 68.3089 -+  mblength = wcsrtombs (month, &wpp, (len + 1) * MB_CUR_MAX, &state);
 68.3090 -+  assert (mblength != (-1) && wpp == NULL);
 68.3091 -+
 68.3092 -+  do
 68.3093 -+    {
 68.3094 -+      int ix = (lo + hi) / 2;
 68.3095 -+
 68.3096 -+      if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0)
 68.3097 -+        hi = ix;
 68.3098 -+      else
 68.3099 -+        lo = ix;
 68.3100 -+    }
 68.3101 -+  while (hi - lo > 1);
 68.3102 -+
 68.3103 -+  result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name))
 68.3104 -+      ? monthtab[lo].val : 0);
 68.3105 -+
 68.3106 -+  if (ea && result)
 68.3107 -+     *ea = (char*) s + strlen (monthtab[lo].name);
 68.3108 -+
 68.3109 -+  free (month);
 68.3110 -+  free (tmp);
 68.3111 -+  free (month_wcs);
 68.3112 -+
 68.3113 -+  return result;
 68.3114 -+}
 68.3115 -+#endif
 68.3116 -+
 68.3117 - /* Compare two lines A and B trying every key in sequence until there
 68.3118 -    are no more keys or a difference is found. */
 68.3119 - 
 68.3120 - static int
 68.3121 --keycompare (struct line const *a, struct line const *b)
 68.3122 -+keycompare_uni (const struct line *a, const struct line *b)
 68.3123 - {
 68.3124 -   struct keyfield *key = keylist;
 68.3125 - 
 68.3126 -@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct
 68.3127 -           else if (key->human_numeric)
 68.3128 -             diff = human_numcompare (ta, tb);
 68.3129 -           else if (key->month)
 68.3130 --            diff = getmonth (ta, NULL) - getmonth (tb, NULL);
 68.3131 -+            diff = getmonth (ta, tlena, NULL) - getmonth (tb, tlenb, NULL);
 68.3132 -           else if (key->random)
 68.3133 -             diff = compare_random (ta, tlena, tb, tlenb);
 68.3134 -           else if (key->version)
 68.3135 -@@ -2695,6 +3135,211 @@ keycompare (struct line const *a, struct
 68.3136 -   return key->reverse ? -diff : diff;
 68.3137 - }
 68.3138 - 
 68.3139 -+#if HAVE_MBRTOWC
 68.3140 -+static int
 68.3141 -+keycompare_mb (const struct line *a, const struct line *b)
 68.3142 -+{
 68.3143 -+  struct keyfield *key = keylist;
 68.3144 -+
 68.3145 -+  /* For the first iteration only, the key positions have been
 68.3146 -+     precomputed for us. */
 68.3147 -+  char *texta = a->keybeg;
 68.3148 -+  char *textb = b->keybeg;
 68.3149 -+  char *lima = a->keylim;
 68.3150 -+  char *limb = b->keylim;
 68.3151 -+
 68.3152 -+  size_t mblength_a, mblength_b;
 68.3153 -+  wchar_t wc_a, wc_b;
 68.3154 -+  mbstate_t state_a, state_b;
 68.3155 -+
 68.3156 -+  int diff = 0;
 68.3157 -+
 68.3158 -+  memset (&state_a, '\0', sizeof(mbstate_t));
 68.3159 -+  memset (&state_b, '\0', sizeof(mbstate_t));
 68.3160 -+  /* Ignore keys with start after end.  */
 68.3161 -+  if (a->keybeg - a->keylim > 0)
 68.3162 -+    return 0;
 68.3163 -+
 68.3164 -+
 68.3165 -+              /* Ignore and/or translate chars before comparing.  */
 68.3166 -+# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE)        \
 68.3167 -+  do                                                                        \
 68.3168 -+    {                                                                        \
 68.3169 -+      wchar_t uwc;                                                        \
 68.3170 -+      char mbc[MB_LEN_MAX];                                                \
 68.3171 -+      mbstate_t state_wc;                                                \
 68.3172 -+                                                                        \
 68.3173 -+      for (NEW_LEN = i = 0; i < LEN;)                                        \
 68.3174 -+        {                                                                \
 68.3175 -+          mbstate_t state_bak;                                                \
 68.3176 -+                                                                        \
 68.3177 -+          state_bak = STATE;                                                \
 68.3178 -+          MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE);                \
 68.3179 -+                                                                        \
 68.3180 -+          if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1                \
 68.3181 -+              || MBLENGTH == 0)                                                \
 68.3182 -+            {                                                                \
 68.3183 -+              if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1)        \
 68.3184 -+                STATE = state_bak;                                        \
 68.3185 -+              if (!ignore)                                                \
 68.3186 -+                COPY[NEW_LEN++] = TEXT[i];                                \
 68.3187 -+              i++;                                                         \
 68.3188 -+              continue;                                                        \
 68.3189 -+            }                                                                \
 68.3190 -+                                                                        \
 68.3191 -+          if (ignore)                                                        \
 68.3192 -+            {                                                                \
 68.3193 -+              if ((ignore == nonprinting && !iswprint (WC))                \
 68.3194 -+                   || (ignore == nondictionary                                \
 68.3195 -+                       && !iswalnum (WC) && !iswblank (WC)))                \
 68.3196 -+                {                                                        \
 68.3197 -+                  i += MBLENGTH;                                        \
 68.3198 -+                  continue;                                                \
 68.3199 -+                }                                                        \
 68.3200 -+            }                                                                \
 68.3201 -+                                                                        \
 68.3202 -+          if (translate)                                                \
 68.3203 -+            {                                                                \
 68.3204 -+                                                                        \
 68.3205 -+              uwc = towupper(WC);                                        \
 68.3206 -+              if (WC == uwc)                                                \
 68.3207 -+                {                                                        \
 68.3208 -+                  memcpy (mbc, TEXT + i, MBLENGTH);                        \
 68.3209 -+                  i += MBLENGTH;                                        \
 68.3210 -+                }                                                        \
 68.3211 -+              else                                                        \
 68.3212 -+                {                                                        \
 68.3213 -+                  i += MBLENGTH;                                        \
 68.3214 -+                  WC = uwc;                                                \
 68.3215 -+                  memset (&state_wc, '\0', sizeof (mbstate_t));                \
 68.3216 -+                                                                        \
 68.3217 -+                  MBLENGTH = wcrtomb (mbc, WC, &state_wc);                \
 68.3218 -+                  assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0);        \
 68.3219 -+                }                                                        \
 68.3220 -+                                                                        \
 68.3221 -+              for (j = 0; j < MBLENGTH; j++)                                \
 68.3222 -+                COPY[NEW_LEN++] = mbc[j];                                \
 68.3223 -+            }                                                                \
 68.3224 -+          else                                                                \
 68.3225 -+            for (j = 0; j < MBLENGTH; j++)                                \
 68.3226 -+              COPY[NEW_LEN++] = TEXT[i++];                                \
 68.3227 -+        }                                                                \
 68.3228 -+      COPY[NEW_LEN] = '\0';                                                \
 68.3229 -+    }                                                                        \
 68.3230 -+  while (0)
 68.3231 -+
 68.3232 -+      /* Actually compare the fields. */
 68.3233 -+
 68.3234 -+  for (;;)
 68.3235 -+    {
 68.3236 -+      /* Find the lengths. */
 68.3237 -+      size_t lena = lima <= texta ? 0 : lima - texta;
 68.3238 -+      size_t lenb = limb <= textb ? 0 : limb - textb;
 68.3239 -+
 68.3240 -+      char enda IF_LINT (= 0);
 68.3241 -+      char endb IF_LINT (= 0);
 68.3242 -+
 68.3243 -+      char const *translate = key->translate;
 68.3244 -+      bool const *ignore = key->ignore;
 68.3245 -+
 68.3246 -+      if (ignore || translate)
 68.3247 -+        {
 68.3248 -+          if (SIZE_MAX - lenb - 2 < lena)
 68.3249 -+            xalloc_die ();
 68.3250 -+          char *copy_a = (char *) xnmalloc (lena + lenb + 2, MB_CUR_MAX);
 68.3251 -+          char *copy_b = copy_a + lena * MB_CUR_MAX + 1;
 68.3252 -+          size_t new_len_a, new_len_b;
 68.3253 -+          size_t i, j;
 68.3254 -+
 68.3255 -+          IGNORE_CHARS (new_len_a, lena, texta, copy_a,
 68.3256 -+                        wc_a, mblength_a, state_a);
 68.3257 -+          IGNORE_CHARS (new_len_b, lenb, textb, copy_b,
 68.3258 -+                        wc_b, mblength_b, state_b);
 68.3259 -+          texta = copy_a; textb = copy_b;
 68.3260 -+          lena = new_len_a; lenb = new_len_b;
 68.3261 -+        }
 68.3262 -+      else
 68.3263 -+        {
 68.3264 -+          /* Use the keys in-place, temporarily null-terminated.  */
 68.3265 -+          enda = texta[lena]; texta[lena] = '\0';
 68.3266 -+          endb = textb[lenb]; textb[lenb] = '\0';
 68.3267 -+        }
 68.3268 -+
 68.3269 -+      if (key->random)
 68.3270 -+        diff = compare_random (texta, lena, textb, lenb);
 68.3271 -+      else if (key->numeric | key->general_numeric | key->human_numeric)
 68.3272 -+        {
 68.3273 -+          char savea = *lima, saveb = *limb;
 68.3274 -+
 68.3275 -+          *lima = *limb = '\0';
 68.3276 -+          diff = (key->numeric ? numcompare (texta, textb)
 68.3277 -+                  : key->general_numeric ? general_numcompare (texta, textb)
 68.3278 -+                  : human_numcompare (texta, textb));
 68.3279 -+          *lima = savea, *limb = saveb;
 68.3280 -+        }
 68.3281 -+      else if (key->version)
 68.3282 -+        diff = filevercmp (texta, textb);
 68.3283 -+      else if (key->month)
 68.3284 -+        diff = getmonth (texta, lena, NULL) - getmonth (textb, lenb, NULL);
 68.3285 -+      else if (lena == 0)
 68.3286 -+        diff = - NONZERO (lenb);
 68.3287 -+      else if (lenb == 0)
 68.3288 -+        diff = 1;
 68.3289 -+      else if (hard_LC_COLLATE && !folding)
 68.3290 -+        {
 68.3291 -+          diff = xmemcoll0 (texta, lena + 1, textb, lenb + 1);
 68.3292 -+        }
 68.3293 -+      else
 68.3294 -+        {
 68.3295 -+          diff = memcmp (texta, textb, MIN (lena, lenb));
 68.3296 -+          if (diff == 0)
 68.3297 -+            diff = lena < lenb ? -1 : lena != lenb;
 68.3298 -+        }
 68.3299 -+
 68.3300 -+      if (ignore || translate)
 68.3301 -+        free (texta);
 68.3302 -+      else
 68.3303 -+        {
 68.3304 -+          texta[lena] = enda;
 68.3305 -+          textb[lenb] = endb;
 68.3306 -+        }
 68.3307 -+
 68.3308 -+      if (diff)
 68.3309 -+        goto not_equal;
 68.3310 -+
 68.3311 -+      key = key->next;
 68.3312 -+      if (! key)
 68.3313 -+        break;
 68.3314 -+
 68.3315 -+      /* Find the beginning and limit of the next field.  */
 68.3316 -+      if (key->eword != -1)
 68.3317 -+        lima = limfield (a, key), limb = limfield (b, key);
 68.3318 -+      else
 68.3319 -+        lima = a->text + a->length - 1, limb = b->text + b->length - 1;
 68.3320 -+
 68.3321 -+      if (key->sword != -1)
 68.3322 -+        texta = begfield (a, key), textb = begfield (b, key);
 68.3323 -+      else
 68.3324 -+        {
 68.3325 -+          texta = a->text, textb = b->text;
 68.3326 -+          if (key->skipsblanks)
 68.3327 -+            {
 68.3328 -+              while (texta < lima && ismbblank (texta, lima - texta, &mblength_a))
 68.3329 -+                texta += mblength_a;
 68.3330 -+              while (textb < limb && ismbblank (textb, limb - textb, &mblength_b))
 68.3331 -+                textb += mblength_b;
 68.3332 -+            }
 68.3333 -+        }
 68.3334 -+    }
 68.3335 -+
 68.3336 -+not_equal:
 68.3337 -+  if (key && key->reverse)
 68.3338 -+    return -diff;
 68.3339 -+  else
 68.3340 -+    return diff;
 68.3341 -+}
 68.3342 -+#endif
 68.3343 -+
 68.3344 - /* Compare two lines A and B, returning negative, zero, or positive
 68.3345 -    depending on whether A compares less than, equal to, or greater than B. */
 68.3346 - 
 68.3347 -@@ -2722,7 +3367,7 @@ compare (struct line const *a, struct li
 68.3348 -     diff = - NONZERO (blen);
 68.3349 -   else if (blen == 0)
 68.3350 -     diff = 1;
 68.3351 --  else if (hard_LC_COLLATE)
 68.3352 -+  else if (hard_LC_COLLATE && !folding)
 68.3353 -     {
 68.3354 -       /* Note xmemcoll0 is a performance enhancement as
 68.3355 -          it will not unconditionally write '\0' after the
 68.3356 -@@ -4121,6 +4766,7 @@ set_ordering (char const *s, struct keyf
 68.3357 -           break;
 68.3358 -         case 'f':
 68.3359 -           key->translate = fold_toupper;
 68.3360 -+          folding = true;
 68.3361 -           break;
 68.3362 -         case 'g':
 68.3363 -           key->general_numeric = true;
 68.3364 -@@ -4199,7 +4845,7 @@ main (int argc, char **argv)
 68.3365 -   initialize_exit_failure (SORT_FAILURE);
 68.3366 - 
 68.3367 -   hard_LC_COLLATE = hard_locale (LC_COLLATE);
 68.3368 --#if HAVE_NL_LANGINFO
 68.3369 -+#if HAVE_LANGINFO_CODESET
 68.3370 -   hard_LC_TIME = hard_locale (LC_TIME);
 68.3371 - #endif
 68.3372 - 
 68.3373 -@@ -4220,6 +4866,29 @@ main (int argc, char **argv)
 68.3374 -       thousands_sep = -1;
 68.3375 -   }
 68.3376 - 
 68.3377 -+#if HAVE_MBRTOWC
 68.3378 -+  if (MB_CUR_MAX > 1)
 68.3379 -+    {
 68.3380 -+      inittables = inittables_mb;
 68.3381 -+      begfield = begfield_mb;
 68.3382 -+      limfield = limfield_mb;
 68.3383 -+      skipblanks = skipblanks_mb;
 68.3384 -+      getmonth = getmonth_mb;
 68.3385 -+      keycompare = keycompare_mb;
 68.3386 -+      numcompare = numcompare_mb;
 68.3387 -+    }
 68.3388 -+  else
 68.3389 -+#endif
 68.3390 -+    {
 68.3391 -+      inittables = inittables_uni;
 68.3392 -+      begfield = begfield_uni;
 68.3393 -+      limfield = limfield_uni;
 68.3394 -+      skipblanks = skipblanks_uni;
 68.3395 -+      getmonth = getmonth_uni;
 68.3396 -+      keycompare = keycompare_uni;
 68.3397 -+      numcompare = numcompare_uni;
 68.3398 -+    }
 68.3399 -+
 68.3400 -   have_read_stdin = false;
 68.3401 -   inittables ();
 68.3402 - 
 68.3403 -@@ -4494,13 +5163,34 @@ main (int argc, char **argv)
 68.3404 - 
 68.3405 -         case 't':
 68.3406 -           {
 68.3407 --            char newtab = optarg[0];
 68.3408 --            if (! newtab)
 68.3409 -+            char newtab[MB_LEN_MAX + 1];
 68.3410 -+            size_t newtab_length = 1;
 68.3411 -+            strncpy (newtab, optarg, MB_LEN_MAX);
 68.3412 -+            if (! newtab[0])
 68.3413 -               error (SORT_FAILURE, 0, _("empty tab"));
 68.3414 --            if (optarg[1])
 68.3415 -+#if HAVE_MBRTOWC
 68.3416 -+            if (MB_CUR_MAX > 1)
 68.3417 -+              {
 68.3418 -+                wchar_t wc;
 68.3419 -+                mbstate_t state;
 68.3420 -+
 68.3421 -+                memset (&state, '\0', sizeof (mbstate_t));
 68.3422 -+                newtab_length = mbrtowc (&wc, newtab, strnlen (newtab,
 68.3423 -+                                                               MB_LEN_MAX),
 68.3424 -+                                         &state);
 68.3425 -+                switch (newtab_length)
 68.3426 -+                  {
 68.3427 -+                  case (size_t) -1:
 68.3428 -+                  case (size_t) -2:
 68.3429 -+                  case 0:
 68.3430 -+                    newtab_length = 1;
 68.3431 -+                  }
 68.3432 -+              }
 68.3433 -+#endif
 68.3434 -+            if (newtab_length == 1 && optarg[1])
 68.3435 -               {
 68.3436 -                 if (STREQ (optarg, "\\0"))
 68.3437 --                  newtab = '\0';
 68.3438 -+                  newtab[0] = '\0';
 68.3439 -                 else
 68.3440 -                   {
 68.3441 -                     /* Provoke with 'sort -txx'.  Complain about
 68.3442 -@@ -4511,9 +5201,12 @@ main (int argc, char **argv)
 68.3443 -                            quote (optarg));
 68.3444 -                   }
 68.3445 -               }
 68.3446 --            if (tab != TAB_DEFAULT && tab != newtab)
 68.3447 -+            if (tab_length
 68.3448 -+                && (tab_length != newtab_length
 68.3449 -+                    || memcmp (tab, newtab, tab_length) != 0))
 68.3450 -               error (SORT_FAILURE, 0, _("incompatible tabs"));
 68.3451 --            tab = newtab;
 68.3452 -+            memcpy (tab, newtab, newtab_length);
 68.3453 -+            tab_length = newtab_length;
 68.3454 -           }
 68.3455 -           break;
 68.3456 - 
 68.3457 -@@ -4751,12 +5444,10 @@ main (int argc, char **argv)
 68.3458 -       sort (files, nfiles, outfile, nthreads);
 68.3459 -     }
 68.3460 - 
 68.3461 --#ifdef lint
 68.3462 -   if (files_from)
 68.3463 -     readtokens0_free (&tok);
 68.3464 -   else
 68.3465 -     free (files);
 68.3466 --#endif
 68.3467 - 
 68.3468 -   if (have_read_stdin && fclose (stdin) == EOF)
 68.3469 -     die (_("close failed"), "-");
 68.3470 -diff -Naurp coreutils-8.25-orig/src/unexpand.c coreutils-8.25/src/unexpand.c
 68.3471 ---- coreutils-8.25-orig/src/unexpand.c	2016-01-01 07:48:50.000000000 -0600
 68.3472 -+++ coreutils-8.25/src/unexpand.c	2016-02-08 19:07:10.311944651 -0600
 68.3473 -@@ -38,12 +38,29 @@
 68.3474 - #include <stdio.h>
 68.3475 - #include <getopt.h>
 68.3476 - #include <sys/types.h>
 68.3477 -+
 68.3478 -+/* Get mbstate_t, mbrtowc(), wcwidth(). */
 68.3479 -+#if HAVE_WCHAR_H
 68.3480 -+# include <wchar.h>
 68.3481 -+#endif
 68.3482 -+
 68.3483 - #include "system.h"
 68.3484 - #include "error.h"
 68.3485 - #include "fadvise.h"
 68.3486 - #include "quote.h"
 68.3487 - #include "xstrndup.h"
 68.3488 - 
 68.3489 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
 68.3490 -+      installation; work around this configuration error.  */
 68.3491 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
 68.3492 -+# define MB_LEN_MAX 16
 68.3493 -+#endif
 68.3494 -+
 68.3495 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
 68.3496 -+#if HAVE_MBRTOWC && defined mbstate_t
 68.3497 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
 68.3498 -+#endif
 68.3499 -+
 68.3500 - /* The official name of this program (e.g., no 'g' prefix).  */
 68.3501 - #define PROGRAM_NAME "unexpand"
 68.3502 - 
 68.3503 -@@ -103,6 +120,210 @@ static struct option const longopts[] =
 68.3504 -   {NULL, 0, NULL, 0}
 68.3505 - };
 68.3506 - 
 68.3507 -+static FILE *next_file (FILE *fp);
 68.3508 -+
 68.3509 -+#if HAVE_MBRTOWC
 68.3510 -+static void
 68.3511 -+unexpand_multibyte (void)
 68.3512 -+{
 68.3513 -+  FILE *fp;			/* Input stream. */
 68.3514 -+  mbstate_t i_state;		/* Current shift state of the input stream. */
 68.3515 -+  mbstate_t i_state_bak;	/* Back up the I_STATE. */
 68.3516 -+  mbstate_t o_state;		/* Current shift state of the output stream. */
 68.3517 -+  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
 68.3518 -+  char *bufpos = buf;			/* Next read position of BUF. */
 68.3519 -+  size_t buflen = 0;		/* The length of the byte sequence in buf. */
 68.3520 -+  wint_t wc;			/* A gotten wide character. */
 68.3521 -+  size_t mblength;		/* The byte size of a multibyte character
 68.3522 -+				   which shows as same character as WC. */
 68.3523 -+  bool prev_tab = false;
 68.3524 -+
 68.3525 -+  /* Index in `tab_list' of next tabstop: */
 68.3526 -+  int tab_index = 0;		/* For calculating width of pending tabs. */
 68.3527 -+  int print_tab_index = 0;	/* For printing as many tabs as possible. */
 68.3528 -+  unsigned int column = 0;	/* Column on screen of next char. */
 68.3529 -+  int next_tab_column;		/* Column the next tab stop is on. */
 68.3530 -+  int convert = 1;		/* If nonzero, perform translations. */
 68.3531 -+  unsigned int pending = 0;	/* Pending columns of blanks. */
 68.3532 -+
 68.3533 -+  fp = next_file ((FILE *) NULL);
 68.3534 -+  if (fp == NULL)
 68.3535 -+    return;
 68.3536 -+
 68.3537 -+  memset (&o_state, '\0', sizeof(mbstate_t));
 68.3538 -+  memset (&i_state, '\0', sizeof(mbstate_t));
 68.3539 -+
 68.3540 -+  for (;;)
 68.3541 -+    {
 68.3542 -+      if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp))
 68.3543 -+	{
 68.3544 -+	  memmove (buf, bufpos, buflen);
 68.3545 -+	  buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp);
 68.3546 -+	  bufpos = buf;
 68.3547 -+	}
 68.3548 -+
 68.3549 -+      /* Get a wide character. */
 68.3550 -+      if (buflen < 1)
 68.3551 -+	{
 68.3552 -+	  mblength = 1;
 68.3553 -+	  wc = WEOF;
 68.3554 -+	}
 68.3555 -+      else
 68.3556 -+	{
 68.3557 -+	  i_state_bak = i_state;
 68.3558 -+	  mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &i_state);
 68.3559 -+	}
 68.3560 -+
 68.3561 -+      if (mblength == (size_t)-1 || mblength == (size_t)-2)
 68.3562 -+	{
 68.3563 -+	  i_state = i_state_bak;
 68.3564 -+	  wc = L'\0';
 68.3565 -+	}
 68.3566 -+
 68.3567 -+      if (wc == L' ' && convert && column < INT_MAX)
 68.3568 -+	{
 68.3569 -+	  ++pending;
 68.3570 -+	  ++column;
 68.3571 -+	}
 68.3572 -+      else if (wc == L'\t' && convert)
 68.3573 -+	{
 68.3574 -+	  if (tab_size == 0)
 68.3575 -+	    {
 68.3576 -+	      /* Do not let tab_index == first_free_tab;
 68.3577 -+		 stop when it is 1 less. */
 68.3578 -+	      while (tab_index < first_free_tab - 1
 68.3579 -+		  && column >= tab_list[tab_index])
 68.3580 -+		tab_index++;
 68.3581 -+	      next_tab_column = tab_list[tab_index];
 68.3582 -+	      if (tab_index < first_free_tab - 1)
 68.3583 -+		tab_index++;
 68.3584 -+	      if (column >= next_tab_column)
 68.3585 -+		{
 68.3586 -+		  convert = 0;	/* Ran out of tab stops. */
 68.3587 -+		  goto flush_pend_mb;
 68.3588 -+		}
 68.3589 -+	    }
 68.3590 -+	  else
 68.3591 -+	    {
 68.3592 -+	      next_tab_column = column + tab_size - column % tab_size;
 68.3593 -+	    }
 68.3594 -+	  pending += next_tab_column - column;
 68.3595 -+	  column = next_tab_column;
 68.3596 -+	}
 68.3597 -+      else
 68.3598 -+	{
 68.3599 -+flush_pend_mb:
 68.3600 -+	  /* Flush pending spaces.  Print as many tabs as possible,
 68.3601 -+	     then print the rest as spaces. */
 68.3602 -+	  if (pending == 1 && column != 1 && !prev_tab)
 68.3603 -+	    {
 68.3604 -+	      putchar (' ');
 68.3605 -+	      pending = 0;
 68.3606 -+	    }
 68.3607 -+	  column -= pending;
 68.3608 -+	  while (pending > 0)
 68.3609 -+	    {
 68.3610 -+	      if (tab_size == 0)
 68.3611 -+		{
 68.3612 -+		  /* Do not let print_tab_index == first_free_tab;
 68.3613 -+		     stop when it is 1 less. */
 68.3614 -+		  while (print_tab_index < first_free_tab - 1
 68.3615 -+		      && column >= tab_list[print_tab_index])
 68.3616 -+		    print_tab_index++;
 68.3617 -+		  next_tab_column = tab_list[print_tab_index];
 68.3618 -+		  if (print_tab_index < first_free_tab - 1)
 68.3619 -+		    print_tab_index++;
 68.3620 -+		}
 68.3621 -+	      else
 68.3622 -+		{
 68.3623 -+		  next_tab_column =
 68.3624 -+		    column + tab_size - column % tab_size;
 68.3625 -+		}
 68.3626 -+	      if (next_tab_column - column <= pending)
 68.3627 -+		{
 68.3628 -+		  putchar ('\t');
 68.3629 -+		  pending -= next_tab_column - column;
 68.3630 -+		  column = next_tab_column;
 68.3631 -+		}
 68.3632 -+	      else
 68.3633 -+		{
 68.3634 -+		  --print_tab_index;
 68.3635 -+		  column += pending;
 68.3636 -+		  while (pending != 0)
 68.3637 -+		    {
 68.3638 -+		      putchar (' ');
 68.3639 -+		      pending--;
 68.3640 -+		    }
 68.3641 -+		}
 68.3642 -+	    }
 68.3643 -+
 68.3644 -+	  if (wc == WEOF)
 68.3645 -+	    {
 68.3646 -+	      fp = next_file (fp);
 68.3647 -+	      if (fp == NULL)
 68.3648 -+		break;          /* No more files. */
 68.3649 -+	      else
 68.3650 -+		{
 68.3651 -+		  memset (&i_state, '\0', sizeof(mbstate_t));
 68.3652 -+		  continue;
 68.3653 -+		}
 68.3654 -+	    }
 68.3655 -+
 68.3656 -+	  if (mblength == (size_t)-1 || mblength == (size_t)-2)
 68.3657 -+	    {
 68.3658 -+	      if (convert)
 68.3659 -+		{
 68.3660 -+		  ++column;
 68.3661 -+		  if (convert_entire_line == 0)
 68.3662 -+		    convert = 0;
 68.3663 -+		}
 68.3664 -+	      mblength = 1;
 68.3665 -+	      putchar (buf[0]);
 68.3666 -+	    }
 68.3667 -+	  else if (mblength == 0)
 68.3668 -+	    {
 68.3669 -+	      if (convert && convert_entire_line == 0)
 68.3670 -+		convert = 0;
 68.3671 -+	      mblength = 1;
 68.3672 -+	      putchar ('\0');
 68.3673 -+	    }
 68.3674 -+	  else
 68.3675 -+	    {
 68.3676 -+	      if (convert)
 68.3677 -+		{
 68.3678 -+		  if (wc == L'\b')
 68.3679 -+		    {
 68.3680 -+		      if (column > 0)
 68.3681 -+			--column;
 68.3682 -+		    }
 68.3683 -+		  else
 68.3684 -+		    {
 68.3685 -+		      int width;            /* The width of WC. */
 68.3686 -+
 68.3687 -+		      width = wcwidth (wc);
 68.3688 -+		      column += (width > 0) ? width : 0;
 68.3689 -+		      if (convert_entire_line == 0)
 68.3690 -+			convert = 0;
 68.3691 -+		    }
 68.3692 -+		}
 68.3693 -+
 68.3694 -+	      if (wc == L'\n')
 68.3695 -+		{
 68.3696 -+		  tab_index = print_tab_index = 0;
 68.3697 -+		  column = pending = 0;
 68.3698 -+		  convert = 1;
 68.3699 -+		}
 68.3700 -+	      fwrite (bufpos, sizeof(char), mblength, stdout);
 68.3701 -+	    }
 68.3702 -+	}
 68.3703 -+      prev_tab = wc == L'\t';
 68.3704 -+      buflen -= mblength;
 68.3705 -+      bufpos += mblength;
 68.3706 -+    }
 68.3707 -+}
 68.3708 -+#endif
 68.3709 -+
 68.3710 -+
 68.3711 - void
 68.3712 - usage (int status)
 68.3713 - {
 68.3714 -@@ -523,7 +744,12 @@ main (int argc, char **argv)
 68.3715 - 
 68.3716 -   file_list = (optind < argc ? &argv[optind] : stdin_argv);
 68.3717 - 
 68.3718 --  unexpand ();
 68.3719 -+#if HAVE_MBRTOWC
 68.3720 -+  if (MB_CUR_MAX > 1)
 68.3721 -+    unexpand_multibyte ();
 68.3722 -+  else
 68.3723 -+#endif
 68.3724 -+    unexpand ();
 68.3725 - 
 68.3726 -   if (have_read_stdin && fclose (stdin) != 0)
 68.3727 -     error (EXIT_FAILURE, errno, "-");
 68.3728 -diff -Naurp coreutils-8.25-orig/src/uniq.c coreutils-8.25/src/uniq.c
 68.3729 ---- coreutils-8.25-orig/src/uniq.c	2016-01-13 05:08:59.000000000 -0600
 68.3730 -+++ coreutils-8.25/src/uniq.c	2016-02-08 19:07:10.312944654 -0600
 68.3731 -@@ -21,6 +21,17 @@
 68.3732 - #include <getopt.h>
 68.3733 - #include <sys/types.h>
 68.3734 - 
 68.3735 -+/* Get mbstate_t, mbrtowc(). */
 68.3736 -+#if HAVE_WCHAR_H
 68.3737 -+# include <wchar.h>
 68.3738 -+#endif
 68.3739 -+
 68.3740 -+/* Get isw* functions. */
 68.3741 -+#if HAVE_WCTYPE_H
 68.3742 -+# include <wctype.h>
 68.3743 -+#endif
 68.3744 -+#include <assert.h>
 68.3745 -+
 68.3746 - #include "system.h"
 68.3747 - #include "argmatch.h"
 68.3748 - #include "linebuffer.h"
 68.3749 -@@ -33,6 +44,18 @@
 68.3750 - #include "xstrtol.h"
 68.3751 - #include "memcasecmp.h"
 68.3752 - #include "quote.h"
 68.3753 -+#include "xmemcoll.h"
 68.3754 -+
 68.3755 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
 68.3756 -+   installation; work around this configuration error.  */
 68.3757 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
 68.3758 -+# define MB_LEN_MAX 16
 68.3759 -+#endif
 68.3760 -+
 68.3761 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
 68.3762 -+#if HAVE_MBRTOWC && defined mbstate_t
 68.3763 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
 68.3764 -+#endif
 68.3765 - 
 68.3766 - /* The official name of this program (e.g., no 'g' prefix).  */
 68.3767 - #define PROGRAM_NAME "uniq"
 68.3768 -@@ -143,6 +166,10 @@ enum
 68.3769 -   GROUP_OPTION = CHAR_MAX + 1
 68.3770 - };
 68.3771 - 
 68.3772 -+/* Function pointers. */
 68.3773 -+static char *
 68.3774 -+(*find_field) (struct linebuffer *line);
 68.3775 -+
 68.3776 - static struct option const longopts[] =
 68.3777 - {
 68.3778 -   {"count", no_argument, NULL, 'c'},
 68.3779 -@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *m
 68.3780 -    return a pointer to the beginning of the line's field to be compared. */
 68.3781 - 
 68.3782 - static char * _GL_ATTRIBUTE_PURE
 68.3783 --find_field (struct linebuffer const *line)
 68.3784 -+find_field_uni (struct linebuffer *line)
 68.3785 - {
 68.3786 -   size_t count;
 68.3787 -   char const *lp = line->buffer;
 68.3788 -@@ -272,6 +299,83 @@ find_field (struct linebuffer const *lin
 68.3789 -   return line->buffer + i;
 68.3790 - }
 68.3791 - 
 68.3792 -+#if HAVE_MBRTOWC
 68.3793 -+
 68.3794 -+# define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL)  \
 68.3795 -+  do                                                                        \
 68.3796 -+    {                                                                        \
 68.3797 -+      mbstate_t state_bak;                                                \
 68.3798 -+                                                                        \
 68.3799 -+      CONVFAIL = 0;                                                        \
 68.3800 -+      state_bak = *STATEP;                                                \
 68.3801 -+                                                                        \
 68.3802 -+      MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP);                \
 68.3803 -+                                                                        \
 68.3804 -+      switch (MBLENGTH)                                                        \
 68.3805 -+        {                                                                \
 68.3806 -+        case (size_t)-2:                                                \
 68.3807 -+        case (size_t)-1:                                                \
 68.3808 -+          *STATEP = state_bak;                                                \
 68.3809 -+          CONVFAIL++;                                                        \
 68.3810 -+          /* Fall through */                                                \
 68.3811 -+        case 0:                                                                \
 68.3812 -+          MBLENGTH = 1;                                                        \
 68.3813 -+        }                                                                \
 68.3814 -+    }                                                                        \
 68.3815 -+  while (0)
 68.3816 -+
 68.3817 -+static char *
 68.3818 -+find_field_multi (struct linebuffer *line)
 68.3819 -+{
 68.3820 -+  size_t count;
 68.3821 -+  char *lp = line->buffer;
 68.3822 -+  size_t size = line->length - 1;
 68.3823 -+  size_t pos;
 68.3824 -+  size_t mblength;
 68.3825 -+  wchar_t wc;
 68.3826 -+  mbstate_t *statep;
 68.3827 -+  int convfail = 0;
 68.3828 -+
 68.3829 -+  pos = 0;
 68.3830 -+  statep = &(line->state);
 68.3831 -+
 68.3832 -+  /* skip fields. */
 68.3833 -+  for (count = 0; count < skip_fields && pos < size; count++)
 68.3834 -+    {
 68.3835 -+      while (pos < size)
 68.3836 -+        {
 68.3837 -+          MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
 68.3838 -+
 68.3839 -+          if (convfail || !(iswblank (wc) || wc == '\n'))
 68.3840 -+            {
 68.3841 -+              pos += mblength;
 68.3842 -+              break;
 68.3843 -+            }
 68.3844 -+          pos += mblength;
 68.3845 -+        }
 68.3846 -+
 68.3847 -+      while (pos < size)
 68.3848 -+        {
 68.3849 -+          MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
 68.3850 -+
 68.3851 -+          if (!convfail && (iswblank (wc) || wc == '\n'))
 68.3852 -+            break;
 68.3853 -+
 68.3854 -+          pos += mblength;
 68.3855 -+        }
 68.3856 -+    }
 68.3857 -+
 68.3858 -+  /* skip fields. */
 68.3859 -+  for (count = 0; count < skip_chars && pos < size; count++)
 68.3860 -+    {
 68.3861 -+      MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
 68.3862 -+      pos += mblength;
 68.3863 -+    }
 68.3864 -+
 68.3865 -+  return lp + pos;
 68.3866 -+}
 68.3867 -+#endif
 68.3868 -+
 68.3869 - /* Return false if two strings OLD and NEW match, true if not.
 68.3870 -    OLD and NEW point not to the beginnings of the lines
 68.3871 -    but rather to the beginnings of the fields to compare.
 68.3872 -@@ -280,6 +384,8 @@ find_field (struct linebuffer const *lin
 68.3873 - static bool
 68.3874 - different (char *old, char *new, size_t oldlen, size_t newlen)
 68.3875 - {
 68.3876 -+  char *copy_old, *copy_new;
 68.3877 -+
 68.3878 -   if (check_chars < oldlen)
 68.3879 -     oldlen = check_chars;
 68.3880 -   if (check_chars < newlen)
 68.3881 -@@ -287,15 +393,104 @@ different (char *old, char *new, size_t
 68.3882 - 
 68.3883 -   if (ignore_case)
 68.3884 -     {
 68.3885 --      /* FIXME: This should invoke strcoll somehow.  */
 68.3886 --      return oldlen != newlen || memcasecmp (old, new, oldlen);
 68.3887 -+      size_t i;
 68.3888 -+
 68.3889 -+      copy_old = xmalloc (oldlen + 1);
 68.3890 -+      copy_new = xmalloc (oldlen + 1);
 68.3891 -+
 68.3892 -+      for (i = 0; i < oldlen; i++)
 68.3893 -+        {
 68.3894 -+          copy_old[i] = toupper (old[i]);
 68.3895 -+          copy_new[i] = toupper (new[i]);
 68.3896 -+        }
 68.3897 -+      bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen);
 68.3898 -+      free (copy_old);
 68.3899 -+      free (copy_new);
 68.3900 -+      return rc;
 68.3901 -     }
 68.3902 --  else if (hard_LC_COLLATE)
 68.3903 --    return xmemcoll (old, oldlen, new, newlen) != 0;
 68.3904 -   else
 68.3905 --    return oldlen != newlen || memcmp (old, new, oldlen);
 68.3906 -+    {
 68.3907 -+      copy_old = (char *)old;
 68.3908 -+      copy_new = (char *)new;
 68.3909 -+    }
 68.3910 -+
 68.3911 -+  return xmemcoll (copy_old, oldlen, copy_new, newlen);
 68.3912 -+
 68.3913 - }
 68.3914 - 
 68.3915 -+#if HAVE_MBRTOWC
 68.3916 -+static int
 68.3917 -+different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate)
 68.3918 -+{
 68.3919 -+  size_t i, j, chars;
 68.3920 -+  const char *str[2];
 68.3921 -+  char *copy[2];
 68.3922 -+  size_t len[2];
 68.3923 -+  mbstate_t state[2];
 68.3924 -+  size_t mblength;
 68.3925 -+  wchar_t wc, uwc;
 68.3926 -+  mbstate_t state_bak;
 68.3927 -+
 68.3928 -+  str[0] = old;
 68.3929 -+  str[1] = new;
 68.3930 -+  len[0] = oldlen;
 68.3931 -+  len[1] = newlen;
 68.3932 -+  state[0] = oldstate;
 68.3933 -+  state[1] = newstate;
 68.3934 -+
 68.3935 -+  for (i = 0; i < 2; i++)
 68.3936 -+    {
 68.3937 -+      copy[i] = xmalloc (len[i] + 1);
 68.3938 -+      memset (copy[i], '\0', len[i] + 1);
 68.3939 -+
 68.3940 -+      for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++)
 68.3941 -+        {
 68.3942 -+          state_bak = state[i];
 68.3943 -+          mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i]));
 68.3944 -+
 68.3945 -+          switch (mblength)
 68.3946 -+            {
 68.3947 -+            case (size_t)-1:
 68.3948 -+            case (size_t)-2:
 68.3949 -+              state[i] = state_bak;
 68.3950 -+              /* Fall through */
 68.3951 -+            case 0:
 68.3952 -+              mblength = 1;
 68.3953 -+              break;
 68.3954 -+
 68.3955 -+            default:
 68.3956 -+              if (ignore_case)
 68.3957 -+                {
 68.3958 -+                  uwc = towupper (wc);
 68.3959 -+
 68.3960 -+                  if (uwc != wc)
 68.3961 -+                    {
 68.3962 -+                      mbstate_t state_wc;
 68.3963 -+                      size_t mblen;
 68.3964 -+
 68.3965 -+                      memset (&state_wc, '\0', sizeof(mbstate_t));
 68.3966 -+                      mblen = wcrtomb (copy[i] + j, uwc, &state_wc);
 68.3967 -+                      assert (mblen != (size_t)-1);
 68.3968 -+                    }
 68.3969 -+                  else
 68.3970 -+                    memcpy (copy[i] + j, str[i] + j, mblength);
 68.3971 -+                }
 68.3972 -+              else
 68.3973 -+                memcpy (copy[i] + j, str[i] + j, mblength);
 68.3974 -+            }
 68.3975 -+          j += mblength;
 68.3976 -+        }
 68.3977 -+      copy[i][j] = '\0';
 68.3978 -+      len[i] = j;
 68.3979 -+    }
 68.3980 -+  int rc = xmemcoll (copy[0], len[0], copy[1], len[1]);
 68.3981 -+  free (copy[0]);
 68.3982 -+  free (copy[1]);
 68.3983 -+  return rc;
 68.3984 -+
 68.3985 -+}
 68.3986 -+#endif
 68.3987 -+
 68.3988 - /* Output the line in linebuffer LINE to standard output
 68.3989 -    provided that the switches say it should be output.
 68.3990 -    MATCH is true if the line matches the previous line.
 68.3991 -@@ -359,19 +554,38 @@ check_file (const char *infile, const ch
 68.3992 -       char *prevfield IF_LINT ( = NULL);
 68.3993 -       size_t prevlen IF_LINT ( = 0);
 68.3994 -       bool first_group_printed = false;
 68.3995 -+#if HAVE_MBRTOWC
 68.3996 -+      mbstate_t prevstate;
 68.3997 -+
 68.3998 -+      memset (&prevstate, '\0', sizeof (mbstate_t));
 68.3999 -+#endif
 68.4000 - 
 68.4001 -       while (!feof (stdin))
 68.4002 -         {
 68.4003 -           char *thisfield;
 68.4004 -           size_t thislen;
 68.4005 -           bool new_group;
 68.4006 -+#if HAVE_MBRTOWC
 68.4007 -+          mbstate_t thisstate;
 68.4008 -+#endif
 68.4009 - 
 68.4010 -           if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
 68.4011 -             break;
 68.4012 - 
 68.4013 -           thisfield = find_field (thisline);
 68.4014 -           thislen = thisline->length - 1 - (thisfield - thisline->buffer);
 68.4015 -+#if HAVE_MBRTOWC
 68.4016 -+          if (MB_CUR_MAX > 1)
 68.4017 -+            {
 68.4018 -+              thisstate = thisline->state;
 68.4019 - 
 68.4020 -+              new_group = (prevline->length == 0
 68.4021 -+                           || different_multi (thisfield, prevfield,
 68.4022 -+                                               thislen, prevlen,
 68.4023 -+                                               thisstate, prevstate));
 68.4024 -+            }
 68.4025 -+          else
 68.4026 -+#endif
 68.4027 -           new_group = (prevline->length == 0
 68.4028 -                        || different (thisfield, prevfield, thislen, prevlen));
 68.4029 - 
 68.4030 -@@ -389,6 +603,10 @@ check_file (const char *infile, const ch
 68.4031 -               SWAP_LINES (prevline, thisline);
 68.4032 -               prevfield = thisfield;
 68.4033 -               prevlen = thislen;
 68.4034 -+#if HAVE_MBRTOWC
 68.4035 -+              if (MB_CUR_MAX > 1)
 68.4036 -+                prevstate = thisstate;
 68.4037 -+#endif
 68.4038 -               first_group_printed = true;
 68.4039 -             }
 68.4040 -         }
 68.4041 -@@ -401,17 +619,26 @@ check_file (const char *infile, const ch
 68.4042 -       size_t prevlen;
 68.4043 -       uintmax_t match_count = 0;
 68.4044 -       bool first_delimiter = true;
 68.4045 -+#if HAVE_MBRTOWC
 68.4046 -+      mbstate_t prevstate;
 68.4047 -+#endif
 68.4048 - 
 68.4049 -       if (readlinebuffer_delim (prevline, stdin, delimiter) == 0)
 68.4050 -         goto closefiles;
 68.4051 -       prevfield = find_field (prevline);
 68.4052 -       prevlen = prevline->length - 1 - (prevfield - prevline->buffer);
 68.4053 -+#if HAVE_MBRTOWC
 68.4054 -+      prevstate = prevline->state;
 68.4055 -+#endif
 68.4056 - 
 68.4057 -       while (!feof (stdin))
 68.4058 -         {
 68.4059 -           bool match;
 68.4060 -           char *thisfield;
 68.4061 -           size_t thislen;
 68.4062 -+#if HAVE_MBRTOWC
 68.4063 -+          mbstate_t thisstate = thisline->state;
 68.4064 -+#endif
 68.4065 -           if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
 68.4066 -             {
 68.4067 -               if (ferror (stdin))
 68.4068 -@@ -420,6 +647,14 @@ check_file (const char *infile, const ch
 68.4069 -             }
 68.4070 -           thisfield = find_field (thisline);
 68.4071 -           thislen = thisline->length - 1 - (thisfield - thisline->buffer);
 68.4072 -+#if HAVE_MBRTOWC
 68.4073 -+          if (MB_CUR_MAX > 1)
 68.4074 -+            {
 68.4075 -+              match = !different_multi (thisfield, prevfield,
 68.4076 -+                                thislen, prevlen, thisstate, prevstate);
 68.4077 -+            }
 68.4078 -+          else
 68.4079 -+#endif
 68.4080 -           match = !different (thisfield, prevfield, thislen, prevlen);
 68.4081 -           match_count += match;
 68.4082 - 
 68.4083 -@@ -452,6 +687,9 @@ check_file (const char *infile, const ch
 68.4084 -               SWAP_LINES (prevline, thisline);
 68.4085 -               prevfield = thisfield;
 68.4086 -               prevlen = thislen;
 68.4087 -+#if HAVE_MBRTOWC
 68.4088 -+              prevstate = thisstate;
 68.4089 -+#endif
 68.4090 -               if (!match)
 68.4091 -                 match_count = 0;
 68.4092 -             }
 68.4093 -@@ -498,6 +736,19 @@ main (int argc, char **argv)
 68.4094 - 
 68.4095 -   atexit (close_stdout);
 68.4096 - 
 68.4097 -+#if HAVE_MBRTOWC
 68.4098 -+  if (MB_CUR_MAX > 1)
 68.4099 -+    {
 68.4100 -+      find_field = find_field_multi;
 68.4101 -+    }
 68.4102 -+  else
 68.4103 -+#endif
 68.4104 -+    {
 68.4105 -+      find_field = find_field_uni;
 68.4106 -+    }
 68.4107 -+
 68.4108 -+
 68.4109 -+
 68.4110 -   skip_chars = 0;
 68.4111 -   skip_fields = 0;
 68.4112 -   check_chars = SIZE_MAX;
 68.4113 -diff -Naurp coreutils-8.25-orig/tests/i18n/sort-month.sh coreutils-8.25/tests/i18n/sort-month.sh
 68.4114 ---- coreutils-8.25-orig/tests/i18n/sort-month.sh	1969-12-31 18:00:00.000000000 -0600
 68.4115 -+++ coreutils-8.25/tests/i18n/sort-month.sh	2016-02-08 19:07:10.312944654 -0600
 68.4116 -@@ -0,0 +1,34 @@
 68.4117 -+#!/bin/sh
 68.4118 -+# Verify sort -M multi-byte support.
 68.4119 -+
 68.4120 -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 68.4121 -+print_ver_ sort
 68.4122 -+require_valgrind_
 68.4123 -+
 68.4124 -+# Skip this test if some deallocations are
 68.4125 -+# avoided at process end.
 68.4126 -+grep '^#define lint 1' $CONFIG_HEADER > /dev/null ||
 68.4127 -+  skip_ 'Allocation checks only work reliably in "lint" mode'
 68.4128 -+
 68.4129 -+export LC_ALL=en_US.UTF-8
 68.4130 -+locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \
 68.4131 -+  || skip_ "No UTF-8 locale available"
 68.4132 -+
 68.4133 -+# Note the use of ɑ here which expands to
 68.4134 -+# a wider representation upon case conversion
 68.4135 -+# which triggered an assertion in sort -M
 68.4136 -+cat <<EOF > exp
 68.4137 -+.
 68.4138 -+ɑ
 68.4139 -+EOF
 68.4140 -+
 68.4141 -+
 68.4142 -+# check large mem leak with --month-sort
 68.4143 -+# https://bugzilla.redhat.com/show_bug.cgi?id=1259942
 68.4144 -+valgrind --leak-check=full \
 68.4145 -+         --error-exitcode=1 --errors-for-leak-kinds=definite \
 68.4146 -+         sort -M < exp > out || fail=1
 68.4147 -+compare exp out || { fail=1; cat out; }
 68.4148 -+
 68.4149 -+
 68.4150 -+Exit $fail
 68.4151 -diff -Naurp coreutils-8.25-orig/tests/i18n/sort.sh coreutils-8.25/tests/i18n/sort.sh
 68.4152 ---- coreutils-8.25-orig/tests/i18n/sort.sh	1969-12-31 18:00:00.000000000 -0600
 68.4153 -+++ coreutils-8.25/tests/i18n/sort.sh	2016-02-08 19:07:10.312944654 -0600
 68.4154 -@@ -0,0 +1,29 @@
 68.4155 -+#!/bin/sh
 68.4156 -+# Verify sort's multi-byte support.
 68.4157 -+
 68.4158 -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 68.4159 -+print_ver_ sort
 68.4160 -+
 68.4161 -+export LC_ALL=en_US.UTF-8
 68.4162 -+locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \
 68.4163 -+  || skip_ "No UTF-8 locale available"
 68.4164 -+
 68.4165 -+# Enable heap consistency checkng on older systems
 68.4166 -+export MALLOC_CHECK_=2
 68.4167 -+
 68.4168 -+
 68.4169 -+# check buffer overflow issue due to
 68.4170 -+# expanding multi-byte representation due to case conversion
 68.4171 -+# https://bugzilla.suse.com/show_bug.cgi?id=928749
 68.4172 -+cat <<EOF > exp
 68.4173 -+.
 68.4174 -+ɑ
 68.4175 -+EOF
 68.4176 -+cat <<EOF | sort -f > out || fail=1
 68.4177 -+.
 68.4178 -+ɑ
 68.4179 -+EOF
 68.4180 -+compare exp out || { fail=1; cat out; }
 68.4181 -+
 68.4182 -+
 68.4183 -+Exit $fail
 68.4184 -diff -Naurp coreutils-8.25-orig/tests/local.mk coreutils-8.25/tests/local.mk
 68.4185 ---- coreutils-8.25-orig/tests/local.mk	2016-01-16 12:18:13.000000000 -0600
 68.4186 -+++ coreutils-8.25/tests/local.mk	2016-02-08 19:07:10.313944658 -0600
 68.4187 -@@ -344,6 +344,9 @@ all_tests =					\
 68.4188 -   tests/misc/sort-discrim.sh			\
 68.4189 -   tests/misc/sort-files0-from.pl		\
 68.4190 -   tests/misc/sort-float.sh			\
 68.4191 -+  tests/misc/sort-mb-tests.sh			\
 68.4192 -+  tests/i18n/sort.sh				\
 68.4193 -+  tests/i18n/sort-month.sh			\
 68.4194 -   tests/misc/sort-merge.pl			\
 68.4195 -   tests/misc/sort-merge-fdlimit.sh		\
 68.4196 -   tests/misc/sort-month.sh			\
 68.4197 -diff -Naurp coreutils-8.25-orig/tests/misc/cut.pl coreutils-8.25/tests/misc/cut.pl
 68.4198 ---- coreutils-8.25-orig/tests/misc/cut.pl	2016-01-16 12:18:13.000000000 -0600
 68.4199 -+++ coreutils-8.25/tests/misc/cut.pl	2016-02-08 19:07:10.314944661 -0600
 68.4200 -@@ -23,9 +23,11 @@ use strict;
 68.4201 - # Turn off localization of executable's output.
 68.4202 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 68.4203 - 
 68.4204 --my $mb_locale = $ENV{LOCALE_FR_UTF8};
 68.4205 -+my $mb_locale;
 68.4206 -+# uncommented enable multibyte paths
 68.4207 -+$mb_locale = $ENV{LOCALE_FR_UTF8};
 68.4208 - ! defined $mb_locale || $mb_locale eq 'none'
 68.4209 --  and $mb_locale = 'C';
 68.4210 -+ and $mb_locale = 'C';
 68.4211 - 
 68.4212 - my $prog = 'cut';
 68.4213 - my $try = "Try '$prog --help' for more information.\n";
 68.4214 -@@ -240,6 +242,7 @@ if ($mb_locale ne 'C')
 68.4215 -         my @new_t = @$t;
 68.4216 -         my $test_name = shift @new_t;
 68.4217 - 
 68.4218 -+        next if ($test_name =~ "newline-[12][0-9]");
 68.4219 -         push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 68.4220 -       }
 68.4221 -     push @Tests, @new;
 68.4222 -diff -Naurp coreutils-8.25-orig/tests/misc/expand.pl coreutils-8.25/tests/misc/expand.pl
 68.4223 ---- coreutils-8.25-orig/tests/misc/expand.pl	2016-01-16 12:18:13.000000000 -0600
 68.4224 -+++ coreutils-8.25/tests/misc/expand.pl	2016-02-08 19:07:10.314944661 -0600
 68.4225 -@@ -23,6 +23,15 @@ use strict;
 68.4226 - # Turn off localization of executable's output.
 68.4227 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 68.4228 - 
 68.4229 -+#comment out next line to disable multibyte tests
 68.4230 -+my $mb_locale = $ENV{LOCALE_FR_UTF8};
 68.4231 -+! defined $mb_locale || $mb_locale eq 'none'
 68.4232 -+ and $mb_locale = 'C';
 68.4233 -+
 68.4234 -+my $prog = 'expand';
 68.4235 -+my $try = "Try \`$prog --help' for more information.\n";
 68.4236 -+my $inval = "$prog: invalid byte, character or field list\n$try";
 68.4237 -+
 68.4238 - my @Tests =
 68.4239 -   (
 68.4240 -    ['t1', '--tabs=3',     {IN=>"a\tb"}, {OUT=>"a  b"}],
 68.4241 -@@ -31,6 +40,37 @@ my @Tests =
 68.4242 -    ['i2', '--tabs=3 -i', {IN=>" \ta\tb"}, {OUT=>"   a\tb"}],
 68.4243 -   );
 68.4244 - 
 68.4245 -+if ($mb_locale ne 'C')
 68.4246 -+  {
 68.4247 -+    # Duplicate each test vector, appending "-mb" to the test name and
 68.4248 -+    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 68.4249 -+    # provide coverage for the distro-added multi-byte code paths.
 68.4250 -+    my @new;
 68.4251 -+    foreach my $t (@Tests)
 68.4252 -+      {
 68.4253 -+        my @new_t = @$t;
 68.4254 -+        my $test_name = shift @new_t;
 68.4255 -+
 68.4256 -+        # Depending on whether expand is multi-byte-patched,
 68.4257 -+        # it emits different diagnostics:
 68.4258 -+        #   non-MB: invalid byte or field list
 68.4259 -+        #   MB:     invalid byte, character or field list
 68.4260 -+        # Adjust the expected error output accordingly.
 68.4261 -+        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 68.4262 -+            (@new_t))
 68.4263 -+          {
 68.4264 -+            my $sub = {ERR_SUBST => 's/, character//'};
 68.4265 -+            push @new_t, $sub;
 68.4266 -+            push @$t, $sub;
 68.4267 -+          }
 68.4268 -+        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 68.4269 -+      }
 68.4270 -+    push @Tests, @new;
 68.4271 -+  }
 68.4272 -+
 68.4273 -+
 68.4274 -+@Tests = triple_test \@Tests;
 68.4275 -+
 68.4276 - my $save_temps = $ENV{DEBUG};
 68.4277 - my $verbose = $ENV{VERBOSE};
 68.4278 - 
 68.4279 -diff -Naurp coreutils-8.25-orig/tests/misc/fold.pl coreutils-8.25/tests/misc/fold.pl
 68.4280 ---- coreutils-8.25-orig/tests/misc/fold.pl	2016-01-16 12:18:13.000000000 -0600
 68.4281 -+++ coreutils-8.25/tests/misc/fold.pl	2016-02-08 19:07:10.314944661 -0600
 68.4282 -@@ -20,9 +20,18 @@ use strict;
 68.4283 - 
 68.4284 - (my $program_name = $0) =~ s|.*/||;
 68.4285 - 
 68.4286 -+my $prog = 'fold';
 68.4287 -+my $try = "Try \`$prog --help' for more information.\n";
 68.4288 -+my $inval = "$prog: invalid byte, character or field list\n$try";
 68.4289 -+
 68.4290 - # Turn off localization of executable's output.
 68.4291 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 68.4292 - 
 68.4293 -+# uncommented to enable multibyte paths
 68.4294 -+my $mb_locale = $ENV{LOCALE_FR_UTF8};
 68.4295 -+! defined $mb_locale || $mb_locale eq 'none'
 68.4296 -+ and $mb_locale = 'C';
 68.4297 -+
 68.4298 - my @Tests =
 68.4299 -   (
 68.4300 -    ['s1', '-w2 -s', {IN=>"a\t"}, {OUT=>"a\n\t"}],
 68.4301 -@@ -31,9 +40,48 @@ my @Tests =
 68.4302 -    ['s4', '-w4 -s', {IN=>"abc ef\n"}, {OUT=>"abc \nef\n"}],
 68.4303 -   );
 68.4304 - 
 68.4305 -+# Add _POSIX2_VERSION=199209 to the environment of each test
 68.4306 -+# that uses an old-style option like +1.
 68.4307 -+if ($mb_locale ne 'C')
 68.4308 -+  {
 68.4309 -+    # Duplicate each test vector, appending "-mb" to the test name and
 68.4310 -+    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 68.4311 -+    # provide coverage for the distro-added multi-byte code paths.
 68.4312 -+    my @new;
 68.4313 -+    foreach my $t (@Tests)
 68.4314 -+      {
 68.4315 -+        my @new_t = @$t;
 68.4316 -+        my $test_name = shift @new_t;
 68.4317 -+
 68.4318 -+        # Depending on whether fold is multi-byte-patched,
 68.4319 -+        # it emits different diagnostics:
 68.4320 -+        #   non-MB: invalid byte or field list
 68.4321 -+        #   MB:     invalid byte, character or field list
 68.4322 -+        # Adjust the expected error output accordingly.
 68.4323 -+        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 68.4324 -+            (@new_t))
 68.4325 -+          {
 68.4326 -+            my $sub = {ERR_SUBST => 's/, character//'};
 68.4327 -+            push @new_t, $sub;
 68.4328 -+            push @$t, $sub;
 68.4329 -+          }
 68.4330 -+        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 68.4331 -+      }
 68.4332 -+    push @Tests, @new;
 68.4333 -+  }
 68.4334 -+
 68.4335 -+@Tests = triple_test \@Tests;
 68.4336 -+
 68.4337 -+# Remember that triple_test creates from each test with exactly one "IN"
 68.4338 -+# file two more tests (.p and .r suffix on name) corresponding to reading
 68.4339 -+# input from a file and from a pipe.  The pipe-reading test would fail
 68.4340 -+# due to a race condition about 1 in 20 times.
 68.4341 -+# Remove the IN_PIPE version of the "output-is-input" test above.
 68.4342 -+# The others aren't susceptible because they have three inputs each.
 68.4343 -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
 68.4344 -+
 68.4345 - my $save_temps = $ENV{DEBUG};
 68.4346 - my $verbose = $ENV{VERBOSE};
 68.4347 - 
 68.4348 --my $prog = 'fold';
 68.4349 - my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose);
 68.4350 - exit $fail;
 68.4351 -diff -Naurp coreutils-8.25-orig/tests/misc/join.pl coreutils-8.25/tests/misc/join.pl
 68.4352 ---- coreutils-8.25-orig/tests/misc/join.pl	2016-01-16 12:18:13.000000000 -0600
 68.4353 -+++ coreutils-8.25/tests/misc/join.pl	2016-02-08 19:07:10.315944664 -0600
 68.4354 -@@ -25,6 +25,15 @@ my $limits = getlimits ();
 68.4355 - 
 68.4356 - my $prog = 'join';
 68.4357 - 
 68.4358 -+my $try = "Try \`$prog --help' for more information.\n";
 68.4359 -+my $inval = "$prog: invalid byte, character or field list\n$try";
 68.4360 -+
 68.4361 -+my $mb_locale;
 68.4362 -+#Comment out next line to disable multibyte tests
 68.4363 -+$mb_locale = $ENV{LOCALE_FR_UTF8};
 68.4364 -+! defined $mb_locale || $mb_locale eq 'none'
 68.4365 -+  and $mb_locale = 'C';
 68.4366 -+
 68.4367 - my $delim = chr 0247;
 68.4368 - sub t_subst ($)
 68.4369 - {
 68.4370 -@@ -329,8 +338,49 @@ foreach my $t (@tv)
 68.4371 -     push @Tests, $new_ent;
 68.4372 -   }
 68.4373 - 
 68.4374 -+# Add _POSIX2_VERSION=199209 to the environment of each test
 68.4375 -+# that uses an old-style option like +1.
 68.4376 -+if ($mb_locale ne 'C')
 68.4377 -+  {
 68.4378 -+    # Duplicate each test vector, appending "-mb" to the test name and
 68.4379 -+    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 68.4380 -+    # provide coverage for the distro-added multi-byte code paths.
 68.4381 -+    my @new;
 68.4382 -+    foreach my $t (@Tests)
 68.4383 -+      {
 68.4384 -+        my @new_t = @$t;
 68.4385 -+        my $test_name = shift @new_t;
 68.4386 -+
 68.4387 -+        # Depending on whether join is multi-byte-patched,
 68.4388 -+        # it emits different diagnostics:
 68.4389 -+        #   non-MB: invalid byte or field list
 68.4390 -+        #   MB:     invalid byte, character or field list
 68.4391 -+        # Adjust the expected error output accordingly.
 68.4392 -+        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 68.4393 -+            (@new_t))
 68.4394 -+          {
 68.4395 -+            my $sub = {ERR_SUBST => 's/, character//'};
 68.4396 -+            push @new_t, $sub;
 68.4397 -+            push @$t, $sub;
 68.4398 -+          }
 68.4399 -+        #Adjust the output some error messages including test_name for mb
 68.4400 -+        if (grep {ref $_ eq 'HASH' && exists $_->{ERR}}
 68.4401 -+             (@new_t))
 68.4402 -+          {
 68.4403 -+            my $sub2 = {ERR_SUBST => "s/$test_name-mb/$test_name/"};
 68.4404 -+            push @new_t, $sub2;
 68.4405 -+            push @$t, $sub2;
 68.4406 -+          }
 68.4407 -+        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 68.4408 -+      }
 68.4409 -+    push @Tests, @new;
 68.4410 -+  }
 68.4411 -+
 68.4412 - @Tests = triple_test \@Tests;
 68.4413 - 
 68.4414 -+#skip invalid-j-mb test, it is failing because of the format
 68.4415 -+@Tests = grep {$_->[0] ne 'invalid-j-mb'} @Tests;
 68.4416 -+
 68.4417 - my $save_temps = $ENV{DEBUG};
 68.4418 - my $verbose = $ENV{VERBOSE};
 68.4419 - 
 68.4420 -diff -Naurp coreutils-8.25-orig/tests/misc/sort-mb-tests.sh coreutils-8.25/tests/misc/sort-mb-tests.sh
 68.4421 ---- coreutils-8.25-orig/tests/misc/sort-mb-tests.sh	1969-12-31 18:00:00.000000000 -0600
 68.4422 -+++ coreutils-8.25/tests/misc/sort-mb-tests.sh	2016-02-08 19:07:10.315944664 -0600
 68.4423 -@@ -0,0 +1,45 @@
 68.4424 -+#!/bin/sh
 68.4425 -+# Verify sort's multi-byte support.
 68.4426 -+
 68.4427 -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 68.4428 -+print_ver_ sort
 68.4429 -+
 68.4430 -+export LC_ALL=en_US.UTF-8
 68.4431 -+locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \
 68.4432 -+  || skip_ "No UTF-8 locale available"
 68.4433 -+
 68.4434 -+
 68.4435 -+cat <<EOF > exp
 68.4436 -+Banana@5
 68.4437 -+Apple@10
 68.4438 -+Citrus@20
 68.4439 -+Cherry@30
 68.4440 -+EOF
 68.4441 -+
 68.4442 -+cat <<EOF | sort -t @ -k2 -n > out || fail=1
 68.4443 -+Apple@10
 68.4444 -+Banana@5
 68.4445 -+Citrus@20
 68.4446 -+Cherry@30
 68.4447 -+EOF
 68.4448 -+
 68.4449 -+compare exp out || { fail=1; cat out; }
 68.4450 -+
 68.4451 -+
 68.4452 -+cat <<EOF > exp
 68.4453 -+Citrus@AA20@@5
 68.4454 -+Cherry@AA30@@10
 68.4455 -+Apple@AA10@@20
 68.4456 -+Banana@AA5@@30
 68.4457 -+EOF
 68.4458 -+
 68.4459 -+cat <<EOF | sort -t @ -k4 -n > out || fail=1
 68.4460 -+Apple@AA10@@20
 68.4461 -+Banana@AA5@@30
 68.4462 -+Citrus@AA20@@5
 68.4463 -+Cherry@AA30@@10
 68.4464 -+EOF
 68.4465 -+
 68.4466 -+compare exp out || { fail=1; cat out; }
 68.4467 -+
 68.4468 -+Exit $fail
 68.4469 -diff -Naurp coreutils-8.25-orig/tests/misc/sort-merge.pl coreutils-8.25/tests/misc/sort-merge.pl
 68.4470 ---- coreutils-8.25-orig/tests/misc/sort-merge.pl	2016-01-16 12:18:14.000000000 -0600
 68.4471 -+++ coreutils-8.25/tests/misc/sort-merge.pl	2016-02-08 19:07:10.316944667 -0600
 68.4472 -@@ -26,6 +26,15 @@ my $prog = 'sort';
 68.4473 - # Turn off localization of executable's output.
 68.4474 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 68.4475 - 
 68.4476 -+my $mb_locale;
 68.4477 -+# uncommented according to upstream commit enabling multibyte paths
 68.4478 -+$mb_locale = $ENV{LOCALE_FR_UTF8};
 68.4479 -+! defined $mb_locale || $mb_locale eq 'none'
 68.4480 -+ and $mb_locale = 'C';
 68.4481 -+
 68.4482 -+my $try = "Try \`$prog --help' for more information.\n";
 68.4483 -+my $inval = "$prog: invalid byte, character or field list\n$try";
 68.4484 -+
 68.4485 - # three empty files and one that says 'foo'
 68.4486 - my @inputs = (+(map{{IN=> {"empty$_"=> ''}}}1..3), {IN=> {foo=> "foo\n"}});
 68.4487 - 
 68.4488 -@@ -77,6 +86,39 @@ my @Tests =
 68.4489 -         {OUT=>$big_input}],
 68.4490 -     );
 68.4491 - 
 68.4492 -+# Add _POSIX2_VERSION=199209 to the environment of each test
 68.4493 -+# that uses an old-style option like +1.
 68.4494 -+if ($mb_locale ne 'C')
 68.4495 -+  {
 68.4496 -+    # Duplicate each test vector, appending "-mb" to the test name and
 68.4497 -+    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 68.4498 -+    # provide coverage for the distro-added multi-byte code paths.
 68.4499 -+    my @new;
 68.4500 -+    foreach my $t (@Tests)
 68.4501 -+      {
 68.4502 -+        my @new_t = @$t;
 68.4503 -+        my $test_name = shift @new_t;
 68.4504 -+
 68.4505 -+        # Depending on whether sort is multi-byte-patched,
 68.4506 -+        # it emits different diagnostics:
 68.4507 -+        #   non-MB: invalid byte or field list
 68.4508 -+        #   MB:     invalid byte, character or field list
 68.4509 -+        # Adjust the expected error output accordingly.
 68.4510 -+        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 68.4511 -+            (@new_t))
 68.4512 -+          {
 68.4513 -+            my $sub = {ERR_SUBST => 's/, character//'};
 68.4514 -+            push @new_t, $sub;
 68.4515 -+            push @$t, $sub;
 68.4516 -+          }
 68.4517 -+        next if ($test_name =~ "nmerge-.");
 68.4518 -+        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 68.4519 -+      }
 68.4520 -+    push @Tests, @new;
 68.4521 -+  }
 68.4522 -+
 68.4523 -+@Tests = triple_test \@Tests;
 68.4524 -+
 68.4525 - my $save_temps = $ENV{DEBUG};
 68.4526 - my $verbose = $ENV{VERBOSE};
 68.4527 - 
 68.4528 -diff -Naurp coreutils-8.25-orig/tests/misc/sort.pl coreutils-8.25/tests/misc/sort.pl
 68.4529 ---- coreutils-8.25-orig/tests/misc/sort.pl	2016-01-16 12:18:14.000000000 -0600
 68.4530 -+++ coreutils-8.25/tests/misc/sort.pl	2016-02-08 19:07:10.316944667 -0600
 68.4531 -@@ -24,10 +24,15 @@ my $prog = 'sort';
 68.4532 - # Turn off localization of executable's output.
 68.4533 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 68.4534 - 
 68.4535 --my $mb_locale = $ENV{LOCALE_FR_UTF8};
 68.4536 -+my $mb_locale;
 68.4537 -+#Comment out next line to disable multibyte tests
 68.4538 -+$mb_locale = $ENV{LOCALE_FR_UTF8};
 68.4539 - ! defined $mb_locale || $mb_locale eq 'none'
 68.4540 -   and $mb_locale = 'C';
 68.4541 - 
 68.4542 -+my $try = "Try \`$prog --help' for more information.\n";
 68.4543 -+my $inval = "$prog: invalid byte, character or field list\n$try";
 68.4544 -+
 68.4545 - # Since each test is run with a file name and with redirected stdin,
 68.4546 - # the name in the diagnostic is either the file name or "-".
 68.4547 - # Normalize each diagnostic to use '-'.
 68.4548 -@@ -424,6 +429,38 @@ foreach my $t (@Tests)
 68.4549 -       }
 68.4550 -   }
 68.4551 - 
 68.4552 -+if ($mb_locale ne 'C')
 68.4553 -+   {
 68.4554 -+    # Duplicate each test vector, appending "-mb" to the test name and
 68.4555 -+    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 68.4556 -+    # provide coverage for the distro-added multi-byte code paths.
 68.4557 -+    my @new;
 68.4558 -+    foreach my $t (@Tests)
 68.4559 -+       {
 68.4560 -+        my @new_t = @$t;
 68.4561 -+        my $test_name = shift @new_t;
 68.4562 -+
 68.4563 -+        # Depending on whether sort is multi-byte-patched,
 68.4564 -+        # it emits different diagnostics:
 68.4565 -+        #   non-MB: invalid byte or field list
 68.4566 -+        #   MB:     invalid byte, character or field list
 68.4567 -+        # Adjust the expected error output accordingly.
 68.4568 -+        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 68.4569 -+            (@new_t))
 68.4570 -+          {
 68.4571 -+            my $sub = {ERR_SUBST => 's/, character//'};
 68.4572 -+            push @new_t, $sub;
 68.4573 -+            push @$t, $sub;
 68.4574 -+          }
 68.4575 -+        #disable several failing tests until investigation, disable all tests with envvars set
 68.4576 -+        next if (grep {ref $_ eq 'HASH' && exists $_->{ENV}} (@new_t));
 68.4577 -+        next if ($test_name =~ "18g" or $test_name =~ "sort-numeric" or $test_name =~ "08[ab]" or $test_name =~ "03[def]" or $test_name =~ "h4" or $test_name =~ "n1" or $test_name =~ "2[01]a");
 68.4578 -+        next if ($test_name =~ "11[ab]"); # avoid FP: expected result differs to MB result due to collation rules.
 68.4579 -+        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 68.4580 -+       }
 68.4581 -+    push @Tests, @new;
 68.4582 -+   }
 68.4583 -+
 68.4584 - @Tests = triple_test \@Tests;
 68.4585 - 
 68.4586 - # Remember that triple_test creates from each test with exactly one "IN"
 68.4587 -@@ -433,6 +470,7 @@ foreach my $t (@Tests)
 68.4588 - # Remove the IN_PIPE version of the "output-is-input" test above.
 68.4589 - # The others aren't susceptible because they have three inputs each.
 68.4590 - @Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
 68.4591 -+@Tests = grep {$_->[0] ne 'output-is-input-mb.p'} @Tests;
 68.4592 - 
 68.4593 - my $save_temps = $ENV{DEBUG};
 68.4594 - my $verbose = $ENV{VERBOSE};
 68.4595 -diff -Naurp coreutils-8.25-orig/tests/misc/unexpand.pl coreutils-8.25/tests/misc/unexpand.pl
 68.4596 ---- coreutils-8.25-orig/tests/misc/unexpand.pl	2016-01-16 12:18:14.000000000 -0600
 68.4597 -+++ coreutils-8.25/tests/misc/unexpand.pl	2016-02-08 19:07:10.317944671 -0600
 68.4598 -@@ -27,6 +27,14 @@ my $limits = getlimits ();
 68.4599 - 
 68.4600 - my $prog = 'unexpand';
 68.4601 - 
 68.4602 -+# comment out next line to disable multibyte tests
 68.4603 -+my $mb_locale = $ENV{LOCALE_FR_UTF8};
 68.4604 -+! defined $mb_locale || $mb_locale eq 'none'
 68.4605 -+ and $mb_locale = 'C';
 68.4606 -+
 68.4607 -+my $try = "Try \`$prog --help' for more information.\n";
 68.4608 -+my $inval = "$prog: invalid byte, character or field list\n$try";
 68.4609 -+
 68.4610 - my @Tests =
 68.4611 -     (
 68.4612 -      ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}],
 68.4613 -@@ -92,6 +100,37 @@ my @Tests =
 68.4614 -       {EXIT => 1}, {ERR => "$prog: tab stop value is too large\n"}],
 68.4615 -     );
 68.4616 - 
 68.4617 -+if ($mb_locale ne 'C')
 68.4618 -+  {
 68.4619 -+    # Duplicate each test vector, appending "-mb" to the test name and
 68.4620 -+    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 68.4621 -+    # provide coverage for the distro-added multi-byte code paths.
 68.4622 -+    my @new;
 68.4623 -+    foreach my $t (@Tests)
 68.4624 -+      {
 68.4625 -+        my @new_t = @$t;
 68.4626 -+        my $test_name = shift @new_t;
 68.4627 -+
 68.4628 -+        # Depending on whether unexpand is multi-byte-patched,
 68.4629 -+        # it emits different diagnostics:
 68.4630 -+        #   non-MB: invalid byte or field list
 68.4631 -+        #   MB:     invalid byte, character or field list
 68.4632 -+        # Adjust the expected error output accordingly.
 68.4633 -+        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 68.4634 -+            (@new_t))
 68.4635 -+          {
 68.4636 -+            my $sub = {ERR_SUBST => 's/, character//'};
 68.4637 -+            push @new_t, $sub;
 68.4638 -+            push @$t, $sub;
 68.4639 -+          }
 68.4640 -+        next if ($test_name =~ 'b-1');
 68.4641 -+        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 68.4642 -+      }
 68.4643 -+    push @Tests, @new;
 68.4644 -+  }
 68.4645 -+
 68.4646 -+@Tests = triple_test \@Tests;
 68.4647 -+
 68.4648 - my $save_temps = $ENV{DEBUG};
 68.4649 - my $verbose = $ENV{VERBOSE};
 68.4650 - 
 68.4651 -diff -Naurp coreutils-8.25-orig/tests/misc/uniq.pl coreutils-8.25/tests/misc/uniq.pl
 68.4652 ---- coreutils-8.25-orig/tests/misc/uniq.pl	2016-01-16 12:18:14.000000000 -0600
 68.4653 -+++ coreutils-8.25/tests/misc/uniq.pl	2016-02-08 19:07:10.317944671 -0600
 68.4654 -@@ -23,9 +23,17 @@ my $limits = getlimits ();
 68.4655 - my $prog = 'uniq';
 68.4656 - my $try = "Try '$prog --help' for more information.\n";
 68.4657 - 
 68.4658 -+my $inval = "$prog: invalid byte, character or field list\n$try";
 68.4659 -+
 68.4660 - # Turn off localization of executable's output.
 68.4661 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 68.4662 - 
 68.4663 -+my $mb_locale;
 68.4664 -+#Comment out next line to disable multibyte tests
 68.4665 -+$mb_locale = $ENV{LOCALE_FR_UTF8};
 68.4666 -+! defined $mb_locale || $mb_locale eq 'none'
 68.4667 -+  and $mb_locale = 'C';
 68.4668 -+
 68.4669 - # When possible, create a "-z"-testing variant of each test.
 68.4670 - sub add_z_variants($)
 68.4671 - {
 68.4672 -@@ -262,6 +270,53 @@ foreach my $t (@Tests)
 68.4673 -       and push @$t, {ENV=>'_POSIX2_VERSION=199209'};
 68.4674 -   }
 68.4675 - 
 68.4676 -+if ($mb_locale ne 'C')
 68.4677 -+  {
 68.4678 -+    # Duplicate each test vector, appending "-mb" to the test name and
 68.4679 -+    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 68.4680 -+    # provide coverage for the distro-added multi-byte code paths.
 68.4681 -+    my @new;
 68.4682 -+    foreach my $t (@Tests)
 68.4683 -+      {
 68.4684 -+        my @new_t = @$t;
 68.4685 -+        my $test_name = shift @new_t;
 68.4686 -+
 68.4687 -+        # Depending on whether uniq is multi-byte-patched,
 68.4688 -+        # it emits different diagnostics:
 68.4689 -+        #   non-MB: invalid byte or field list
 68.4690 -+        #   MB:     invalid byte, character or field list
 68.4691 -+        # Adjust the expected error output accordingly.
 68.4692 -+        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 68.4693 -+            (@new_t))
 68.4694 -+          {
 68.4695 -+            my $sub = {ERR_SUBST => 's/, character//'};
 68.4696 -+            push @new_t, $sub;
 68.4697 -+            push @$t, $sub;
 68.4698 -+          }
 68.4699 -+        # In test #145, replace the each ‘...’ by '...'.
 68.4700 -+        if ($test_name =~ "145")
 68.4701 -+          {
 68.4702 -+            my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"};
 68.4703 -+            push @new_t, $sub;
 68.4704 -+            push @$t, $sub;
 68.4705 -+          }
 68.4706 -+        next if (   $test_name =~ "schar"
 68.4707 -+                 or $test_name =~ "^obs-plus"
 68.4708 -+                 or $test_name =~ "119");
 68.4709 -+        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 68.4710 -+      }
 68.4711 -+    push @Tests, @new;
 68.4712 -+   }
 68.4713 -+
 68.4714 -+# Remember that triple_test creates from each test with exactly one "IN"
 68.4715 -+# file two more tests (.p and .r suffix on name) corresponding to reading
 68.4716 -+# input from a file and from a pipe.  The pipe-reading test would fail
 68.4717 -+# due to a race condition about 1 in 20 times.
 68.4718 -+# Remove the IN_PIPE version of the "output-is-input" test above.
 68.4719 -+# The others aren't susceptible because they have three inputs each.
 68.4720 -+
 68.4721 -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
 68.4722 -+
 68.4723 - @Tests = add_z_variants \@Tests;
 68.4724 - @Tests = triple_test \@Tests;
 68.4725 - 
 68.4726 -diff -Naurp coreutils-8.25-orig/tests/pr/pr-tests.pl coreutils-8.25/tests/pr/pr-tests.pl
 68.4727 ---- coreutils-8.25-orig/tests/pr/pr-tests.pl	2016-01-16 12:18:14.000000000 -0600
 68.4728 -+++ coreutils-8.25/tests/pr/pr-tests.pl	2016-02-08 19:07:10.318944674 -0600
 68.4729 -@@ -24,6 +24,15 @@ use strict;
 68.4730 - my $prog = 'pr';
 68.4731 - my $normalize_strerror = "s/': .*/'/";
 68.4732 - 
 68.4733 -+my $mb_locale;
 68.4734 -+#Uncomment the following line to enable multibyte tests
 68.4735 -+$mb_locale = $ENV{LOCALE_FR_UTF8};
 68.4736 -+! defined $mb_locale || $mb_locale eq 'none'
 68.4737 -+  and $mb_locale = 'C';
 68.4738 -+
 68.4739 -+my $try = "Try \`$prog --help' for more information.\n";
 68.4740 -+my $inval = "$prog: invalid byte, character or field list\n$try";
 68.4741 -+
 68.4742 - my @tv = (
 68.4743 - 
 68.4744 - # -b option is no longer an official option. But it's still working to
 68.4745 -@@ -467,8 +476,48 @@ push @Tests,
 68.4746 -     {IN=>{3=>"x\ty\tz\n"}},
 68.4747 -      {OUT=>join("\t", qw(a b c m n o x y z)) . "\n"} ];
 68.4748 - 
 68.4749 -+# Add _POSIX2_VERSION=199209 to the environment of each test
 68.4750 -+# that uses an old-style option like +1.
 68.4751 -+if ($mb_locale ne 'C')
 68.4752 -+  {
 68.4753 -+    # Duplicate each test vector, appending "-mb" to the test name and
 68.4754 -+    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 68.4755 -+    # provide coverage for the distro-added multi-byte code paths.
 68.4756 -+    my @new;
 68.4757 -+    foreach my $t (@Tests)
 68.4758 -+      {
 68.4759 -+        my @new_t = @$t;
 68.4760 -+        my $test_name = shift @new_t;
 68.4761 -+
 68.4762 -+        # Depending on whether pr is multi-byte-patched,
 68.4763 -+        # it emits different diagnostics:
 68.4764 -+        #   non-MB: invalid byte or field list
 68.4765 -+        #   MB:     invalid byte, character or field list
 68.4766 -+        # Adjust the expected error output accordingly.
 68.4767 -+        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 68.4768 -+            (@new_t))
 68.4769 -+          {
 68.4770 -+            my $sub = {ERR_SUBST => 's/, character//'};
 68.4771 -+            push @new_t, $sub;
 68.4772 -+            push @$t, $sub;
 68.4773 -+          }
 68.4774 -+        #temporarily skip some failing tests
 68.4775 -+        next if ($test_name =~ "col-0" or $test_name =~ "col-inval");
 68.4776 -+        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 68.4777 -+      }
 68.4778 -+    push @Tests, @new;
 68.4779 -+  }
 68.4780 -+
 68.4781 - @Tests = triple_test \@Tests;
 68.4782 - 
 68.4783 -+# Remember that triple_test creates from each test with exactly one "IN"
 68.4784 -+# file two more tests (.p and .r suffix on name) corresponding to reading
 68.4785 -+# input from a file and from a pipe.  The pipe-reading test would fail
 68.4786 -+# due to a race condition about 1 in 20 times.
 68.4787 -+# Remove the IN_PIPE version of the "output-is-input" test above.
 68.4788 -+# The others aren't susceptible because they have three inputs each.
 68.4789 -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
 68.4790 -+
 68.4791 - my $save_temps = $ENV{DEBUG};
 68.4792 - my $verbose = $ENV{VERBOSE};
 68.4793 - 
    69.1 --- a/coreutils/stuff/coreutils-fix-po.patch	Sat May 27 16:29:45 2017 +0300
    69.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.3 @@ -1,84 +0,0 @@
    69.4 ---- a/po/nb.po
    69.5 -+++ b/po/nb.po
    69.6 -@@ -2721,7 +2721,7 @@
    69.7 - "A line OFFSET is a required '+' or '-' followed by a positive integer.\n"
    69.8 - msgstr ""
    69.9 - "\n"
   69.10 --"\vMØNSTER må utformes slik:\n"
   69.11 -+"MØNSTER må utformes slik:\n"
   69.12 - "  INTEGER            kopier frem til - men ikke inkludert - angitt "
   69.13 - "linjenummer\n"
   69.14 - "  /REGEXP/[OFFSET]   kopier frem til - men ikke inkludert - en samsvarende "
   69.15 -@@ -7132,7 +7132,7 @@
   69.16 - "Multiple fields/ranges can be separated with commas\n"
   69.17 - msgstr ""
   69.18 - "\n"
   69.19 --"\vFELT støtter feltrekkevidder i cut(1)-stil:\n"
   69.20 -+"FELT støtter feltrekkevidder i cut(1)-stil:\n"
   69.21 - "  N    N'te byte, tegn eller felt, talt fra 1\n"
   69.22 - "  N-   fra N'te byte, tegn eller felt, til slutten av linja\n"
   69.23 - "  N-M  fra N'te til M'te (inklusive) byte, tegn eller felt\n"
   69.24 ---- a/po/sl.po
   69.25 -+++ b/po/sl.po
   69.26 -@@ -2641,7 +2641,7 @@
   69.27 - #: src/csplit.c:1299
   69.28 - #, c-format
   69.29 - msgid "invalid conversion specifier in suffix: \\%.3o"
   69.30 --msgstr "neveljavno določilo pretvorbe v priponi: \\\\%.3o"
   69.31 -+msgstr "neveljavno določilo pretvorbe v priponi: \\%.3o"
   69.32 - 
   69.33 - #: src/csplit.c:1304
   69.34 - #, c-format
   69.35 -@@ -6711,7 +6711,7 @@
   69.36 - "ločitvena\n"
   69.37 - "znaka za ločevanje logičnih strani; če je drugi znak izpuščen, se "
   69.38 - "privzame :.\n"
   69.39 --"Uporabite \\\\\\\\ za \\\\. SLOG je nekaj od naštetega:\n"
   69.40 -+"Uporabite \\\\ za \\. SLOG je nekaj od naštetega:\n"
   69.41 - 
   69.42 - #: src/nl.c:211
   69.43 - msgid ""
   69.44 -@@ -7951,8 +7951,8 @@
   69.45 - msgstr ""
   69.46 - "  -h, --header=ZGLAVJE\n"
   69.47 - "                    uporabimo navedeno osredinjeno ZGLAVJE namesto imena\n"
   69.48 --"                    datoteke; -h \\\"\\\" izpiše prazno vrstica; ne "
   69.49 --"uporabljajte -h\\\"\\\"\n"
   69.50 -+"                    datoteke; -h \"\" izpiše prazno vrstica; ne "
   69.51 -+"uporabljajte -h\"\"\n"
   69.52 - "  -i[ZNAK[ŠIRINA]], --output-tabs[=ZNAK[ŠIRINA]]\n"
   69.53 - "                    presledke skrčimo v ZNAK (privzeto TAB) do ŠIRINE\n"
   69.54 - "                    tabulatorja (privzeto 8)\n"
   69.55 -@@ -12078,15 +12078,15 @@
   69.56 - "MNOŽICE določajo nizi znakov. Večinoma predstavljajo sebe, posebej pa se\n"
   69.57 - "tolmačijo naslednja zaporedja:\n"
   69.58 - "\n"
   69.59 --"  \\\\NNN            znak z osmiško kodo NNN (dolžina 1, 2 ali 3 osmiške "
   69.60 -+"  \\NNN            znak z osmiško kodo NNN (dolžina 1, 2 ali 3 osmiške "
   69.61 - "števke)\n"
   69.62 --"  \\\\\\\\             obratna poševnica\n"
   69.63 --"  \\\\a              zvonček\n"
   69.64 --"  \\\\b              pomik za en znak v levo\n"
   69.65 --"  \\\\f              skok na novo stran\n"
   69.66 --"  \\\\n              skok v novo vrstico\n"
   69.67 --"  \\\\r              pomik na levi rob\n"
   69.68 --"  \\\\t              vodoravni tabulator\n"
   69.69 -+"  \\\\             obratna poševnica\n"
   69.70 -+"  \\a              zvonček\n"
   69.71 -+"  \\b              pomik za en znak v levo\n"
   69.72 -+"  \\f              skok na novo stran\n"
   69.73 -+"  \\n              skok v novo vrstico\n"
   69.74 -+"  \\r              pomik na levi rob\n"
   69.75 -+"  \\t              vodoravni tabulator\n"
   69.76 - 
   69.77 - #: src/tr.c:317
   69.78 - msgid ""
   69.79 -@@ -12100,7 +12100,7 @@
   69.80 - "  [:cntrl:]       all control characters\n"
   69.81 - "  [:digit:]       all digits\n"
   69.82 - msgstr ""
   69.83 --"  \\\\v              navpični tabulator\n"
   69.84 -+"  \\v              navpični tabulator\n"
   69.85 - "  ZNAK1-ZNAK2     naraščajoče zaporedje znakov od ZNAKA1 do ZNAKA2\n"
   69.86 - "  [ZNAK1-ZNAK2]   isto kot ZNAK1-ZNAK2, če to uporabljata obe množici\n"
   69.87 - "  [ZNAK*]         v MNOŽICI 2; toliko ponovitev ZNAKA kot v MNOŽICI 1\n"
    70.1 --- a/coreutils/stuff/ls.u	Sat May 27 16:29:45 2017 +0300
    70.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.3 @@ -1,10 +0,0 @@
    70.4 ---- coreutils-7.4/src/ls.c
    70.5 -+++ coreutils-7.4/src/ls.c
    70.6 -@@ -63,6 +63,7 @@
    70.7 - #include <grp.h>
    70.8 - #include <pwd.h>
    70.9 - #include <getopt.h>
   70.10 -+#include <asm/types.h>
   70.11 - #include <signal.h>
   70.12 - #include <selinux/selinux.h>
   70.13 - #include <wchar.h>
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/coreutils/stuff/patches/README	Sat May 27 16:55:17 2017 +0300
    71.3 @@ -0,0 +1,3 @@
    71.4 +coreutils-8.25-i18n-2.patch: LFS: Coreutils Internationalization Fixes Patch
    71.5 +uname.u: SliTaz: show extended info touching CPU via uname
    71.6 +coreutils-fix-po.patch: SliTaz: fix translations, especially deprecated symbol '\v'
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/coreutils/stuff/patches/coreutils-8.25-i18n-2.patch	Sat May 27 16:55:17 2017 +0300
    72.3 @@ -0,0 +1,4790 @@
    72.4 +Submitted by:            DJ Lucas (dj_AT_linuxfromscratch_DOT_org)
    72.5 +Date:                    2016-02-09
    72.6 +Initial Package Version: 8.25
    72.7 +Upstream Status:         Rejected
    72.8 +Origin:                  Based on Suse's i18n patches at https://build.opensuse.org/package/view_file/Base:System/coreutils/coreutils-i18n.patch
    72.9 +Description:             Fixes several i18n issues with various Coreutils programs
   72.10 +
   72.11 +diff -Naurp coreutils-8.25-orig/lib/linebuffer.h coreutils-8.25/lib/linebuffer.h
   72.12 +--- coreutils-8.25-orig/lib/linebuffer.h	2016-01-01 07:45:55.000000000 -0600
   72.13 ++++ coreutils-8.25/lib/linebuffer.h	2016-02-08 19:07:10.298944609 -0600
   72.14 +@@ -21,6 +21,11 @@
   72.15 + 
   72.16 + # include <stdio.h>
   72.17 + 
   72.18 ++/* Get mbstate_t.  */
   72.19 ++# if HAVE_WCHAR_H
   72.20 ++#  include <wchar.h>
   72.21 ++# endif
   72.22 ++
   72.23 + /* A 'struct linebuffer' holds a line of text. */
   72.24 + 
   72.25 + struct linebuffer
   72.26 +@@ -28,6 +33,9 @@ struct linebuffer
   72.27 +   size_t size;                  /* Allocated. */
   72.28 +   size_t length;                /* Used. */
   72.29 +   char *buffer;
   72.30 ++# if HAVE_WCHAR_H
   72.31 ++  mbstate_t state;
   72.32 ++# endif
   72.33 + };
   72.34 + 
   72.35 + /* Initialize linebuffer LINEBUFFER for use. */
   72.36 +diff -Naurp coreutils-8.25-orig/src/cut.c coreutils-8.25/src/cut.c
   72.37 +--- coreutils-8.25-orig/src/cut.c	2016-01-13 05:08:59.000000000 -0600
   72.38 ++++ coreutils-8.25/src/cut.c	2016-02-08 19:07:10.300944616 -0600
   72.39 +@@ -28,6 +28,11 @@
   72.40 + #include <assert.h>
   72.41 + #include <getopt.h>
   72.42 + #include <sys/types.h>
   72.43 ++
   72.44 ++/* Get mbstate_t, mbrtowc().  */
   72.45 ++#if HAVE_WCHAR_H
   72.46 ++# include <wchar.h>
   72.47 ++#endif
   72.48 + #include "system.h"
   72.49 + 
   72.50 + #include "error.h"
   72.51 +@@ -38,6 +43,18 @@
   72.52 + 
   72.53 + #include "set-fields.h"
   72.54 + 
   72.55 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
   72.56 ++   installation; work around this configuration error.        */
   72.57 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
   72.58 ++# undef MB_LEN_MAX
   72.59 ++# define MB_LEN_MAX 16
   72.60 ++#endif
   72.61 ++
   72.62 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
   72.63 ++#if HAVE_MBRTOWC && defined mbstate_t
   72.64 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
   72.65 ++#endif
   72.66 ++
   72.67 + /* The official name of this program (e.g., no 'g' prefix).  */
   72.68 + #define PROGRAM_NAME "cut"
   72.69 + 
   72.70 +@@ -54,6 +71,52 @@
   72.71 +     }									\
   72.72 +   while (0)
   72.73 + 
   72.74 ++/* Refill the buffer BUF to get a multibyte character. */
   72.75 ++#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM)                        \
   72.76 ++  do                                                                        \
   72.77 ++    {                                                                        \
   72.78 ++      if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM))        \
   72.79 ++        {                                                                \
   72.80 ++          memmove (BUF, BUFPOS, BUFLEN);                                \
   72.81 ++          BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \
   72.82 ++          BUFPOS = BUF;                                                        \
   72.83 ++        }                                                                \
   72.84 ++    }                                                                        \
   72.85 ++  while (0)
   72.86 ++
   72.87 ++/* Get wide character on BUFPOS. BUFPOS is not included after that.
   72.88 ++   If byte sequence is not valid as a character, CONVFAIL is true. Otherwise false. */
   72.89 ++#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \
   72.90 ++  do                                                                        \
   72.91 ++    {                                                                        \
   72.92 ++      mbstate_t state_bak;                                                \
   72.93 ++                                                                        \
   72.94 ++      if (BUFLEN < 1)                                                        \
   72.95 ++        {                                                                \
   72.96 ++          WC = WEOF;                                                        \
   72.97 ++          break;                                                        \
   72.98 ++        }                                                                \
   72.99 ++                                                                        \
  72.100 ++      /* Get a wide character. */                                        \
  72.101 ++      CONVFAIL = false;                                                        \
  72.102 ++      state_bak = STATE;                                                \
  72.103 ++      MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE);        \
  72.104 ++                                                                        \
  72.105 ++      switch (MBLENGTH)                                                        \
  72.106 ++        {                                                                \
  72.107 ++        case (size_t)-1:                                                \
  72.108 ++        case (size_t)-2:                                                \
  72.109 ++          CONVFAIL = true;                                                        \
  72.110 ++          STATE = state_bak;                                                \
  72.111 ++          /* Fall througn. */                                                \
  72.112 ++                                                                        \
  72.113 ++        case 0:                                                                \
  72.114 ++          MBLENGTH = 1;                                                        \
  72.115 ++          break;                                                        \
  72.116 ++        }                                                                \
  72.117 ++    }                                                                        \
  72.118 ++  while (0)
  72.119 ++
  72.120 + 
  72.121 + /* Pointer inside RP.  When checking if a byte or field is selected
  72.122 +    by a finite range, we check if it is between CURRENT_RP.LO
  72.123 +@@ -61,6 +124,9 @@
  72.124 +    CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */
  72.125 + static struct field_range_pair *current_rp;
  72.126 + 
  72.127 ++/* Length of the delimiter given as argument to -d.  */
  72.128 ++size_t delimlen;
  72.129 ++
  72.130 + /* This buffer is used to support the semantics of the -s option
  72.131 +    (or lack of same) when the specified field list includes (does
  72.132 +    not include) the first field.  In both of those cases, the entire
  72.133 +@@ -77,15 +143,25 @@ enum operating_mode
  72.134 +   {
  72.135 +     undefined_mode,
  72.136 + 
  72.137 +-    /* Output characters that are in the given bytes. */
  72.138 ++    /* Output bytes that are at the given positions. */
  72.139 +     byte_mode,
  72.140 + 
  72.141 ++    /* Output characters that are at the given positions. */
  72.142 ++    character_mode,
  72.143 ++
  72.144 +     /* Output the given delimiter-separated fields. */
  72.145 +     field_mode
  72.146 +   };
  72.147 + 
  72.148 + static enum operating_mode operating_mode;
  72.149 + 
  72.150 ++/* If nonzero, when in byte mode, don't split multibyte characters.  */
  72.151 ++static int byte_mode_character_aware;
  72.152 ++
  72.153 ++/* If nonzero, the function for single byte locale is work
  72.154 ++   if this program runs on multibyte locale. */
  72.155 ++static int force_singlebyte_mode;
  72.156 ++
  72.157 + /* If true do not output lines containing no delimiter characters.
  72.158 +    Otherwise, all such lines are printed.  This option is valid only
  72.159 +    with field mode.  */
  72.160 +@@ -97,6 +173,9 @@ static bool complement;
  72.161 + 
  72.162 + /* The delimiter character for field mode. */
  72.163 + static unsigned char delim;
  72.164 ++#if HAVE_WCHAR_H
  72.165 ++static wchar_t wcdelim;
  72.166 ++#endif
  72.167 + 
  72.168 + /* The delimiter for each line/record. */
  72.169 + static unsigned char line_delim = '\n';
  72.170 +@@ -164,7 +243,7 @@ Print selected parts of lines from each
  72.171 +   -f, --fields=LIST       select only these fields;  also print any line\n\
  72.172 +                             that contains no delimiter character, unless\n\
  72.173 +                             the -s option is specified\n\
  72.174 +-  -n                      (ignored)\n\
  72.175 ++  -n                      with -b: don't split multibyte characters\n\
  72.176 + "), stdout);
  72.177 +       fputs (_("\
  72.178 +       --complement        complement the set of selected bytes, characters\n\
  72.179 +@@ -280,6 +359,82 @@ cut_bytes (FILE *stream)
  72.180 +     }
  72.181 + }
  72.182 + 
  72.183 ++#if HAVE_MBRTOWC
  72.184 ++/* This function is in use for the following case.
  72.185 ++
  72.186 ++   1. Read from the stream STREAM, printing to standard output any selected
  72.187 ++   characters.
  72.188 ++
  72.189 ++   2. Read from stream STREAM, printing to standard output any selected bytes,
  72.190 ++   without splitting multibyte characters.  */
  72.191 ++
  72.192 ++static void
  72.193 ++cut_characters_or_cut_bytes_no_split (FILE *stream)
  72.194 ++{
  72.195 ++  size_t idx;                /* number of bytes or characters in the line so far. */
  72.196 ++  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
  72.197 ++  char *bufpos;                /* Next read position of BUF. */
  72.198 ++  size_t buflen;        /* The length of the byte sequence in buf. */
  72.199 ++  wint_t wc;                /* A gotten wide character. */
  72.200 ++  size_t mblength;        /* The byte size of a multibyte character which shows
  72.201 ++                           as same character as WC. */
  72.202 ++  mbstate_t state;        /* State of the stream. */
  72.203 ++  bool convfail = false;  /* true, when conversion failed. Otherwise false. */
  72.204 ++  /* Whether to begin printing delimiters between ranges for the current line.
  72.205 ++     Set after we've begun printing data corresponding to the first range.  */
  72.206 ++  bool print_delimiter = false;
  72.207 ++
  72.208 ++  idx = 0;
  72.209 ++  buflen = 0;
  72.210 ++  bufpos = buf;
  72.211 ++  memset (&state, '\0', sizeof(mbstate_t));
  72.212 ++
  72.213 ++  current_rp = frp;
  72.214 ++
  72.215 ++  while (1)
  72.216 ++    {
  72.217 ++      REFILL_BUFFER (buf, bufpos, buflen, stream);
  72.218 ++
  72.219 ++      GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail);
  72.220 ++      (void) convfail;  /* ignore unused */
  72.221 ++
  72.222 ++      if (wc == WEOF)
  72.223 ++        {
  72.224 ++          if (idx > 0)
  72.225 ++            putchar (line_delim);
  72.226 ++          break;
  72.227 ++        }
  72.228 ++      else if (wc == line_delim)
  72.229 ++        {
  72.230 ++          putchar (line_delim);
  72.231 ++          idx = 0;
  72.232 ++          print_delimiter = false;
  72.233 ++          current_rp = frp;
  72.234 ++        }
  72.235 ++      else
  72.236 ++        {
  72.237 ++          next_item (&idx);
  72.238 ++          if (print_kth (idx))
  72.239 ++            {
  72.240 ++              if (output_delimiter_specified)
  72.241 ++                {
  72.242 ++                  if (print_delimiter && is_range_start_index (idx))
  72.243 ++                    {
  72.244 ++                      fwrite (output_delimiter_string, sizeof (char),
  72.245 ++                              output_delimiter_length, stdout);
  72.246 ++                    }
  72.247 ++                  print_delimiter = true;
  72.248 ++                }
  72.249 ++              fwrite (bufpos, mblength, sizeof(char), stdout);
  72.250 ++            }
  72.251 ++        }
  72.252 ++
  72.253 ++      buflen -= mblength;
  72.254 ++      bufpos += mblength;
  72.255 ++    }
  72.256 ++}
  72.257 ++#endif
  72.258 ++
  72.259 + /* Read from stream STREAM, printing to standard output any selected fields.  */
  72.260 + 
  72.261 + static void
  72.262 +@@ -425,13 +580,211 @@ cut_fields (FILE *stream)
  72.263 +     }
  72.264 + }
  72.265 + 
  72.266 ++#if HAVE_MBRTOWC
  72.267 ++static void
  72.268 ++cut_fields_mb (FILE *stream)
  72.269 ++{
  72.270 ++  int c;
  72.271 ++  size_t field_idx;
  72.272 ++  int found_any_selected_field;
  72.273 ++  int buffer_first_field;
  72.274 ++  int empty_input;
  72.275 ++  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
  72.276 ++  char *bufpos;                /* Next read position of BUF. */
  72.277 ++  size_t buflen;        /* The length of the byte sequence in buf. */
  72.278 ++  wint_t wc = 0;        /* A gotten wide character. */
  72.279 ++  size_t mblength;        /* The byte size of a multibyte character which shows
  72.280 ++                           as same character as WC. */
  72.281 ++  mbstate_t state;        /* State of the stream. */
  72.282 ++  bool convfail = false;  /* true, when conversion failed. Otherwise false. */
  72.283 ++
  72.284 ++  current_rp = frp;
  72.285 ++
  72.286 ++  found_any_selected_field = 0;
  72.287 ++  field_idx = 1;
  72.288 ++  bufpos = buf;
  72.289 ++  buflen = 0;
  72.290 ++  memset (&state, '\0', sizeof(mbstate_t));
  72.291 ++
  72.292 ++  c = getc (stream);
  72.293 ++  empty_input = (c == EOF);
  72.294 ++  if (c != EOF)
  72.295 ++  {
  72.296 ++    ungetc (c, stream);
  72.297 ++    wc = 0;
  72.298 ++  }
  72.299 ++  else
  72.300 ++    wc = WEOF;
  72.301 ++
  72.302 ++  /* To support the semantics of the -s flag, we may have to buffer
  72.303 ++     all of the first field to determine whether it is `delimited.'
  72.304 ++     But that is unnecessary if all non-delimited lines must be printed
  72.305 ++     and the first field has been selected, or if non-delimited lines
  72.306 ++     must be suppressed and the first field has *not* been selected.
  72.307 ++     That is because a non-delimited line has exactly one field.  */
  72.308 ++  buffer_first_field = (suppress_non_delimited ^ !print_kth (1));
  72.309 ++
  72.310 ++  while (1)
  72.311 ++    {
  72.312 ++      if (field_idx == 1 && buffer_first_field)
  72.313 ++        {
  72.314 ++          int len = 0;
  72.315 ++
  72.316 ++          while (1)
  72.317 ++            {
  72.318 ++              REFILL_BUFFER (buf, bufpos, buflen, stream);
  72.319 ++
  72.320 ++              GET_NEXT_WC_FROM_BUFFER
  72.321 ++                (wc, bufpos, buflen, mblength, state, convfail);
  72.322 ++
  72.323 ++              if (wc == WEOF)
  72.324 ++                break;
  72.325 ++
  72.326 ++              field_1_buffer = xrealloc (field_1_buffer, len + mblength);
  72.327 ++              memcpy (field_1_buffer + len, bufpos, mblength);
  72.328 ++              len += mblength;
  72.329 ++              buflen -= mblength;
  72.330 ++              bufpos += mblength;
  72.331 ++
  72.332 ++              if (!convfail && (wc == line_delim || wc == wcdelim))
  72.333 ++                break;
  72.334 ++            }
  72.335 ++
  72.336 ++          if (len <= 0 && wc == WEOF)
  72.337 ++            break;
  72.338 ++
  72.339 ++          /* If the first field extends to the end of line (it is not
  72.340 ++             delimited) and we are printing all non-delimited lines,
  72.341 ++             print this one.  */
  72.342 ++          if (convfail || (!convfail && wc != wcdelim))
  72.343 ++            {
  72.344 ++              if (suppress_non_delimited)
  72.345 ++                {
  72.346 ++                  /* Empty.        */
  72.347 ++                }
  72.348 ++              else
  72.349 ++                {
  72.350 ++                  fwrite (field_1_buffer, sizeof (char), len, stdout);
  72.351 ++                  /* Make sure the output line is newline terminated.  */
  72.352 ++                  if (convfail || (!convfail && wc != line_delim))
  72.353 ++                    putchar (line_delim);
  72.354 ++                }
  72.355 ++              continue;
  72.356 ++            }
  72.357 ++
  72.358 ++          if (print_kth (1))
  72.359 ++            {
  72.360 ++              /* Print the field, but not the trailing delimiter.  */
  72.361 ++              fwrite (field_1_buffer, sizeof (char), len - 1, stdout);
  72.362 ++              found_any_selected_field = 1;
  72.363 ++            }
  72.364 ++          next_item (&field_idx);
  72.365 ++        }
  72.366 ++
  72.367 ++      if (wc != WEOF)
  72.368 ++        {
  72.369 ++          if (print_kth (field_idx))
  72.370 ++            {
  72.371 ++              if (found_any_selected_field)
  72.372 ++                {
  72.373 ++                  fwrite (output_delimiter_string, sizeof (char),
  72.374 ++                          output_delimiter_length, stdout);
  72.375 ++                }
  72.376 ++              found_any_selected_field = 1;
  72.377 ++            }
  72.378 ++
  72.379 ++          while (1)
  72.380 ++            {
  72.381 ++              REFILL_BUFFER (buf, bufpos, buflen, stream);
  72.382 ++
  72.383 ++              GET_NEXT_WC_FROM_BUFFER
  72.384 ++                (wc, bufpos, buflen, mblength, state, convfail);
  72.385 ++
  72.386 ++              if (wc == WEOF)
  72.387 ++                break;
  72.388 ++              else if (!convfail && (wc == wcdelim || wc == line_delim))
  72.389 ++                {
  72.390 ++                  buflen -= mblength;
  72.391 ++                  bufpos += mblength;
  72.392 ++                  break;
  72.393 ++                }
  72.394 ++
  72.395 ++              if (print_kth (field_idx))
  72.396 ++                fwrite (bufpos, mblength, sizeof(char), stdout);
  72.397 ++
  72.398 ++              buflen -= mblength;
  72.399 ++              bufpos += mblength;
  72.400 ++            }
  72.401 ++        }
  72.402 ++
  72.403 ++      if ((!convfail || wc == line_delim) && buflen < 1)
  72.404 ++        wc = WEOF;
  72.405 ++
  72.406 ++      if (!convfail && wc == wcdelim)
  72.407 ++        next_item (&field_idx);
  72.408 ++      else if (wc == WEOF || (!convfail && wc == line_delim))
  72.409 ++        {
  72.410 ++          if (found_any_selected_field
  72.411 ++              || (!empty_input && !(suppress_non_delimited && field_idx == 1)))
  72.412 ++            putchar (line_delim);
  72.413 ++          if (wc == WEOF)
  72.414 ++            break;
  72.415 ++          field_idx = 1;
  72.416 ++          current_rp = frp;
  72.417 ++          found_any_selected_field = 0;
  72.418 ++        }
  72.419 ++    }
  72.420 ++}
  72.421 ++#endif
  72.422 ++
  72.423 + static void
  72.424 + cut_stream (FILE *stream)
  72.425 + {
  72.426 +-  if (operating_mode == byte_mode)
  72.427 +-    cut_bytes (stream);
  72.428 ++#if HAVE_MBRTOWC
  72.429 ++  if (MB_CUR_MAX > 1 && !force_singlebyte_mode)
  72.430 ++    {
  72.431 ++      switch (operating_mode)
  72.432 ++        {
  72.433 ++        case byte_mode:
  72.434 ++          if (byte_mode_character_aware)
  72.435 ++            cut_characters_or_cut_bytes_no_split (stream);
  72.436 ++          else
  72.437 ++            cut_bytes (stream);
  72.438 ++          break;
  72.439 ++
  72.440 ++        case character_mode:
  72.441 ++          cut_characters_or_cut_bytes_no_split (stream);
  72.442 ++          break;
  72.443 ++
  72.444 ++        case field_mode:
  72.445 ++          if (delimlen == 1)
  72.446 ++            {
  72.447 ++              /* Check if we have utf8 multibyte locale, so we can use this
  72.448 ++                 optimization because of uniqueness of characters, which is
  72.449 ++                 not true for e.g. SJIS */
  72.450 ++              char * loc = setlocale(LC_CTYPE, NULL);
  72.451 ++              if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") ||
  72.452 ++                  strstr (loc, "UTF8") || strstr (loc, "utf8")))
  72.453 ++                {
  72.454 ++                  cut_fields (stream);
  72.455 ++                  break;
  72.456 ++                }
  72.457 ++            }
  72.458 ++          cut_fields_mb (stream);
  72.459 ++          break;
  72.460 ++
  72.461 ++        default:
  72.462 ++          abort ();
  72.463 ++        }
  72.464 ++    }
  72.465 +   else
  72.466 +-    cut_fields (stream);
  72.467 ++#endif
  72.468 ++    {
  72.469 ++      if (operating_mode == field_mode)
  72.470 ++        cut_fields (stream);
  72.471 ++      else
  72.472 ++        cut_bytes (stream);
  72.473 ++    }
  72.474 + }
  72.475 + 
  72.476 + /* Process file FILE to standard output.
  72.477 +@@ -483,6 +836,7 @@ main (int argc, char **argv)
  72.478 +   bool ok;
  72.479 +   bool delim_specified = false;
  72.480 +   char *spec_list_string IF_LINT ( = NULL);
  72.481 ++  char mbdelim[MB_LEN_MAX + 1];
  72.482 + 
  72.483 +   initialize_main (&argc, &argv);
  72.484 +   set_program_name (argv[0]);
  72.485 +@@ -505,7 +859,6 @@ main (int argc, char **argv)
  72.486 +       switch (optc)
  72.487 +         {
  72.488 +         case 'b':
  72.489 +-        case 'c':
  72.490 +           /* Build the byte list. */
  72.491 +           if (operating_mode != undefined_mode)
  72.492 +             FATAL_ERROR (_("only one type of list may be specified"));
  72.493 +@@ -513,6 +866,14 @@ main (int argc, char **argv)
  72.494 +           spec_list_string = optarg;
  72.495 +           break;
  72.496 + 
  72.497 ++        case 'c':
  72.498 ++          /* Build the character list. */
  72.499 ++          if (operating_mode != undefined_mode)
  72.500 ++            FATAL_ERROR (_("only one type of list may be specified"));
  72.501 ++          operating_mode = character_mode;
  72.502 ++          spec_list_string = optarg;
  72.503 ++          break;
  72.504 ++
  72.505 +         case 'f':
  72.506 +           /* Build the field list. */
  72.507 +           if (operating_mode != undefined_mode)
  72.508 +@@ -524,10 +885,38 @@ main (int argc, char **argv)
  72.509 +         case 'd':
  72.510 +           /* New delimiter. */
  72.511 +           /* Interpret -d '' to mean 'use the NUL byte as the delimiter.'  */
  72.512 +-          if (optarg[0] != '\0' && optarg[1] != '\0')
  72.513 +-            FATAL_ERROR (_("the delimiter must be a single character"));
  72.514 +-          delim = optarg[0];
  72.515 +-          delim_specified = true;
  72.516 ++            {
  72.517 ++#if HAVE_MBRTOWC
  72.518 ++              if(MB_CUR_MAX > 1)
  72.519 ++                {
  72.520 ++                  mbstate_t state;
  72.521 ++
  72.522 ++                  memset (&state, '\0', sizeof(mbstate_t));
  72.523 ++                  delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state);
  72.524 ++
  72.525 ++                  if (delimlen == (size_t)-1 || delimlen == (size_t)-2)
  72.526 ++                    ++force_singlebyte_mode;
  72.527 ++                  else
  72.528 ++                    {
  72.529 ++                      delimlen = (delimlen < 1) ? 1 : delimlen;
  72.530 ++                      if (wcdelim != L'\0' && *(optarg + delimlen) != '\0')
  72.531 ++                        FATAL_ERROR (_("the delimiter must be a single character"));
  72.532 ++                      memcpy (mbdelim, optarg, delimlen);
  72.533 ++                      mbdelim[delimlen] = '\0';
  72.534 ++                      if (delimlen == 1)
  72.535 ++                        delim = *optarg;
  72.536 ++                    }
  72.537 ++                }
  72.538 ++
  72.539 ++              if (MB_CUR_MAX <= 1 || force_singlebyte_mode)
  72.540 ++#endif
  72.541 ++                {
  72.542 ++                  if (optarg[0] != '\0' && optarg[1] != '\0')
  72.543 ++                    FATAL_ERROR (_("the delimiter must be a single character"));
  72.544 ++                  delim = (unsigned char) optarg[0];
  72.545 ++                }
  72.546 ++            delim_specified = true;
  72.547 ++          }
  72.548 +           break;
  72.549 + 
  72.550 +         case OUTPUT_DELIMITER_OPTION:
  72.551 +@@ -540,6 +929,7 @@ main (int argc, char **argv)
  72.552 +           break;
  72.553 + 
  72.554 +         case 'n':
  72.555 ++          byte_mode_character_aware = 1;
  72.556 +           break;
  72.557 + 
  72.558 +         case 's':
  72.559 +@@ -579,15 +969,34 @@ main (int argc, char **argv)
  72.560 +               | (complement ? SETFLD_COMPLEMENT : 0) );
  72.561 + 
  72.562 +   if (!delim_specified)
  72.563 +-    delim = '\t';
  72.564 ++    {
  72.565 ++      delim = '\t';
  72.566 ++#ifdef HAVE_MBRTOWC
  72.567 ++      wcdelim = L'\t';
  72.568 ++      mbdelim[0] = '\t';
  72.569 ++      mbdelim[1] = '\0';
  72.570 ++      delimlen = 1;
  72.571 ++#endif
  72.572 ++    }
  72.573 + 
  72.574 +   if (output_delimiter_string == NULL)
  72.575 +     {
  72.576 +-      static char dummy[2];
  72.577 +-      dummy[0] = delim;
  72.578 +-      dummy[1] = '\0';
  72.579 +-      output_delimiter_string = dummy;
  72.580 +-      output_delimiter_length = 1;
  72.581 ++#ifdef HAVE_MBRTOWC
  72.582 ++      if (MB_CUR_MAX > 1 && !force_singlebyte_mode)
  72.583 ++        {
  72.584 ++          output_delimiter_string = xstrdup(mbdelim);
  72.585 ++          output_delimiter_length = delimlen;
  72.586 ++        }
  72.587 ++
  72.588 ++      if (MB_CUR_MAX <= 1 || force_singlebyte_mode)
  72.589 ++#endif
  72.590 ++        {
  72.591 ++          static char dummy[2];
  72.592 ++          dummy[0] = delim;
  72.593 ++          dummy[1] = '\0';
  72.594 ++          output_delimiter_string = dummy;
  72.595 ++          output_delimiter_length = 1;
  72.596 ++        }
  72.597 +     }
  72.598 + 
  72.599 +   if (optind == argc)
  72.600 +diff -Naurp coreutils-8.25-orig/src/expand.c coreutils-8.25/src/expand.c
  72.601 +--- coreutils-8.25-orig/src/expand.c	2016-01-01 07:48:50.000000000 -0600
  72.602 ++++ coreutils-8.25/src/expand.c	2016-02-08 19:07:10.301944619 -0600
  72.603 +@@ -37,12 +37,34 @@
  72.604 + #include <stdio.h>
  72.605 + #include <getopt.h>
  72.606 + #include <sys/types.h>
  72.607 ++
  72.608 ++/* Get mbstate_t, mbrtowc(), wcwidth(). */
  72.609 ++#if HAVE_WCHAR_H
  72.610 ++# include <wchar.h>
  72.611 ++#endif
  72.612 ++
  72.613 ++/* Get iswblank(). */
  72.614 ++#if HAVE_WCTYPE_H
  72.615 ++# include <wctype.h>
  72.616 ++#endif
  72.617 ++
  72.618 + #include "system.h"
  72.619 + #include "error.h"
  72.620 + #include "fadvise.h"
  72.621 + #include "quote.h"
  72.622 + #include "xstrndup.h"
  72.623 + 
  72.624 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
  72.625 ++   installation; work around this configuration error.  */
  72.626 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
  72.627 ++# define MB_LEN_MAX 16
  72.628 ++#endif
  72.629 ++
  72.630 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
  72.631 ++#if HAVE_MBRTOWC && defined mbstate_t
  72.632 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
  72.633 ++#endif
  72.634 ++
  72.635 + /* The official name of this program (e.g., no 'g' prefix).  */
  72.636 + #define PROGRAM_NAME "expand"
  72.637 + 
  72.638 +@@ -357,6 +379,142 @@ expand (void)
  72.639 +     }
  72.640 + }
  72.641 + 
  72.642 ++#if HAVE_MBRTOWC
  72.643 ++static void
  72.644 ++expand_multibyte (void)
  72.645 ++{
  72.646 ++  FILE *fp;			/* Input strem. */
  72.647 ++  mbstate_t i_state;		/* Current shift state of the input stream. */
  72.648 ++  mbstate_t i_state_bak;	/* Back up the I_STATE. */
  72.649 ++  mbstate_t o_state;		/* Current shift state of the output stream. */
  72.650 ++  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
  72.651 ++  char *bufpos = buf;			/* Next read position of BUF. */
  72.652 ++  size_t buflen = 0;		/* The length of the byte sequence in buf. */
  72.653 ++  wchar_t wc;			/* A gotten wide character. */
  72.654 ++  size_t mblength;		/* The byte size of a multibyte character
  72.655 ++				   which shows as same character as WC. */
  72.656 ++  int tab_index = 0;		/* Index in `tab_list' of next tabstop. */
  72.657 ++  int column = 0;		/* Column on screen of the next char. */
  72.658 ++  int next_tab_column;		/* Column the next tab stop is on. */
  72.659 ++  int convert = 1;		/* If nonzero, perform translations. */
  72.660 ++
  72.661 ++  fp = next_file ((FILE *) NULL);
  72.662 ++  if (fp == NULL)
  72.663 ++    return;
  72.664 ++
  72.665 ++  memset (&o_state, '\0', sizeof(mbstate_t));
  72.666 ++  memset (&i_state, '\0', sizeof(mbstate_t));
  72.667 ++
  72.668 ++  for (;;)
  72.669 ++    {
  72.670 ++      /* Refill the buffer BUF. */
  72.671 ++      if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp))
  72.672 ++	{
  72.673 ++	  memmove (buf, bufpos, buflen);
  72.674 ++	  buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp);
  72.675 ++	  bufpos = buf;
  72.676 ++	}
  72.677 ++
  72.678 ++      /* No character is left in BUF. */
  72.679 ++      if (buflen < 1)
  72.680 ++	{
  72.681 ++	  fp = next_file (fp);
  72.682 ++
  72.683 ++	  if (fp == NULL)
  72.684 ++	    break;		/* No more files. */
  72.685 ++	  else
  72.686 ++	    {
  72.687 ++	      memset (&i_state, '\0', sizeof(mbstate_t));
  72.688 ++	      continue;
  72.689 ++	    }
  72.690 ++	}
  72.691 ++
  72.692 ++      /* Get a wide character. */
  72.693 ++      i_state_bak = i_state;
  72.694 ++      mblength = mbrtowc (&wc, bufpos, buflen, &i_state);
  72.695 ++
  72.696 ++      switch (mblength)
  72.697 ++	{
  72.698 ++	case (size_t)-1:	/* illegal byte sequence. */
  72.699 ++	case (size_t)-2:
  72.700 ++	  mblength = 1;
  72.701 ++	  i_state = i_state_bak;
  72.702 ++	  if (convert)
  72.703 ++	    {
  72.704 ++	      ++column;
  72.705 ++	      if (convert_entire_line == 0 && !isblank(*bufpos))
  72.706 ++		convert = 0;
  72.707 ++	    }
  72.708 ++	  putchar (*bufpos);
  72.709 ++	  break;
  72.710 ++
  72.711 ++	case 0:		/* null. */
  72.712 ++	  mblength = 1;
  72.713 ++	  if (convert && convert_entire_line == 0)
  72.714 ++	    convert = 0;
  72.715 ++	  putchar ('\0');
  72.716 ++	  break;
  72.717 ++
  72.718 ++	default:
  72.719 ++	  if (wc == L'\n')   /* LF. */
  72.720 ++	    {
  72.721 ++	      tab_index = 0;
  72.722 ++	      column = 0;
  72.723 ++	      convert = 1;
  72.724 ++	      putchar ('\n');
  72.725 ++	    }
  72.726 ++	  else if (wc == L'\t' && convert)	/* Tab. */
  72.727 ++	    {
  72.728 ++	      if (tab_size == 0)
  72.729 ++		{
  72.730 ++		  /* Do not let tab_index == first_free_tab;
  72.731 ++		     stop when it is 1 less. */
  72.732 ++		  while (tab_index < first_free_tab - 1
  72.733 ++		      && column >= tab_list[tab_index])
  72.734 ++		    tab_index++;
  72.735 ++		  next_tab_column = tab_list[tab_index];
  72.736 ++		  if (tab_index < first_free_tab - 1)
  72.737 ++		    tab_index++;
  72.738 ++		  if (column >= next_tab_column)
  72.739 ++		    next_tab_column = column + 1;
  72.740 ++		}
  72.741 ++	      else
  72.742 ++		next_tab_column = column + tab_size - column % tab_size;
  72.743 ++
  72.744 ++	      while (column < next_tab_column)
  72.745 ++		{
  72.746 ++		  putchar (' ');
  72.747 ++		  ++column;
  72.748 ++		}
  72.749 ++	    }
  72.750 ++	  else  /* Others. */
  72.751 ++	    {
  72.752 ++	      if (convert)
  72.753 ++		{
  72.754 ++		  if (wc == L'\b')
  72.755 ++		    {
  72.756 ++		      if (column > 0)
  72.757 ++			--column;
  72.758 ++		    }
  72.759 ++		  else
  72.760 ++		    {
  72.761 ++		      int width;		/* The width of WC. */
  72.762 ++
  72.763 ++		      width = wcwidth (wc);
  72.764 ++		      column += (width > 0) ? width : 0;
  72.765 ++		      if (convert_entire_line == 0 && !iswblank(wc))
  72.766 ++			convert = 0;
  72.767 ++		    }
  72.768 ++		}
  72.769 ++	      fwrite (bufpos, sizeof(char), mblength, stdout);
  72.770 ++	    }
  72.771 ++	}
  72.772 ++      buflen -= mblength;
  72.773 ++      bufpos += mblength;
  72.774 ++    }
  72.775 ++}
  72.776 ++#endif
  72.777 ++
  72.778 + int
  72.779 + main (int argc, char **argv)
  72.780 + {
  72.781 +@@ -421,7 +579,12 @@ main (int argc, char **argv)
  72.782 + 
  72.783 +   file_list = (optind < argc ? &argv[optind] : stdin_argv);
  72.784 + 
  72.785 +-  expand ();
  72.786 ++#if HAVE_MBRTOWC
  72.787 ++  if (MB_CUR_MAX > 1)
  72.788 ++    expand_multibyte ();
  72.789 ++  else
  72.790 ++#endif
  72.791 ++    expand ();
  72.792 + 
  72.793 +   if (have_read_stdin && fclose (stdin) != 0)
  72.794 +     error (EXIT_FAILURE, errno, "-");
  72.795 +diff -Naurp coreutils-8.25-orig/src/fold.c coreutils-8.25/src/fold.c
  72.796 +--- coreutils-8.25-orig/src/fold.c	2016-01-01 07:48:50.000000000 -0600
  72.797 ++++ coreutils-8.25/src/fold.c	2016-02-08 19:07:10.302944622 -0600
  72.798 +@@ -22,11 +22,33 @@
  72.799 + #include <getopt.h>
  72.800 + #include <sys/types.h>
  72.801 + 
  72.802 ++/* Get mbstate_t, mbrtowc(), wcwidth().  */
  72.803 ++#if HAVE_WCHAR_H
  72.804 ++# include <wchar.h>
  72.805 ++#endif
  72.806 ++
  72.807 ++/* Get iswprint(), iswblank(), wcwidth().  */
  72.808 ++#if HAVE_WCTYPE_H
  72.809 ++# include <wctype.h>
  72.810 ++#endif
  72.811 ++
  72.812 + #include "system.h"
  72.813 + #include "error.h"
  72.814 + #include "fadvise.h"
  72.815 + #include "xdectoint.h"
  72.816 + 
  72.817 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
  72.818 ++      installation; work around this configuration error.  */
  72.819 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
  72.820 ++# undef MB_LEN_MAX
  72.821 ++# define MB_LEN_MAX 16
  72.822 ++#endif
  72.823 ++
  72.824 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
  72.825 ++#if HAVE_MBRTOWC && defined mbstate_t
  72.826 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
  72.827 ++#endif
  72.828 ++
  72.829 + #define TAB_WIDTH 8
  72.830 + 
  72.831 + /* The official name of this program (e.g., no 'g' prefix).  */
  72.832 +@@ -34,20 +56,41 @@
  72.833 + 
  72.834 + #define AUTHORS proper_name ("David MacKenzie")
  72.835 + 
  72.836 ++#define FATAL_ERROR(Message)                                            \
  72.837 ++  do                                                                    \
  72.838 ++    {                                                                   \
  72.839 ++      error (0, 0, (Message));                                          \
  72.840 ++      usage (2);                                                        \
  72.841 ++    }                                                                   \
  72.842 ++  while (0)
  72.843 ++
  72.844 ++enum operating_mode
  72.845 ++{
  72.846 ++  /* Fold texts by columns that are at the given positions. */
  72.847 ++  column_mode,
  72.848 ++
  72.849 ++  /* Fold texts by bytes that are at the given positions. */
  72.850 ++  byte_mode,
  72.851 ++
  72.852 ++  /* Fold texts by characters that are at the given positions. */
  72.853 ++  character_mode,
  72.854 ++};
  72.855 ++
  72.856 ++/* The argument shows current mode. (Default: column_mode) */
  72.857 ++static enum operating_mode operating_mode;
  72.858 ++
  72.859 + /* If nonzero, try to break on whitespace. */
  72.860 + static bool break_spaces;
  72.861 + 
  72.862 +-/* If nonzero, count bytes, not column positions. */
  72.863 +-static bool count_bytes;
  72.864 +-
  72.865 + /* If nonzero, at least one of the files we read was standard input. */
  72.866 + static bool have_read_stdin;
  72.867 + 
  72.868 +-static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::";
  72.869 ++static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::";
  72.870 + 
  72.871 + static struct option const longopts[] =
  72.872 + {
  72.873 +   {"bytes", no_argument, NULL, 'b'},
  72.874 ++  {"characters", no_argument, NULL, 'c'},
  72.875 +   {"spaces", no_argument, NULL, 's'},
  72.876 +   {"width", required_argument, NULL, 'w'},
  72.877 +   {GETOPT_HELP_OPTION_DECL},
  72.878 +@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing t
  72.879 + 
  72.880 +       fputs (_("\
  72.881 +   -b, --bytes         count bytes rather than columns\n\
  72.882 ++  -c, --characters    count characters rather than columns\n\
  72.883 +   -s, --spaces        break at spaces\n\
  72.884 +   -w, --width=WIDTH   use WIDTH columns instead of 80\n\
  72.885 + "), stdout);
  72.886 +@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing t
  72.887 + static size_t
  72.888 + adjust_column (size_t column, char c)
  72.889 + {
  72.890 +-  if (!count_bytes)
  72.891 ++  if (operating_mode != byte_mode)
  72.892 +     {
  72.893 +       if (c == '\b')
  72.894 +         {
  72.895 +@@ -115,30 +159,14 @@ adjust_column (size_t column, char c)
  72.896 +    to stdout, with maximum line length WIDTH.
  72.897 +    Return true if successful.  */
  72.898 + 
  72.899 +-static bool
  72.900 +-fold_file (char const *filename, size_t width)
  72.901 ++static void
  72.902 ++fold_text (FILE *istream, size_t width, int *saved_errno)
  72.903 + {
  72.904 +-  FILE *istream;
  72.905 +   int c;
  72.906 +   size_t column = 0;		/* Screen column where next char will go. */
  72.907 +   size_t offset_out = 0;	/* Index in 'line_out' for next char. */
  72.908 +   static char *line_out = NULL;
  72.909 +   static size_t allocated_out = 0;
  72.910 +-  int saved_errno;
  72.911 +-
  72.912 +-  if (STREQ (filename, "-"))
  72.913 +-    {
  72.914 +-      istream = stdin;
  72.915 +-      have_read_stdin = true;
  72.916 +-    }
  72.917 +-  else
  72.918 +-    istream = fopen (filename, "r");
  72.919 +-
  72.920 +-  if (istream == NULL)
  72.921 +-    {
  72.922 +-      error (0, errno, "%s", quotef (filename));
  72.923 +-      return false;
  72.924 +-    }
  72.925 + 
  72.926 +   fadvise (istream, FADVISE_SEQUENTIAL);
  72.927 + 
  72.928 +@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t
  72.929 +               bool found_blank = false;
  72.930 +               size_t logical_end = offset_out;
  72.931 + 
  72.932 ++              /* If LINE_OUT has no wide character,
  72.933 ++                 put a new wide character in LINE_OUT
  72.934 ++                 if column is bigger than width. */
  72.935 ++              if (offset_out == 0)
  72.936 ++                {
  72.937 ++                  line_out[offset_out++] = c;
  72.938 ++                  continue;
  72.939 ++                }
  72.940 ++
  72.941 +               /* Look for the last blank. */
  72.942 +               while (logical_end)
  72.943 +                 {
  72.944 +@@ -214,11 +251,221 @@ fold_file (char const *filename, size_t
  72.945 +       line_out[offset_out++] = c;
  72.946 +     }
  72.947 + 
  72.948 +-  saved_errno = errno;
  72.949 ++  *saved_errno = errno;
  72.950 ++
  72.951 ++  if (offset_out)
  72.952 ++    fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
  72.953 ++
  72.954 ++}
  72.955 ++
  72.956 ++#if HAVE_MBRTOWC
  72.957 ++static void
  72.958 ++fold_multibyte_text (FILE *istream, size_t width, int *saved_errno)
  72.959 ++{
  72.960 ++  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
  72.961 ++  size_t buflen = 0;        /* The length of the byte sequence in buf. */
  72.962 ++  char *bufpos = buf;         /* Next read position of BUF. */
  72.963 ++  wint_t wc;                /* A gotten wide character. */
  72.964 ++  size_t mblength;        /* The byte size of a multibyte character which shows
  72.965 ++                           as same character as WC. */
  72.966 ++  mbstate_t state, state_bak;        /* State of the stream. */
  72.967 ++  int convfail = 0;                /* 1, when conversion is failed. Otherwise 0. */
  72.968 ++
  72.969 ++  static char *line_out = NULL;
  72.970 ++  size_t offset_out = 0;        /* Index in `line_out' for next char. */
  72.971 ++  static size_t allocated_out = 0;
  72.972 ++
  72.973 ++  int increment;
  72.974 ++  size_t column = 0;
  72.975 ++
  72.976 ++  size_t last_blank_pos;
  72.977 ++  size_t last_blank_column;
  72.978 ++  int is_blank_seen;
  72.979 ++  int last_blank_increment = 0;
  72.980 ++  int is_bs_following_last_blank;
  72.981 ++  size_t bs_following_last_blank_num;
  72.982 ++  int is_cr_after_last_blank;
  72.983 ++
  72.984 ++#define CLEAR_FLAGS                                \
  72.985 ++   do                                                \
  72.986 ++     {                                                \
  72.987 ++        last_blank_pos = 0;                        \
  72.988 ++        last_blank_column = 0;                        \
  72.989 ++        is_blank_seen = 0;                        \
  72.990 ++        is_bs_following_last_blank = 0;                \
  72.991 ++        bs_following_last_blank_num = 0;        \
  72.992 ++        is_cr_after_last_blank = 0;                \
  72.993 ++     }                                                \
  72.994 ++   while (0)
  72.995 ++
  72.996 ++#define START_NEW_LINE                        \
  72.997 ++   do                                        \
  72.998 ++     {                                        \
  72.999 ++      putchar ('\n');                        \
 72.1000 ++      column = 0;                        \
 72.1001 ++      offset_out = 0;                        \
 72.1002 ++      CLEAR_FLAGS;                        \
 72.1003 ++    }                                        \
 72.1004 ++   while (0)
 72.1005 ++
 72.1006 ++  CLEAR_FLAGS;
 72.1007 ++  memset (&state, '\0', sizeof(mbstate_t));
 72.1008 ++
 72.1009 ++  for (;; bufpos += mblength, buflen -= mblength)
 72.1010 ++    {
 72.1011 ++      if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream))
 72.1012 ++        {
 72.1013 ++          memmove (buf, bufpos, buflen);
 72.1014 ++          buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream);
 72.1015 ++          bufpos = buf;
 72.1016 ++        }
 72.1017 ++
 72.1018 ++      if (buflen < 1)
 72.1019 ++        break;
 72.1020 ++
 72.1021 ++      /* Get a wide character. */
 72.1022 ++      state_bak = state;
 72.1023 ++      mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state);
 72.1024 ++
 72.1025 ++      switch (mblength)
 72.1026 ++        {
 72.1027 ++        case (size_t)-1:
 72.1028 ++        case (size_t)-2:
 72.1029 ++          convfail++;
 72.1030 ++          state = state_bak;
 72.1031 ++          /* Fall through. */
 72.1032 ++
 72.1033 ++        case 0:
 72.1034 ++          mblength = 1;
 72.1035 ++          break;
 72.1036 ++        }
 72.1037 ++
 72.1038 ++rescan:
 72.1039 ++      if (operating_mode == byte_mode)                        /* byte mode */
 72.1040 ++        increment = mblength;
 72.1041 ++      else if (operating_mode == character_mode)        /* character mode */
 72.1042 ++        increment = 1;
 72.1043 ++      else                                                /* column mode */
 72.1044 ++        {
 72.1045 ++          if (convfail)
 72.1046 ++            increment = 1;
 72.1047 ++          else
 72.1048 ++            {
 72.1049 ++              switch (wc)
 72.1050 ++                {
 72.1051 ++                case L'\n':
 72.1052 ++                  fwrite (line_out, sizeof(char), offset_out, stdout);
 72.1053 ++                  START_NEW_LINE;
 72.1054 ++                  continue;
 72.1055 ++
 72.1056 ++                case L'\b':
 72.1057 ++                  increment = (column > 0) ? -1 : 0;
 72.1058 ++                  break;
 72.1059 ++
 72.1060 ++                case L'\r':
 72.1061 ++                  increment = -1 * column;
 72.1062 ++                  break;
 72.1063 ++
 72.1064 ++                case L'\t':
 72.1065 ++                  increment = 8 - column % 8;
 72.1066 ++                  break;
 72.1067 ++
 72.1068 ++                default:
 72.1069 ++                  increment = wcwidth (wc);
 72.1070 ++                  increment = (increment < 0) ? 0 : increment;
 72.1071 ++                }
 72.1072 ++            }
 72.1073 ++        }
 72.1074 ++
 72.1075 ++      if (column + increment > width && break_spaces && last_blank_pos)
 72.1076 ++        {
 72.1077 ++          fwrite (line_out, sizeof(char), last_blank_pos, stdout);
 72.1078 ++          putchar ('\n');
 72.1079 ++
 72.1080 ++          offset_out = offset_out - last_blank_pos;
 72.1081 ++          column = column - last_blank_column + ((is_cr_after_last_blank)
 72.1082 ++              ? last_blank_increment : bs_following_last_blank_num);
 72.1083 ++          memmove (line_out, line_out + last_blank_pos, offset_out);
 72.1084 ++          CLEAR_FLAGS;
 72.1085 ++          goto rescan;
 72.1086 ++        }
 72.1087 ++
 72.1088 ++      if (column + increment > width && column != 0)
 72.1089 ++        {
 72.1090 ++          fwrite (line_out, sizeof(char), offset_out, stdout);
 72.1091 ++          START_NEW_LINE;
 72.1092 ++          goto rescan;
 72.1093 ++        }
 72.1094 ++
 72.1095 ++      if (allocated_out < offset_out + mblength)
 72.1096 ++        {
 72.1097 ++          line_out = X2REALLOC (line_out, &allocated_out);
 72.1098 ++        }
 72.1099 ++
 72.1100 ++      memcpy (line_out + offset_out, bufpos, mblength);
 72.1101 ++      offset_out += mblength;
 72.1102 ++      column += increment;
 72.1103 ++
 72.1104 ++      if (is_blank_seen && !convfail && wc == L'\r')
 72.1105 ++        is_cr_after_last_blank = 1;
 72.1106 ++
 72.1107 ++      if (is_bs_following_last_blank && !convfail && wc == L'\b')
 72.1108 ++        ++bs_following_last_blank_num;
 72.1109 ++      else
 72.1110 ++        is_bs_following_last_blank = 0;
 72.1111 ++
 72.1112 ++      if (break_spaces && !convfail && iswblank (wc))
 72.1113 ++        {
 72.1114 ++          last_blank_pos = offset_out;
 72.1115 ++          last_blank_column = column;
 72.1116 ++          is_blank_seen = 1;
 72.1117 ++          last_blank_increment = increment;
 72.1118 ++          is_bs_following_last_blank = 1;
 72.1119 ++          bs_following_last_blank_num = 0;
 72.1120 ++          is_cr_after_last_blank = 0;
 72.1121 ++        }
 72.1122 ++    }
 72.1123 ++
 72.1124 ++  *saved_errno = errno;
 72.1125 + 
 72.1126 +   if (offset_out)
 72.1127 +     fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
 72.1128 + 
 72.1129 ++}
 72.1130 ++#endif
 72.1131 ++
 72.1132 ++/* Fold file FILENAME, or standard input if FILENAME is "-",
 72.1133 ++   to stdout, with maximum line length WIDTH.
 72.1134 ++   Return 0 if successful, 1 if an error occurs. */
 72.1135 ++
 72.1136 ++static bool
 72.1137 ++fold_file (char const *filename, size_t width)
 72.1138 ++{
 72.1139 ++  FILE *istream;
 72.1140 ++  int saved_errno;
 72.1141 ++
 72.1142 ++  if (STREQ (filename, "-"))
 72.1143 ++    {
 72.1144 ++      istream = stdin;
 72.1145 ++      have_read_stdin = 1;
 72.1146 ++    }
 72.1147 ++  else
 72.1148 ++    istream = fopen (filename, "r");
 72.1149 ++
 72.1150 ++  if (istream == NULL)
 72.1151 ++    {
 72.1152 ++      error (0, errno, "%s", quotef (filename));
 72.1153 ++      return 1;
 72.1154 ++    }
 72.1155 ++
 72.1156 ++  /* Define how ISTREAM is being folded. */
 72.1157 ++#if HAVE_MBRTOWC
 72.1158 ++  if (MB_CUR_MAX > 1)
 72.1159 ++    fold_multibyte_text (istream, width, &saved_errno);
 72.1160 ++  else
 72.1161 ++#endif
 72.1162 ++    fold_text (istream, width, &saved_errno);
 72.1163 ++
 72.1164 +   if (ferror (istream))
 72.1165 +     {
 72.1166 +       error (0, saved_errno, "%s", quotef (filename));
 72.1167 +@@ -251,7 +498,8 @@ main (int argc, char **argv)
 72.1168 + 
 72.1169 +   atexit (close_stdout);
 72.1170 + 
 72.1171 +-  break_spaces = count_bytes = have_read_stdin = false;
 72.1172 ++  operating_mode = column_mode;
 72.1173 ++  break_spaces = have_read_stdin = false;
 72.1174 + 
 72.1175 +   while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
 72.1176 +     {
 72.1177 +@@ -260,7 +508,15 @@ main (int argc, char **argv)
 72.1178 +       switch (optc)
 72.1179 +         {
 72.1180 +         case 'b':		/* Count bytes rather than columns. */
 72.1181 +-          count_bytes = true;
 72.1182 ++          if (operating_mode != column_mode)
 72.1183 ++            FATAL_ERROR (_("only one way of folding may be specified"));
 72.1184 ++          operating_mode = byte_mode;
 72.1185 ++          break;
 72.1186 ++
 72.1187 ++        case 'c':
 72.1188 ++          if (operating_mode != column_mode)
 72.1189 ++            FATAL_ERROR (_("only one way of folding may be specified"));
 72.1190 ++          operating_mode = character_mode;
 72.1191 +           break;
 72.1192 + 
 72.1193 +         case 's':		/* Break at word boundaries. */
 72.1194 +diff -Naurp coreutils-8.25-orig/src/join.c coreutils-8.25/src/join.c
 72.1195 +--- coreutils-8.25-orig/src/join.c	2016-01-13 05:08:59.000000000 -0600
 72.1196 ++++ coreutils-8.25/src/join.c	2016-02-08 19:07:10.303944625 -0600
 72.1197 +@@ -22,18 +22,32 @@
 72.1198 + #include <sys/types.h>
 72.1199 + #include <getopt.h>
 72.1200 + 
 72.1201 ++/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth().  */
 72.1202 ++#if HAVE_WCHAR_H
 72.1203 ++# include <wchar.h>
 72.1204 ++#endif
 72.1205 ++
 72.1206 ++/* Get iswblank(), towupper.  */
 72.1207 ++#if HAVE_WCTYPE_H
 72.1208 ++# include <wctype.h>
 72.1209 ++#endif
 72.1210 ++
 72.1211 + #include "system.h"
 72.1212 + #include "error.h"
 72.1213 + #include "fadvise.h"
 72.1214 + #include "hard-locale.h"
 72.1215 + #include "linebuffer.h"
 72.1216 +-#include "memcasecmp.h"
 72.1217 + #include "quote.h"
 72.1218 + #include "stdio--.h"
 72.1219 + #include "xmemcoll.h"
 72.1220 + #include "xstrtol.h"
 72.1221 + #include "argmatch.h"
 72.1222 + 
 72.1223 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
 72.1224 ++#if HAVE_MBRTOWC && defined mbstate_t
 72.1225 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
 72.1226 ++#endif
 72.1227 ++
 72.1228 + /* The official name of this program (e.g., no 'g' prefix).  */
 72.1229 + #define PROGRAM_NAME "join"
 72.1230 + 
 72.1231 +@@ -135,10 +149,12 @@ static struct outlist outlist_head;
 72.1232 + /* Last element in 'outlist', where a new element can be added.  */
 72.1233 + static struct outlist *outlist_end = &outlist_head;
 72.1234 + 
 72.1235 +-/* Tab character separating fields.  If negative, fields are separated
 72.1236 +-   by any nonempty string of blanks, otherwise by exactly one
 72.1237 +-   tab character whose value (when cast to unsigned char) equals TAB.  */
 72.1238 +-static int tab = -1;
 72.1239 ++/* Tab character separating fields.  If NULL, fields are separated
 72.1240 ++   by any nonempty string of blanks.  */
 72.1241 ++static char *tab = NULL;
 72.1242 ++
 72.1243 ++/* The number of bytes used for tab. */
 72.1244 ++static size_t tablen = 0;
 72.1245 + 
 72.1246 + /* If nonzero, check that the input is correctly ordered. */
 72.1247 + static enum
 72.1248 +@@ -275,13 +291,14 @@ xfields (struct line *line)
 72.1249 +   if (ptr == lim)
 72.1250 +     return;
 72.1251 + 
 72.1252 +-  if (0 <= tab && tab != '\n')
 72.1253 ++  if (tab != NULL)
 72.1254 +     {
 72.1255 ++      unsigned char t = tab[0];
 72.1256 +       char *sep;
 72.1257 +-      for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1)
 72.1258 ++      for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1)
 72.1259 +         extract_field (line, ptr, sep - ptr);
 72.1260 +     }
 72.1261 +-  else if (tab < 0)
 72.1262 ++   else
 72.1263 +     {
 72.1264 +       /* Skip leading blanks before the first field.  */
 72.1265 +       while (field_sep (*ptr))
 72.1266 +@@ -305,6 +322,147 @@ xfields (struct line *line)
 72.1267 +   extract_field (line, ptr, lim - ptr);
 72.1268 + }
 72.1269 + 
 72.1270 ++#if HAVE_MBRTOWC
 72.1271 ++static void
 72.1272 ++xfields_multibyte (struct line *line)
 72.1273 ++{
 72.1274 ++  char *ptr = line->buf.buffer;
 72.1275 ++  char const *lim = ptr + line->buf.length - 1;
 72.1276 ++  wchar_t wc = 0;
 72.1277 ++  size_t mblength = 1;
 72.1278 ++  mbstate_t state, state_bak;
 72.1279 ++
 72.1280 ++  memset (&state, 0, sizeof (mbstate_t));
 72.1281 ++
 72.1282 ++  if (ptr >= lim)
 72.1283 ++    return;
 72.1284 ++
 72.1285 ++  if (tab != NULL)
 72.1286 ++    {
 72.1287 ++      char *sep = ptr;
 72.1288 ++      for (; ptr < lim; ptr = sep + mblength)
 72.1289 ++	{
 72.1290 ++	  sep = ptr;
 72.1291 ++	  while (sep < lim)
 72.1292 ++	    {
 72.1293 ++	      state_bak = state;
 72.1294 ++	      mblength = mbrtowc (&wc, sep, lim - sep + 1, &state);
 72.1295 ++
 72.1296 ++	      if (mblength == (size_t)-1 || mblength == (size_t)-2)
 72.1297 ++		{
 72.1298 ++		  mblength = 1;
 72.1299 ++		  state = state_bak;
 72.1300 ++		}
 72.1301 ++	      mblength = (mblength < 1) ? 1 : mblength;
 72.1302 ++
 72.1303 ++	      if (mblength == tablen && !memcmp (sep, tab, mblength))
 72.1304 ++		break;
 72.1305 ++	      else
 72.1306 ++		{
 72.1307 ++		  sep += mblength;
 72.1308 ++		  continue;
 72.1309 ++		}
 72.1310 ++	    }
 72.1311 ++
 72.1312 ++	  if (sep >= lim)
 72.1313 ++	    break;
 72.1314 ++
 72.1315 ++	  extract_field (line, ptr, sep - ptr);
 72.1316 ++	}
 72.1317 ++    }
 72.1318 ++  else
 72.1319 ++    {
 72.1320 ++      /* Skip leading blanks before the first field.  */
 72.1321 ++      while(ptr < lim)
 72.1322 ++      {
 72.1323 ++        state_bak = state;
 72.1324 ++        mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state);
 72.1325 ++
 72.1326 ++        if (mblength == (size_t)-1 || mblength == (size_t)-2)
 72.1327 ++          {
 72.1328 ++            mblength = 1;
 72.1329 ++            state = state_bak;
 72.1330 ++            break;
 72.1331 ++          }
 72.1332 ++        mblength = (mblength < 1) ? 1 : mblength;
 72.1333 ++
 72.1334 ++        if (!iswblank(wc) && wc != '\n')
 72.1335 ++          break;
 72.1336 ++        ptr += mblength;
 72.1337 ++      }
 72.1338 ++
 72.1339 ++      do
 72.1340 ++	{
 72.1341 ++	  char *sep;
 72.1342 ++	  state_bak = state;
 72.1343 ++	  mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state);
 72.1344 ++	  if (mblength == (size_t)-1 || mblength == (size_t)-2)
 72.1345 ++	    {
 72.1346 ++	      mblength = 1;
 72.1347 ++	      state = state_bak;
 72.1348 ++	      break;
 72.1349 ++	    }
 72.1350 ++	  mblength = (mblength < 1) ? 1 : mblength;
 72.1351 ++
 72.1352 ++	  sep = ptr + mblength;
 72.1353 ++	  while (sep < lim)
 72.1354 ++	    {
 72.1355 ++	      state_bak = state;
 72.1356 ++	      mblength = mbrtowc (&wc, sep, lim - sep + 1, &state);
 72.1357 ++	      if (mblength == (size_t)-1 || mblength == (size_t)-2)
 72.1358 ++		{
 72.1359 ++		  mblength = 1;
 72.1360 ++		  state = state_bak;
 72.1361 ++		  break;
 72.1362 ++		}
 72.1363 ++	      mblength = (mblength < 1) ? 1 : mblength;
 72.1364 ++
 72.1365 ++	      if (iswblank (wc) || wc == '\n')
 72.1366 ++		break;
 72.1367 ++
 72.1368 ++	      sep += mblength;
 72.1369 ++	    }
 72.1370 ++
 72.1371 ++	  extract_field (line, ptr, sep - ptr);
 72.1372 ++	  if (sep >= lim)
 72.1373 ++	    return;
 72.1374 ++
 72.1375 ++	  state_bak = state;
 72.1376 ++	  mblength = mbrtowc (&wc, sep, lim - sep + 1, &state);
 72.1377 ++	  if (mblength == (size_t)-1 || mblength == (size_t)-2)
 72.1378 ++	    {
 72.1379 ++	      mblength = 1;
 72.1380 ++	      state = state_bak;
 72.1381 ++	      break;
 72.1382 ++	    }
 72.1383 ++	  mblength = (mblength < 1) ? 1 : mblength;
 72.1384 ++
 72.1385 ++	  ptr = sep + mblength;
 72.1386 ++	  while (ptr < lim)
 72.1387 ++	    {
 72.1388 ++	      state_bak = state;
 72.1389 ++	      mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state);
 72.1390 ++	      if (mblength == (size_t)-1 || mblength == (size_t)-2)
 72.1391 ++		{
 72.1392 ++		  mblength = 1;
 72.1393 ++		  state = state_bak;
 72.1394 ++		  break;
 72.1395 ++		}
 72.1396 ++	      mblength = (mblength < 1) ? 1 : mblength;
 72.1397 ++
 72.1398 ++	      if (!iswblank (wc) && wc != '\n')
 72.1399 ++		break;
 72.1400 ++
 72.1401 ++	      ptr += mblength;
 72.1402 ++	    }
 72.1403 ++	}
 72.1404 ++      while (ptr < lim);
 72.1405 ++    }
 72.1406 ++
 72.1407 ++  extract_field (line, ptr, lim - ptr);
 72.1408 ++}
 72.1409 ++#endif
 72.1410 ++
 72.1411 + static void
 72.1412 + freeline (struct line *line)
 72.1413 + {
 72.1414 +@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct
 72.1415 +         size_t jf_1, size_t jf_2)
 72.1416 + {
 72.1417 +   /* Start of field to compare in each file.  */
 72.1418 +-  char *beg1;
 72.1419 +-  char *beg2;
 72.1420 +-
 72.1421 +-  size_t len1;
 72.1422 +-  size_t len2;		/* Length of fields to compare.  */
 72.1423 ++  char *beg[2];
 72.1424 ++  char *copy[2];
 72.1425 ++  size_t len[2]; 	/* Length of fields to compare.  */
 72.1426 +   int diff;
 72.1427 ++  int i, j;
 72.1428 ++  int mallocd = 0;
 72.1429 + 
 72.1430 +   if (jf_1 < line1->nfields)
 72.1431 +     {
 72.1432 +-      beg1 = line1->fields[jf_1].beg;
 72.1433 +-      len1 = line1->fields[jf_1].len;
 72.1434 ++      beg[0] = line1->fields[jf_1].beg;
 72.1435 ++      len[0] = line1->fields[jf_1].len;
 72.1436 +     }
 72.1437 +   else
 72.1438 +     {
 72.1439 +-      beg1 = NULL;
 72.1440 +-      len1 = 0;
 72.1441 ++      beg[0] = NULL;
 72.1442 ++      len[0] = 0;
 72.1443 +     }
 72.1444 + 
 72.1445 +   if (jf_2 < line2->nfields)
 72.1446 +     {
 72.1447 +-      beg2 = line2->fields[jf_2].beg;
 72.1448 +-      len2 = line2->fields[jf_2].len;
 72.1449 ++      beg[1] = line2->fields[jf_2].beg;
 72.1450 ++      len[1] = line2->fields[jf_2].len;
 72.1451 +     }
 72.1452 +   else
 72.1453 +     {
 72.1454 +-      beg2 = NULL;
 72.1455 +-      len2 = 0;
 72.1456 ++      beg[1] = NULL;
 72.1457 ++      len[1] = 0;
 72.1458 +     }
 72.1459 + 
 72.1460 +-  if (len1 == 0)
 72.1461 +-    return len2 == 0 ? 0 : -1;
 72.1462 +-  if (len2 == 0)
 72.1463 ++  if (len[0] == 0)
 72.1464 ++    return len[1] == 0 ? 0 : -1;
 72.1465 ++  if (len[1] == 0)
 72.1466 +     return 1;
 72.1467 + 
 72.1468 +   if (ignore_case)
 72.1469 +     {
 72.1470 +-      /* FIXME: ignore_case does not work with NLS (in particular,
 72.1471 +-         with multibyte chars).  */
 72.1472 +-      diff = memcasecmp (beg1, beg2, MIN (len1, len2));
 72.1473 ++#ifdef HAVE_MBRTOWC
 72.1474 ++      if (MB_CUR_MAX > 1)
 72.1475 ++      {
 72.1476 ++        size_t mblength;
 72.1477 ++        wchar_t wc, uwc;
 72.1478 ++        mbstate_t state, state_bak;
 72.1479 ++
 72.1480 ++        memset (&state, '\0', sizeof (mbstate_t));
 72.1481 ++
 72.1482 ++        for (i = 0; i < 2; i++)
 72.1483 ++          {
 72.1484 ++            mallocd = 1;
 72.1485 ++            copy[i] = xmalloc (len[i] + 1);
 72.1486 ++            memset (copy[i], '\0',len[i] + 1);
 72.1487 ++
 72.1488 ++            for (j = 0; j < MIN (len[0], len[1]);)
 72.1489 ++              {
 72.1490 ++                state_bak = state;
 72.1491 ++                mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state);
 72.1492 ++
 72.1493 ++                switch (mblength)
 72.1494 ++                  {
 72.1495 ++                  case (size_t) -1:
 72.1496 ++                  case (size_t) -2:
 72.1497 ++                    state = state_bak;
 72.1498 ++                    /* Fall through */
 72.1499 ++                  case 0:
 72.1500 ++                    mblength = 1;
 72.1501 ++                    break;
 72.1502 ++
 72.1503 ++                  default:
 72.1504 ++                    uwc = towupper (wc);
 72.1505 ++
 72.1506 ++                    if (uwc != wc)
 72.1507 ++                      {
 72.1508 ++                        mbstate_t state_wc;
 72.1509 ++                        size_t mblen;
 72.1510 ++
 72.1511 ++                        memset (&state_wc, '\0', sizeof (mbstate_t));
 72.1512 ++                        mblen = wcrtomb (copy[i] + j, uwc, &state_wc);
 72.1513 ++                        assert (mblen != (size_t)-1);
 72.1514 ++                      }
 72.1515 ++                    else
 72.1516 ++                      memcpy (copy[i] + j, beg[i] + j, mblength);
 72.1517 ++                  }
 72.1518 ++                j += mblength;
 72.1519 ++              }
 72.1520 ++            copy[i][j] = '\0';
 72.1521 ++          }
 72.1522 ++      }
 72.1523 ++      else
 72.1524 ++#endif
 72.1525 ++      {
 72.1526 ++        for (i = 0; i < 2; i++)
 72.1527 ++          {
 72.1528 ++            mallocd = 1;
 72.1529 ++            copy[i] = xmalloc (len[i] + 1);
 72.1530 ++
 72.1531 ++            for (j = 0; j < MIN (len[0], len[1]); j++)
 72.1532 ++              copy[i][j] = toupper (beg[i][j]);
 72.1533 ++
 72.1534 ++            copy[i][j] = '\0';
 72.1535 ++          }
 72.1536 ++      }
 72.1537 +     }
 72.1538 +   else
 72.1539 +     {
 72.1540 +-      if (hard_LC_COLLATE)
 72.1541 +-        return xmemcoll (beg1, len1, beg2, len2);
 72.1542 +-      diff = memcmp (beg1, beg2, MIN (len1, len2));
 72.1543 ++      copy[0] = beg[0];
 72.1544 ++      copy[1] = beg[1];
 72.1545 ++    }
 72.1546 ++
 72.1547 ++  if (hard_LC_COLLATE)
 72.1548 ++    {
 72.1549 ++      diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]);
 72.1550 ++
 72.1551 ++      if (mallocd)
 72.1552 ++        for (i = 0; i < 2; i++)
 72.1553 ++          free (copy[i]);
 72.1554 ++
 72.1555 ++      return diff;
 72.1556 +     }
 72.1557 ++  diff = memcmp (copy[0], copy[1], MIN (len[0], len[1]));
 72.1558 ++
 72.1559 ++  if (mallocd)
 72.1560 ++    for (i = 0; i < 2; i++)
 72.1561 ++      free (copy[i]);
 72.1562 ++
 72.1563 + 
 72.1564 +   if (diff)
 72.1565 +     return diff;
 72.1566 +-  return len1 < len2 ? -1 : len1 != len2;
 72.1567 ++  return len[0] - len[1];
 72.1568 + }
 72.1569 + 
 72.1570 + /* Check that successive input lines PREV and CURRENT from input file
 72.1571 +@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep,
 72.1572 +     }
 72.1573 +   ++line_no[which - 1];
 72.1574 + 
 72.1575 ++#if HAVE_MBRTOWC
 72.1576 ++  if (MB_CUR_MAX > 1)
 72.1577 ++    xfields_multibyte (line);
 72.1578 ++  else
 72.1579 ++#endif
 72.1580 +   xfields (line);
 72.1581 + 
 72.1582 +   if (prevline[which - 1])
 72.1583 +@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *li
 72.1584 + 
 72.1585 + /* Output all the fields in line, other than the join field.  */
 72.1586 + 
 72.1587 ++#define PUT_TAB_CHAR							\
 72.1588 ++  do									\
 72.1589 ++    {									\
 72.1590 ++      (tab != NULL) ?							\
 72.1591 ++	fwrite(tab, sizeof(char), tablen, stdout) : putchar (' ');	\
 72.1592 ++    }									\
 72.1593 ++  while (0)
 72.1594 ++
 72.1595 + static void
 72.1596 + prfields (struct line const *line, size_t join_field, size_t autocount)
 72.1597 + {
 72.1598 +   size_t i;
 72.1599 +   size_t nfields = autoformat ? autocount : line->nfields;
 72.1600 +-  char output_separator = tab < 0 ? ' ' : tab;
 72.1601 + 
 72.1602 +   for (i = 0; i < join_field && i < nfields; ++i)
 72.1603 +     {
 72.1604 +-      putchar (output_separator);
 72.1605 ++      PUT_TAB_CHAR;
 72.1606 +       prfield (i, line);
 72.1607 +     }
 72.1608 +   for (i = join_field + 1; i < nfields; ++i)
 72.1609 +     {
 72.1610 +-      putchar (output_separator);
 72.1611 ++      PUT_TAB_CHAR;
 72.1612 +       prfield (i, line);
 72.1613 +     }
 72.1614 + }
 72.1615 +@@ -591,7 +838,6 @@ static void
 72.1616 + prjoin (struct line const *line1, struct line const *line2)
 72.1617 + {
 72.1618 +   const struct outlist *outlist;
 72.1619 +-  char output_separator = tab < 0 ? ' ' : tab;
 72.1620 +   size_t field;
 72.1621 +   struct line const *line;
 72.1622 + 
 72.1623 +@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct
 72.1624 +           o = o->next;
 72.1625 +           if (o == NULL)
 72.1626 +             break;
 72.1627 +-          putchar (output_separator);
 72.1628 ++          PUT_TAB_CHAR;
 72.1629 +         }
 72.1630 +       putchar (eolchar);
 72.1631 +     }
 72.1632 +@@ -1103,21 +1349,46 @@ main (int argc, char **argv)
 72.1633 + 
 72.1634 +         case 't':
 72.1635 +           {
 72.1636 +-            unsigned char newtab = optarg[0];
 72.1637 ++            char *newtab = NULL;
 72.1638 ++            size_t newtablen;
 72.1639 ++            newtab = xstrdup (optarg);
 72.1640 ++#if HAVE_MBRTOWC
 72.1641 ++            if (MB_CUR_MAX > 1)
 72.1642 ++              {
 72.1643 ++                mbstate_t state;
 72.1644 ++
 72.1645 ++                memset (&state, 0, sizeof (mbstate_t));
 72.1646 ++                newtablen = mbrtowc (NULL, newtab,
 72.1647 ++                                     strnlen (newtab, MB_LEN_MAX),
 72.1648 ++                                     &state);
 72.1649 ++                if (newtablen == (size_t) 0
 72.1650 ++                    || newtablen == (size_t) -1
 72.1651 ++                    || newtablen == (size_t) -2)
 72.1652 ++                  newtablen = 1;
 72.1653 ++              }
 72.1654 ++            else
 72.1655 ++#endif
 72.1656 ++              newtablen = 1;
 72.1657 +             if (! newtab)
 72.1658 +-              newtab = '\n'; /* '' => process the whole line.  */
 72.1659 ++            {
 72.1660 ++              newtab = (char*)"\n"; /* '' => process the whole line.  */
 72.1661 ++            }
 72.1662 +             else if (optarg[1])
 72.1663 +               {
 72.1664 +-                if (STREQ (optarg, "\\0"))
 72.1665 +-                  newtab = '\0';
 72.1666 +-                else
 72.1667 +-                  error (EXIT_FAILURE, 0, _("multi-character tab %s"),
 72.1668 +-                         quote (optarg));
 72.1669 ++                if (newtablen == 1 && newtab[1])
 72.1670 ++                {
 72.1671 ++                  if (STREQ (newtab, "\\0"))
 72.1672 ++                     newtab[0] = '\0';
 72.1673 ++                }
 72.1674 ++              }
 72.1675 ++            if (tab != NULL && strcmp (tab, newtab))
 72.1676 ++              {
 72.1677 ++                free (newtab);
 72.1678 ++                error (EXIT_FAILURE, 0, _("incompatible tabs"));
 72.1679 +               }
 72.1680 +-            if (0 <= tab && tab != newtab)
 72.1681 +-              error (EXIT_FAILURE, 0, _("incompatible tabs"));
 72.1682 +             tab = newtab;
 72.1683 +-          }
 72.1684 ++            tablen = newtablen;
 72.1685 ++           }
 72.1686 +           break;
 72.1687 + 
 72.1688 +         case 'z':
 72.1689 +diff -Naurp coreutils-8.25-orig/src/pr.c coreutils-8.25/src/pr.c
 72.1690 +--- coreutils-8.25-orig/src/pr.c	2016-01-01 07:48:50.000000000 -0600
 72.1691 ++++ coreutils-8.25/src/pr.c	2016-02-08 19:07:10.306944635 -0600
 72.1692 +@@ -311,6 +311,24 @@
 72.1693 + 
 72.1694 + #include <getopt.h>
 72.1695 + #include <sys/types.h>
 72.1696 ++
 72.1697 ++/* Get MB_LEN_MAX.  */
 72.1698 ++#include <limits.h>
 72.1699 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
 72.1700 ++   installation; work around this configuration error.  */
 72.1701 ++#if !defined MB_LEN_MAX || MB_LEN_MAX == 1
 72.1702 ++# define MB_LEN_MAX 16
 72.1703 ++#endif
 72.1704 ++
 72.1705 ++/* Get MB_CUR_MAX.  */
 72.1706 ++#include <stdlib.h>
 72.1707 ++
 72.1708 ++/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
 72.1709 ++/* Get mbstate_t, mbrtowc(), wcwidth().  */
 72.1710 ++#if HAVE_WCHAR_H
 72.1711 ++# include <wchar.h>
 72.1712 ++#endif
 72.1713 ++
 72.1714 + #include "system.h"
 72.1715 + #include "error.h"
 72.1716 + #include "fadvise.h"
 72.1717 +@@ -323,6 +341,18 @@
 72.1718 + #include "xstrtol.h"
 72.1719 + #include "xdectoint.h"
 72.1720 + 
 72.1721 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
 72.1722 ++#if HAVE_MBRTOWC && defined mbstate_t
 72.1723 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
 72.1724 ++#endif
 72.1725 ++
 72.1726 ++#ifndef HAVE_DECL_WCWIDTH
 72.1727 ++"this configure-time declaration test was not run"
 72.1728 ++#endif
 72.1729 ++#if !HAVE_DECL_WCWIDTH
 72.1730 ++extern int wcwidth ();
 72.1731 ++#endif
 72.1732 ++
 72.1733 + /* The official name of this program (e.g., no 'g' prefix).  */
 72.1734 + #define PROGRAM_NAME "pr"
 72.1735 + 
 72.1736 +@@ -415,7 +445,20 @@ struct COLUMN
 72.1737 + 
 72.1738 + typedef struct COLUMN COLUMN;
 72.1739 + 
 72.1740 +-static int char_to_clump (char c);
 72.1741 ++/* Funtion pointers to switch functions for single byte locale or for
 72.1742 ++   multibyte locale. If multibyte functions do not exist in your sysytem,
 72.1743 ++   these pointers always point the function for single byte locale. */
 72.1744 ++static void (*print_char) (char c);
 72.1745 ++static int (*char_to_clump) (char c);
 72.1746 ++
 72.1747 ++/* Functions for single byte locale. */
 72.1748 ++static void print_char_single (char c);
 72.1749 ++static int char_to_clump_single (char c);
 72.1750 ++
 72.1751 ++/* Functions for multibyte locale. */
 72.1752 ++static void print_char_multi (char c);
 72.1753 ++static int char_to_clump_multi (char c);
 72.1754 ++
 72.1755 + static bool read_line (COLUMN *p);
 72.1756 + static bool print_page (void);
 72.1757 + static bool print_stored (COLUMN *p);
 72.1758 +@@ -427,6 +470,7 @@ static void add_line_number (COLUMN *p);
 72.1759 + static void getoptnum (const char *n_str, int min, int *num,
 72.1760 +                        const char *errfmt);
 72.1761 + static void getoptarg (char *arg, char switch_char, char *character,
 72.1762 ++                       int *character_length, int *character_width,
 72.1763 +                        int *number);
 72.1764 + static void print_files (int number_of_files, char **av);
 72.1765 + static void init_parameters (int number_of_files);
 72.1766 +@@ -440,7 +484,6 @@ static void store_char (char c);
 72.1767 + static void pad_down (unsigned int lines);
 72.1768 + static void read_rest_of_line (COLUMN *p);
 72.1769 + static void skip_read (COLUMN *p, int column_number);
 72.1770 +-static void print_char (char c);
 72.1771 + static void cleanup (void);
 72.1772 + static void print_sep_string (void);
 72.1773 + static void separator_string (const char *optarg_S);
 72.1774 +@@ -452,7 +495,7 @@ static COLUMN *column_vector;
 72.1775 +    we store the leftmost columns contiguously in buff.
 72.1776 +    To print a line from buff, get the index of the first character
 72.1777 +    from line_vector[i], and print up to line_vector[i + 1]. */
 72.1778 +-static char *buff;
 72.1779 ++static unsigned char *buff;
 72.1780 + 
 72.1781 + /* Index of the position in buff where the next character
 72.1782 +    will be stored. */
 72.1783 +@@ -556,7 +599,7 @@ static int chars_per_column;
 72.1784 + static bool untabify_input = false;
 72.1785 + 
 72.1786 + /* (-e) The input tab character. */
 72.1787 +-static char input_tab_char = '\t';
 72.1788 ++static char input_tab_char[MB_LEN_MAX] = "\t";
 72.1789 + 
 72.1790 + /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ...
 72.1791 +    where the leftmost column is 1. */
 72.1792 +@@ -566,7 +609,10 @@ static int chars_per_input_tab = 8;
 72.1793 + static bool tabify_output = false;
 72.1794 + 
 72.1795 + /* (-i) The output tab character. */
 72.1796 +-static char output_tab_char = '\t';
 72.1797 ++static char output_tab_char[MB_LEN_MAX] = "\t";
 72.1798 ++
 72.1799 ++/* (-i) The byte length of output tab character. */
 72.1800 ++static int output_tab_char_length = 1;
 72.1801 + 
 72.1802 + /* (-i) The width of the output tab. */
 72.1803 + static int chars_per_output_tab = 8;
 72.1804 +@@ -636,7 +682,13 @@ static int line_number;
 72.1805 + static bool numbered_lines = false;
 72.1806 + 
 72.1807 + /* (-n) Character which follows each line number. */
 72.1808 +-static char number_separator = '\t';
 72.1809 ++static char number_separator[MB_LEN_MAX] = "\t";
 72.1810 ++
 72.1811 ++/* (-n) The byte length of the character which follows each line number. */
 72.1812 ++static int number_separator_length = 1;
 72.1813 ++
 72.1814 ++/* (-n) The character width of the character which follows each line number. */
 72.1815 ++static int number_separator_width = 0;
 72.1816 + 
 72.1817 + /* (-n) line counting starts with 1st line of input file (not with 1st
 72.1818 +    line of 1st page printed). */
 72.1819 +@@ -689,6 +741,7 @@ static bool use_col_separator = false;
 72.1820 +    -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */
 72.1821 + static char *col_sep_string = (char *) "";
 72.1822 + static int col_sep_length = 0;
 72.1823 ++static int col_sep_width = 0;
 72.1824 + static char *column_separator = (char *) " ";
 72.1825 + static char *line_separator = (char *) "\t";
 72.1826 + 
 72.1827 +@@ -839,6 +892,13 @@ separator_string (const char *optarg_S)
 72.1828 +   col_sep_length = (int) strlen (optarg_S);
 72.1829 +   col_sep_string = xmalloc (col_sep_length + 1);
 72.1830 +   strcpy (col_sep_string, optarg_S);
 72.1831 ++
 72.1832 ++#if HAVE_MBRTOWC
 72.1833 ++  if (MB_CUR_MAX > 1)
 72.1834 ++    col_sep_width = mbswidth (col_sep_string, 0);
 72.1835 ++  else
 72.1836 ++#endif
 72.1837 ++    col_sep_width = col_sep_length;
 72.1838 + }
 72.1839 + 
 72.1840 + int
 72.1841 +@@ -863,6 +923,21 @@ main (int argc, char **argv)
 72.1842 + 
 72.1843 +   atexit (close_stdout);
 72.1844 + 
 72.1845 ++/* Define which functions are used, the ones for single byte locale or the ones
 72.1846 ++   for multibyte locale. */
 72.1847 ++#if HAVE_MBRTOWC
 72.1848 ++  if (MB_CUR_MAX > 1)
 72.1849 ++    {
 72.1850 ++      print_char = print_char_multi;
 72.1851 ++      char_to_clump = char_to_clump_multi;
 72.1852 ++    }
 72.1853 ++  else
 72.1854 ++#endif
 72.1855 ++    {
 72.1856 ++      print_char = print_char_single;
 72.1857 ++      char_to_clump = char_to_clump_single;
 72.1858 ++    }
 72.1859 ++
 72.1860 +   n_files = 0;
 72.1861 +   file_names = (argc > 1
 72.1862 +                 ? xmalloc ((argc - 1) * sizeof (char *))
 72.1863 +@@ -939,8 +1014,12 @@ main (int argc, char **argv)
 72.1864 +           break;
 72.1865 +         case 'e':
 72.1866 +           if (optarg)
 72.1867 +-            getoptarg (optarg, 'e', &input_tab_char,
 72.1868 +-                       &chars_per_input_tab);
 72.1869 ++            {
 72.1870 ++              int dummy_length, dummy_width;
 72.1871 ++
 72.1872 ++              getoptarg (optarg, 'e', input_tab_char, &dummy_length,
 72.1873 ++                         &dummy_width, &chars_per_input_tab);
 72.1874 ++            }
 72.1875 +           /* Could check tab width > 0. */
 72.1876 +           untabify_input = true;
 72.1877 +           break;
 72.1878 +@@ -953,8 +1032,12 @@ main (int argc, char **argv)
 72.1879 +           break;
 72.1880 +         case 'i':
 72.1881 +           if (optarg)
 72.1882 +-            getoptarg (optarg, 'i', &output_tab_char,
 72.1883 +-                       &chars_per_output_tab);
 72.1884 ++            {
 72.1885 ++              int dummy_width;
 72.1886 ++
 72.1887 ++              getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length,
 72.1888 ++                         &dummy_width, &chars_per_output_tab);
 72.1889 ++            }
 72.1890 +           /* Could check tab width > 0. */
 72.1891 +           tabify_output = true;
 72.1892 +           break;
 72.1893 +@@ -972,8 +1055,8 @@ main (int argc, char **argv)
 72.1894 +         case 'n':
 72.1895 +           numbered_lines = true;
 72.1896 +           if (optarg)
 72.1897 +-            getoptarg (optarg, 'n', &number_separator,
 72.1898 +-                       &chars_per_number);
 72.1899 ++            getoptarg (optarg, 'n', number_separator, &number_separator_length,
 72.1900 ++                       &number_separator_width, &chars_per_number);
 72.1901 +           break;
 72.1902 +         case 'N':
 72.1903 +           skip_count = false;
 72.1904 +@@ -997,7 +1080,7 @@ main (int argc, char **argv)
 72.1905 +           old_s = false;
 72.1906 +           /* Reset an additional input of -s, -S dominates -s */
 72.1907 +           col_sep_string = bad_cast ("");
 72.1908 +-          col_sep_length = 0;
 72.1909 ++          col_sep_length = col_sep_width = 0;
 72.1910 +           use_col_separator = true;
 72.1911 +           if (optarg)
 72.1912 +             separator_string (optarg);
 72.1913 +@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, i
 72.1914 +    a number. */
 72.1915 + 
 72.1916 + static void
 72.1917 +-getoptarg (char *arg, char switch_char, char *character, int *number)
 72.1918 ++getoptarg (char *arg, char switch_char, char *character, int *character_length,
 72.1919 ++           int *character_width, int *number)
 72.1920 + {
 72.1921 +   if (!ISDIGIT (*arg))
 72.1922 +-    *character = *arg++;
 72.1923 ++    {
 72.1924 ++#ifdef HAVE_MBRTOWC
 72.1925 ++      if (MB_CUR_MAX > 1)        /* for multibyte locale. */
 72.1926 ++        {
 72.1927 ++          wchar_t wc;
 72.1928 ++          size_t mblength;
 72.1929 ++          int width;
 72.1930 ++          mbstate_t state = {'\0'};
 72.1931 ++
 72.1932 ++          mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state);
 72.1933 ++
 72.1934 ++          if (mblength == (size_t)-1 || mblength == (size_t)-2)
 72.1935 ++            {
 72.1936 ++              *character_length = 1;
 72.1937 ++              *character_width = 1;
 72.1938 ++            }
 72.1939 ++          else
 72.1940 ++            {
 72.1941 ++              *character_length = (mblength < 1) ? 1 : mblength;
 72.1942 ++              width = wcwidth (wc);
 72.1943 ++              *character_width = (width < 0) ? 0 : width;
 72.1944 ++            }
 72.1945 ++
 72.1946 ++          strncpy (character, arg, *character_length);
 72.1947 ++          arg += *character_length;
 72.1948 ++        }
 72.1949 ++      else                        /* for single byte locale. */
 72.1950 ++#endif
 72.1951 ++        {
 72.1952 ++          *character = *arg++;
 72.1953 ++          *character_length = 1;
 72.1954 ++          *character_width = 1;
 72.1955 ++        }
 72.1956 ++    }
 72.1957 ++
 72.1958 +   if (*arg)
 72.1959 +     {
 72.1960 +       long int tmp_long;
 72.1961 +@@ -1177,6 +1295,11 @@ static void
 72.1962 + init_parameters (int number_of_files)
 72.1963 + {
 72.1964 +   int chars_used_by_number = 0;
 72.1965 ++  int mb_len = 1;
 72.1966 ++#if HAVE_MBRTOWC
 72.1967 ++  if (MB_CUR_MAX > 1)
 72.1968 ++    mb_len = MB_LEN_MAX;
 72.1969 ++#endif
 72.1970 + 
 72.1971 +   lines_per_body = lines_per_page - lines_per_header - lines_per_footer;
 72.1972 +   if (lines_per_body <= 0)
 72.1973 +@@ -1214,7 +1337,7 @@ init_parameters (int number_of_files)
 72.1974 +           else
 72.1975 +             col_sep_string = column_separator;
 72.1976 + 
 72.1977 +-          col_sep_length = 1;
 72.1978 ++          col_sep_length = col_sep_width = 1;
 72.1979 +           use_col_separator = true;
 72.1980 +         }
 72.1981 +       /* It's rather pointless to define a TAB separator with column
 72.1982 +@@ -1244,11 +1367,11 @@ init_parameters (int number_of_files)
 72.1983 +              + TAB_WIDTH (chars_per_input_tab, chars_per_number);   */
 72.1984 + 
 72.1985 +       /* Estimate chars_per_text without any margin and keep it constant. */
 72.1986 +-      if (number_separator == '\t')
 72.1987 ++      if (number_separator[0] == '\t')
 72.1988 +         number_width = (chars_per_number
 72.1989 +                         + TAB_WIDTH (chars_per_default_tab, chars_per_number));
 72.1990 +       else
 72.1991 +-        number_width = chars_per_number + 1;
 72.1992 ++        number_width = chars_per_number + number_separator_width;
 72.1993 + 
 72.1994 +       /* The number is part of the column width unless we are
 72.1995 +          printing files in parallel. */
 72.1996 +@@ -1257,7 +1380,7 @@ init_parameters (int number_of_files)
 72.1997 +     }
 72.1998 + 
 72.1999 +   chars_per_column = (chars_per_line - chars_used_by_number
 72.2000 +-                      - (columns - 1) * col_sep_length) / columns;
 72.2001 ++                      - (columns - 1) * col_sep_width) / columns;
 72.2002 + 
 72.2003 +   if (chars_per_column < 1)
 72.2004 +     error (EXIT_FAILURE, 0, _("page width too narrow"));
 72.2005 +@@ -1275,7 +1398,7 @@ init_parameters (int number_of_files)
 72.2006 +      We've to use 8 as the lower limit, if we use chars_per_default_tab = 8
 72.2007 +      to expand a tab which is not an input_tab-char. */
 72.2008 +   free (clump_buff);
 72.2009 +-  clump_buff = xmalloc (MAX (8, chars_per_input_tab));
 72.2010 ++  clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab));
 72.2011 + }
 72.2012 + 
 72.2013 + /* Open the necessary files,
 72.2014 +@@ -1383,7 +1506,7 @@ init_funcs (void)
 72.2015 + 
 72.2016 +   /* Enlarge p->start_position of first column to use the same form of
 72.2017 +      padding_not_printed with all columns. */
 72.2018 +-  h = h + col_sep_length;
 72.2019 ++  h = h + col_sep_width;
 72.2020 + 
 72.2021 +   /* This loop takes care of all but the rightmost column. */
 72.2022 + 
 72.2023 +@@ -1417,7 +1540,7 @@ init_funcs (void)
 72.2024 +         }
 72.2025 +       else
 72.2026 +         {
 72.2027 +-          h = h_next + col_sep_length;
 72.2028 ++          h = h_next + col_sep_width;
 72.2029 +           h_next = h + chars_per_column;
 72.2030 +         }
 72.2031 +     }
 72.2032 +@@ -1708,9 +1831,9 @@ static void
 72.2033 + align_column (COLUMN *p)
 72.2034 + {
 72.2035 +   padding_not_printed = p->start_position;
 72.2036 +-  if (padding_not_printed - col_sep_length > 0)
 72.2037 ++  if (padding_not_printed - col_sep_width > 0)
 72.2038 +     {
 72.2039 +-      pad_across_to (padding_not_printed - col_sep_length);
 72.2040 ++      pad_across_to (padding_not_printed - col_sep_width);
 72.2041 +       padding_not_printed = ANYWHERE;
 72.2042 +     }
 72.2043 + 
 72.2044 +@@ -1981,13 +2104,13 @@ store_char (char c)
 72.2045 +       /* May be too generous. */
 72.2046 +       buff = X2REALLOC (buff, &buff_allocated);
 72.2047 +     }
 72.2048 +-  buff[buff_current++] = c;
 72.2049 ++  buff[buff_current++] = (unsigned char) c;
 72.2050 + }
 72.2051 + 
 72.2052 + static void
 72.2053 + add_line_number (COLUMN *p)
 72.2054 + {
 72.2055 +-  int i;
 72.2056 ++  int i, j;
 72.2057 +   char *s;
 72.2058 +   int num_width;
 72.2059 + 
 72.2060 +@@ -2004,22 +2127,24 @@ add_line_number (COLUMN *p)
 72.2061 +       /* Tabification is assumed for multiple columns, also for n-separators,
 72.2062 +          but 'default n-separator = TAB' hasn't been given priority over
 72.2063 +          equal column_width also specified by POSIX. */
 72.2064 +-      if (number_separator == '\t')
 72.2065 ++      if (number_separator[0] == '\t')
 72.2066 +         {
 72.2067 +           i = number_width - chars_per_number;
 72.2068 +           while (i-- > 0)
 72.2069 +             (p->char_func) (' ');
 72.2070 +         }
 72.2071 +       else
 72.2072 +-        (p->char_func) (number_separator);
 72.2073 ++        for (j = 0; j < number_separator_length; j++)
 72.2074 ++          (p->char_func) (number_separator[j]);
 72.2075 +     }
 72.2076 +   else
 72.2077 +     /* To comply with POSIX, we avoid any expansion of default TAB
 72.2078 +        separator with a single column output. No column_width requirement
 72.2079 +        has to be considered. */
 72.2080 +     {
 72.2081 +-      (p->char_func) (number_separator);
 72.2082 +-      if (number_separator == '\t')
 72.2083 ++      for (j = 0; j < number_separator_length; j++)
 72.2084 ++        (p->char_func) (number_separator[j]);
 72.2085 ++      if (number_separator[0] == '\t')
 72.2086 +         output_position = POS_AFTER_TAB (chars_per_output_tab,
 72.2087 +                           output_position);
 72.2088 +     }
 72.2089 +@@ -2180,7 +2305,7 @@ print_white_space (void)
 72.2090 +   while (goal - h_old > 1
 72.2091 +          && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal)
 72.2092 +     {
 72.2093 +-      putchar (output_tab_char);
 72.2094 ++      fwrite (output_tab_char, sizeof(char), output_tab_char_length, stdout);
 72.2095 +       h_old = h_new;
 72.2096 +     }
 72.2097 +   while (++h_old <= goal)
 72.2098 +@@ -2200,6 +2325,7 @@ print_sep_string (void)
 72.2099 + {
 72.2100 +   char *s;
 72.2101 +   int l = col_sep_length;
 72.2102 ++  int not_space_flag;
 72.2103 + 
 72.2104 +   s = col_sep_string;
 72.2105 + 
 72.2106 +@@ -2213,6 +2339,7 @@ print_sep_string (void)
 72.2107 +     {
 72.2108 +       for (; separators_not_printed > 0; --separators_not_printed)
 72.2109 +         {
 72.2110 ++          not_space_flag = 0;
 72.2111 +           while (l-- > 0)
 72.2112 +             {
 72.2113 +               /* 3 types of sep_strings: spaces only, spaces and chars,
 72.2114 +@@ -2226,12 +2353,15 @@ print_sep_string (void)
 72.2115 +                 }
 72.2116 +               else
 72.2117 +                 {
 72.2118 ++                  not_space_flag = 1;
 72.2119 +                   if (spaces_not_printed > 0)
 72.2120 +                     print_white_space ();
 72.2121 +                   putchar (*s++);
 72.2122 +-                  ++output_position;
 72.2123 +                 }
 72.2124 +             }
 72.2125 ++          if (not_space_flag)
 72.2126 ++            output_position += col_sep_width;
 72.2127 ++
 72.2128 +           /* sep_string ends with some spaces */
 72.2129 +           if (spaces_not_printed > 0)
 72.2130 +             print_white_space ();
 72.2131 +@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clu
 72.2132 +    required number of tabs and spaces. */
 72.2133 + 
 72.2134 + static void
 72.2135 +-print_char (char c)
 72.2136 ++print_char_single (char c)
 72.2137 + {
 72.2138 +   if (tabify_output)
 72.2139 +     {
 72.2140 +@@ -2283,6 +2413,74 @@ print_char (char c)
 72.2141 +   putchar (c);
 72.2142 + }
 72.2143 + 
 72.2144 ++#ifdef HAVE_MBRTOWC
 72.2145 ++static void
 72.2146 ++print_char_multi (char c)
 72.2147 ++{
 72.2148 ++  static size_t mbc_pos = 0;
 72.2149 ++  static char mbc[MB_LEN_MAX] = {'\0'};
 72.2150 ++  static mbstate_t state = {'\0'};
 72.2151 ++  mbstate_t state_bak;
 72.2152 ++  wchar_t wc;
 72.2153 ++  size_t mblength;
 72.2154 ++  int width;
 72.2155 ++
 72.2156 ++  if (tabify_output)
 72.2157 ++    {
 72.2158 ++      state_bak = state;
 72.2159 ++      mbc[mbc_pos++] = c;
 72.2160 ++      mblength = mbrtowc (&wc, mbc, mbc_pos, &state);
 72.2161 ++
 72.2162 ++      while (mbc_pos > 0)
 72.2163 ++        {
 72.2164 ++          switch (mblength)
 72.2165 ++            {
 72.2166 ++            case (size_t)-2:
 72.2167 ++              state = state_bak;
 72.2168 ++              return;
 72.2169 ++
 72.2170 ++            case (size_t)-1:
 72.2171 ++              state = state_bak;
 72.2172 ++              ++output_position;
 72.2173 ++              putchar (mbc[0]);
 72.2174 ++              memmove (mbc, mbc + 1, MB_CUR_MAX - 1);
 72.2175 ++              --mbc_pos;
 72.2176 ++              break;
 72.2177 ++
 72.2178 ++            case 0:
 72.2179 ++              mblength = 1;
 72.2180 ++
 72.2181 ++            default:
 72.2182 ++              if (wc == L' ')
 72.2183 ++                {
 72.2184 ++                  memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength);
 72.2185 ++                  --mbc_pos;
 72.2186 ++                  ++spaces_not_printed;
 72.2187 ++                  return;
 72.2188 ++                }
 72.2189 ++              else if (spaces_not_printed > 0)
 72.2190 ++                print_white_space ();
 72.2191 ++
 72.2192 ++              /* Nonprintables are assumed to have width 0, except L'\b'. */
 72.2193 ++              if ((width = wcwidth (wc)) < 1)
 72.2194 ++                {
 72.2195 ++                  if (wc == L'\b')
 72.2196 ++                    --output_position;
 72.2197 ++                }
 72.2198 ++              else
 72.2199 ++                output_position += width;
 72.2200 ++
 72.2201 ++              fwrite (mbc, sizeof(char), mblength, stdout);
 72.2202 ++              memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength);
 72.2203 ++              mbc_pos -= mblength;
 72.2204 ++            }
 72.2205 ++        }
 72.2206 ++      return;
 72.2207 ++    }
 72.2208 ++  putchar (c);
 72.2209 ++}
 72.2210 ++#endif
 72.2211 ++
 72.2212 + /* Skip to page PAGE before printing.
 72.2213 +    PAGE may be larger than total number of pages. */
 72.2214 + 
 72.2215 +@@ -2462,9 +2660,9 @@ read_line (COLUMN *p)
 72.2216 +           align_empty_cols = false;
 72.2217 +         }
 72.2218 + 
 72.2219 +-      if (padding_not_printed - col_sep_length > 0)
 72.2220 ++      if (padding_not_printed - col_sep_width > 0)
 72.2221 +         {
 72.2222 +-          pad_across_to (padding_not_printed - col_sep_length);
 72.2223 ++          pad_across_to (padding_not_printed - col_sep_width);
 72.2224 +           padding_not_printed = ANYWHERE;
 72.2225 +         }
 72.2226 + 
 72.2227 +@@ -2534,7 +2732,7 @@ print_stored (COLUMN *p)
 72.2228 +   int i;
 72.2229 + 
 72.2230 +   int line = p->current_line++;
 72.2231 +-  char *first = &buff[line_vector[line]];
 72.2232 ++  unsigned char *first = &buff[line_vector[line]];
 72.2233 +   /* FIXME
 72.2234 +      UMR: Uninitialized memory read:
 72.2235 +      * This is occurring while in:
 72.2236 +@@ -2546,7 +2744,7 @@ print_stored (COLUMN *p)
 72.2237 +      xmalloc        [xmalloc.c:94]
 72.2238 +      init_store_cols [pr.c:1648]
 72.2239 +      */
 72.2240 +-  char *last = &buff[line_vector[line + 1]];
 72.2241 ++  unsigned char *last = &buff[line_vector[line + 1]];
 72.2242 + 
 72.2243 +   pad_vertically = true;
 72.2244 + 
 72.2245 +@@ -2565,9 +2763,9 @@ print_stored (COLUMN *p)
 72.2246 +         }
 72.2247 +     }
 72.2248 + 
 72.2249 +-  if (padding_not_printed - col_sep_length > 0)
 72.2250 ++  if (padding_not_printed - col_sep_width > 0)
 72.2251 +     {
 72.2252 +-      pad_across_to (padding_not_printed - col_sep_length);
 72.2253 ++      pad_across_to (padding_not_printed - col_sep_width);
 72.2254 +       padding_not_printed = ANYWHERE;
 72.2255 +     }
 72.2256 + 
 72.2257 +@@ -2580,8 +2778,8 @@ print_stored (COLUMN *p)
 72.2258 +   if (spaces_not_printed == 0)
 72.2259 +     {
 72.2260 +       output_position = p->start_position + end_vector[line];
 72.2261 +-      if (p->start_position - col_sep_length == chars_per_margin)
 72.2262 +-        output_position -= col_sep_length;
 72.2263 ++      if (p->start_position - col_sep_width == chars_per_margin)
 72.2264 ++        output_position -= col_sep_width;
 72.2265 +     }
 72.2266 + 
 72.2267 +   return true;
 72.2268 +@@ -2600,7 +2798,7 @@ print_stored (COLUMN *p)
 72.2269 +    number of characters is 1.) */
 72.2270 + 
 72.2271 + static int
 72.2272 +-char_to_clump (char c)
 72.2273 ++char_to_clump_single (char c)
 72.2274 + {
 72.2275 +   unsigned char uc = c;
 72.2276 +   char *s = clump_buff;
 72.2277 +@@ -2610,10 +2808,10 @@ char_to_clump (char c)
 72.2278 +   int chars;
 72.2279 +   int chars_per_c = 8;
 72.2280 + 
 72.2281 +-  if (c == input_tab_char)
 72.2282 ++  if (c == input_tab_char[0])
 72.2283 +     chars_per_c = chars_per_input_tab;
 72.2284 + 
 72.2285 +-  if (c == input_tab_char || c == '\t')
 72.2286 ++  if (c == input_tab_char[0] || c == '\t')
 72.2287 +     {
 72.2288 +       width = TAB_WIDTH (chars_per_c, input_position);
 72.2289 + 
 72.2290 +@@ -2694,6 +2892,164 @@ char_to_clump (char c)
 72.2291 +   return chars;
 72.2292 + }
 72.2293 + 
 72.2294 ++#ifdef HAVE_MBRTOWC
 72.2295 ++static int
 72.2296 ++char_to_clump_multi (char c)
 72.2297 ++{
 72.2298 ++  static size_t mbc_pos = 0;
 72.2299 ++  static char mbc[MB_LEN_MAX] = {'\0'};
 72.2300 ++  static mbstate_t state = {'\0'};
 72.2301 ++  mbstate_t state_bak;
 72.2302 ++  wchar_t wc;
 72.2303 ++  size_t mblength;
 72.2304 ++  int wc_width;
 72.2305 ++  register char *s = clump_buff;
 72.2306 ++  register int i, j;
 72.2307 ++  char esc_buff[4];
 72.2308 ++  int width;
 72.2309 ++  int chars;
 72.2310 ++  int chars_per_c = 8;
 72.2311 ++
 72.2312 ++  state_bak = state;
 72.2313 ++  mbc[mbc_pos++] = c;
 72.2314 ++  mblength = mbrtowc (&wc, mbc, mbc_pos, &state);
 72.2315 ++
 72.2316 ++  width = 0;
 72.2317 ++  chars = 0;
 72.2318 ++  while (mbc_pos > 0)
 72.2319 ++    {
 72.2320 ++      switch (mblength)
 72.2321 ++        {
 72.2322 ++        case (size_t)-2:
 72.2323 ++          state = state_bak;
 72.2324 ++          return 0;
 72.2325 ++
 72.2326 ++        case (size_t)-1:
 72.2327 ++          state = state_bak;
 72.2328 ++          mblength = 1;
 72.2329 ++
 72.2330 ++          if (use_esc_sequence || use_cntrl_prefix)
 72.2331 ++            {
 72.2332 ++              width = +4;
 72.2333 ++              chars = +4;
 72.2334 ++              *s++ = '\\';
 72.2335 ++              sprintf (esc_buff, "%03o", (unsigned char) mbc[0]);
 72.2336 ++              for (i = 0; i <= 2; ++i)
 72.2337 ++                *s++ = (int) esc_buff[i];
 72.2338 ++            }
 72.2339 ++          else
 72.2340 ++            {
 72.2341 ++              width += 1;
 72.2342 ++              chars += 1;
 72.2343 ++              *s++ = mbc[0];
 72.2344 ++            }
 72.2345 ++          break;
 72.2346 ++
 72.2347 ++        case 0:
 72.2348 ++          mblength = 1;
 72.2349 ++                /* Fall through */
 72.2350 ++
 72.2351 ++        default:
 72.2352 ++          if (memcmp (mbc, input_tab_char, mblength) == 0)
 72.2353 ++            chars_per_c = chars_per_input_tab;
 72.2354 ++
 72.2355 ++          if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t')
 72.2356 ++            {
 72.2357 ++              int  width_inc;
 72.2358 ++
 72.2359 ++              width_inc = TAB_WIDTH (chars_per_c, input_position);
 72.2360 ++              width += width_inc;
 72.2361 ++
 72.2362 ++              if (untabify_input)
 72.2363 ++                {
 72.2364 ++                  for (i = width_inc; i; --i)
 72.2365 ++                    *s++ = ' ';
 72.2366 ++                  chars += width_inc;
 72.2367 ++                }
 72.2368 ++              else
 72.2369 ++                {
 72.2370 ++                  for (i = 0; i <  mblength; i++)
 72.2371 ++                    *s++ = mbc[i];
 72.2372 ++                  chars += mblength;
 72.2373 ++                }
 72.2374 ++            }
 72.2375 ++          else if ((wc_width = wcwidth (wc)) < 1)
 72.2376 ++            {
 72.2377 ++              if (use_esc_sequence)
 72.2378 ++                {
 72.2379 ++                  for (i = 0; i < mblength; i++)
 72.2380 ++                    {
 72.2381 ++                      width += 4;
 72.2382 ++                      chars += 4;
 72.2383 ++                      *s++ = '\\';
 72.2384 ++                      sprintf (esc_buff, "%03o", (unsigned char) mbc[i]);
 72.2385 ++                      for (j = 0; j <= 2; ++j)
 72.2386 ++                        *s++ = (int) esc_buff[j];
 72.2387 ++                    }
 72.2388 ++                }
 72.2389 ++              else if (use_cntrl_prefix)
 72.2390 ++                {
 72.2391 ++                  if (wc < 0200)
 72.2392 ++                    {
 72.2393 ++                      width += 2;
 72.2394 ++                      chars += 2;
 72.2395 ++                      *s++ = '^';
 72.2396 ++                      *s++ = wc ^ 0100;
 72.2397 ++                    }
 72.2398 ++                  else
 72.2399 ++                    {
 72.2400 ++                      for (i = 0; i < mblength; i++)
 72.2401 ++                        {
 72.2402 ++                          width += 4;
 72.2403 ++                          chars += 4;
 72.2404 ++                          *s++ = '\\';
 72.2405 ++                          sprintf (esc_buff, "%03o", (unsigned char) mbc[i]);
 72.2406 ++                          for (j = 0; j <= 2; ++j)
 72.2407 ++                            *s++ = (int) esc_buff[j];
 72.2408 ++                        }
 72.2409 ++                    }
 72.2410 ++                }
 72.2411 ++              else if (wc == L'\b')
 72.2412 ++                {
 72.2413 ++                  width += -1;
 72.2414 ++                  chars += 1;
 72.2415 ++                  *s++ = c;
 72.2416 ++                }
 72.2417 ++              else
 72.2418 ++                {
 72.2419 ++                  width += 0;
 72.2420 ++                  chars += mblength;
 72.2421 ++                  for (i = 0; i < mblength; i++)
 72.2422 ++                    *s++ = mbc[i];
 72.2423 ++                }
 72.2424 ++            }
 72.2425 ++          else
 72.2426 ++            {
 72.2427 ++              width += wc_width;
 72.2428 ++              chars += mblength;
 72.2429 ++              for (i = 0; i < mblength; i++)
 72.2430 ++                *s++ = mbc[i];
 72.2431 ++            }
 72.2432 ++        }
 72.2433 ++      memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength);
 72.2434 ++      mbc_pos -= mblength;
 72.2435 ++    }
 72.2436 ++
 72.2437 ++  /* Too many backspaces must put us in position 0 -- never negative. */
 72.2438 ++  if (width < 0 && input_position == 0)
 72.2439 ++    {
 72.2440 ++      chars = 0;
 72.2441 ++      input_position = 0;
 72.2442 ++    }
 72.2443 ++  else if (width < 0 && input_position <= -width)
 72.2444 ++    input_position = 0;
 72.2445 ++  else
 72.2446 ++   input_position += width;
 72.2447 ++
 72.2448 ++  return chars;
 72.2449 ++}
 72.2450 ++#endif
 72.2451 ++
 72.2452 + /* We've just printed some files and need to clean up things before
 72.2453 +    looking for more options and printing the next batch of files.
 72.2454 + 
 72.2455 +diff -Naurp coreutils-8.25-orig/src/sort.c coreutils-8.25/src/sort.c
 72.2456 +--- coreutils-8.25-orig/src/sort.c	2016-01-16 13:09:33.000000000 -0600
 72.2457 ++++ coreutils-8.25/src/sort.c	2016-02-08 19:07:10.310944648 -0600
 72.2458 +@@ -29,6 +29,14 @@
 72.2459 + #include <sys/wait.h>
 72.2460 + #include <signal.h>
 72.2461 + #include <assert.h>
 72.2462 ++#if HAVE_WCHAR_H
 72.2463 ++# include <wchar.h>
 72.2464 ++#endif
 72.2465 ++/* Get isw* functions. */
 72.2466 ++#if HAVE_WCTYPE_H
 72.2467 ++# include <wctype.h>
 72.2468 ++#endif
 72.2469 ++
 72.2470 + #include "system.h"
 72.2471 + #include "argmatch.h"
 72.2472 + #include "error.h"
 72.2473 +@@ -163,14 +171,39 @@ static int decimal_point;
 72.2474 + /* Thousands separator; if -1, then there isn't one.  */
 72.2475 + static int thousands_sep;
 72.2476 + 
 72.2477 ++/* True if -f is specified.  */
 72.2478 ++static bool folding;
 72.2479 ++
 72.2480 + /* Nonzero if the corresponding locales are hard.  */
 72.2481 + static bool hard_LC_COLLATE;
 72.2482 +-#if HAVE_NL_LANGINFO
 72.2483 ++#if HAVE_LANGINFO_CODESET
 72.2484 + static bool hard_LC_TIME;
 72.2485 + #endif
 72.2486 + 
 72.2487 + #define NONZERO(x) ((x) != 0)
 72.2488 + 
 72.2489 ++/* get a multibyte character's byte length. */
 72.2490 ++#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE)                        \
 72.2491 ++  do                                                                        \
 72.2492 ++    {                                                                        \
 72.2493 ++      wchar_t wc;                                                        \
 72.2494 ++      mbstate_t state_bak;                                                \
 72.2495 ++                                                                        \
 72.2496 ++      state_bak = STATE;                                                \
 72.2497 ++      mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE);                        \
 72.2498 ++                                                                        \
 72.2499 ++      switch (MBLENGTH)                                                        \
 72.2500 ++        {                                                                \
 72.2501 ++        case (size_t)-1:                                                \
 72.2502 ++        case (size_t)-2:                                                \
 72.2503 ++          STATE = state_bak;                                                \
 72.2504 ++                /* Fall through. */                                        \
 72.2505 ++        case 0:                                                                \
 72.2506 ++          MBLENGTH = 1;                                                        \
 72.2507 ++      }                                                                        \
 72.2508 ++    }                                                                        \
 72.2509 ++  while (0)
 72.2510 ++
 72.2511 + /* The kind of blanks for '-b' to skip in various options. */
 72.2512 + enum blanktype { bl_start, bl_end, bl_both };
 72.2513 + 
 72.2514 +@@ -344,13 +377,11 @@ static bool reverse;
 72.2515 +    they were read if all keys compare equal.  */
 72.2516 + static bool stable;
 72.2517 + 
 72.2518 +-/* If TAB has this value, blanks separate fields.  */
 72.2519 +-enum { TAB_DEFAULT = CHAR_MAX + 1 };
 72.2520 +-
 72.2521 +-/* Tab character separating fields.  If TAB_DEFAULT, then fields are
 72.2522 ++/* Tab character separating fields.  If tab_length is 0, then fields are
 72.2523 +    separated by the empty string between a non-blank character and a blank
 72.2524 +    character. */
 72.2525 +-static int tab = TAB_DEFAULT;
 72.2526 ++static char tab[MB_LEN_MAX + 1];
 72.2527 ++static size_t tab_length = 0;
 72.2528 + 
 72.2529 + /* Flag to remove consecutive duplicate lines from the output.
 72.2530 +    Only the last of a sequence of equal lines will be output. */
 72.2531 +@@ -810,6 +841,46 @@ reap_all (void)
 72.2532 +     reap (-1);
 72.2533 + }
 72.2534 + 
 72.2535 ++/* Function pointers. */
 72.2536 ++static void
 72.2537 ++(*inittables) (void);
 72.2538 ++static char *
 72.2539 ++(*begfield) (const struct line*, const struct keyfield *);
 72.2540 ++static char *
 72.2541 ++(*limfield) (const struct line*, const struct keyfield *);
 72.2542 ++static void
 72.2543 ++(*skipblanks) (char **ptr, char *lim);
 72.2544 ++static int
 72.2545 ++(*getmonth) (char const *, size_t, char **);
 72.2546 ++static int
 72.2547 ++(*keycompare) (const struct line *, const struct line *);
 72.2548 ++static int
 72.2549 ++(*numcompare) (const char *, const char *);
 72.2550 ++
 72.2551 ++/* Test for white space multibyte character.
 72.2552 ++   Set LENGTH the byte length of investigated multibyte character. */
 72.2553 ++#if HAVE_MBRTOWC
 72.2554 ++static int
 72.2555 ++ismbblank (const char *str, size_t len, size_t *length)
 72.2556 ++{
 72.2557 ++  size_t mblength;
 72.2558 ++  wchar_t wc;
 72.2559 ++  mbstate_t state;
 72.2560 ++
 72.2561 ++  memset (&state, '\0', sizeof(mbstate_t));
 72.2562 ++  mblength = mbrtowc (&wc, str, len, &state);
 72.2563 ++
 72.2564 ++  if (mblength == (size_t)-1 || mblength == (size_t)-2)
 72.2565 ++    {
 72.2566 ++      *length = 1;
 72.2567 ++      return 0;
 72.2568 ++    }
 72.2569 ++
 72.2570 ++  *length = (mblength < 1) ? 1 : mblength;
 72.2571 ++  return iswblank (wc) || wc == '\n';
 72.2572 ++}
 72.2573 ++#endif
 72.2574 ++
 72.2575 + /* Clean up any remaining temporary files.  */
 72.2576 + 
 72.2577 + static void
 72.2578 +@@ -1254,7 +1325,7 @@ zaptemp (char const *name)
 72.2579 +   free (node);
 72.2580 + }
 72.2581 + 
 72.2582 +-#if HAVE_NL_LANGINFO
 72.2583 ++#if HAVE_LANGINFO_CODESET
 72.2584 + 
 72.2585 + static int
 72.2586 + struct_month_cmp (void const *m1, void const *m2)
 72.2587 +@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void c
 72.2588 + /* Initialize the character class tables. */
 72.2589 + 
 72.2590 + static void
 72.2591 +-inittables (void)
 72.2592 ++inittables_uni (void)
 72.2593 + {
 72.2594 +   size_t i;
 72.2595 + 
 72.2596 +@@ -1281,7 +1352,7 @@ inittables (void)
 72.2597 +       fold_toupper[i] = toupper (i);
 72.2598 +     }
 72.2599 + 
 72.2600 +-#if HAVE_NL_LANGINFO
 72.2601 ++#if HAVE_LANGINFO_CODESET
 72.2602 +   /* If we're not in the "C" locale, read different names for months.  */
 72.2603 +   if (hard_LC_TIME)
 72.2604 +     {
 72.2605 +@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char con
 72.2606 +     xstrtol_fatal (e, oi, c, long_options, s);
 72.2607 + }
 72.2608 + 
 72.2609 ++#if HAVE_MBRTOWC
 72.2610 ++static void
 72.2611 ++inittables_mb (void)
 72.2612 ++{
 72.2613 ++  int i, j, k, l;
 72.2614 ++  char *name, *s, *lc_time, *lc_ctype;
 72.2615 ++  size_t s_len, mblength;
 72.2616 ++  char mbc[MB_LEN_MAX];
 72.2617 ++  wchar_t wc, pwc;
 72.2618 ++  mbstate_t state_mb, state_wc;
 72.2619 ++
 72.2620 ++  lc_time = setlocale (LC_TIME, "");
 72.2621 ++  if (lc_time)
 72.2622 ++    lc_time = xstrdup (lc_time);
 72.2623 ++
 72.2624 ++  lc_ctype = setlocale (LC_CTYPE, "");
 72.2625 ++  if (lc_ctype)
 72.2626 ++    lc_ctype = xstrdup (lc_ctype);
 72.2627 ++
 72.2628 ++  if (lc_time && lc_ctype)
 72.2629 ++    /* temporarily set LC_CTYPE to match LC_TIME, so that we can convert
 72.2630 ++     * the names of months to upper case */
 72.2631 ++    setlocale (LC_CTYPE, lc_time);
 72.2632 ++
 72.2633 ++  for (i = 0; i < MONTHS_PER_YEAR; i++)
 72.2634 ++    {
 72.2635 ++      s = (char *) nl_langinfo (ABMON_1 + i);
 72.2636 ++      s_len = strlen (s);
 72.2637 ++      monthtab[i].name = name = (char *) xmalloc (s_len + 1);
 72.2638 ++      monthtab[i].val = i + 1;
 72.2639 ++
 72.2640 ++      memset (&state_mb, '\0', sizeof (mbstate_t));
 72.2641 ++      memset (&state_wc, '\0', sizeof (mbstate_t));
 72.2642 ++
 72.2643 ++      for (j = 0; j < s_len;)
 72.2644 ++        {
 72.2645 ++          if (!ismbblank (s + j, s_len - j, &mblength))
 72.2646 ++            break;
 72.2647 ++          j += mblength;
 72.2648 ++        }
 72.2649 ++
 72.2650 ++      for (k = 0; j < s_len;)
 72.2651 ++        {
 72.2652 ++          mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb);
 72.2653 ++          assert (mblength != (size_t)-1 && mblength != (size_t)-2);
 72.2654 ++          if (mblength == 0)
 72.2655 ++            break;
 72.2656 ++
 72.2657 ++          pwc = towupper (wc);
 72.2658 ++          if (pwc == wc)
 72.2659 ++            {
 72.2660 ++              memcpy (mbc, s + j, mblength);
 72.2661 ++              j += mblength;
 72.2662 ++            }
 72.2663 ++          else
 72.2664 ++            {
 72.2665 ++              j += mblength;
 72.2666 ++              mblength = wcrtomb (mbc, pwc, &state_wc);
 72.2667 ++              assert (mblength != (size_t)0 && mblength != (size_t)-1);
 72.2668 ++            }
 72.2669 ++
 72.2670 ++          for (l = 0; l < mblength; l++)
 72.2671 ++            name[k++] = mbc[l];
 72.2672 ++        }
 72.2673 ++      name[k] = '\0';
 72.2674 ++    }
 72.2675 ++  qsort ((void *) monthtab, MONTHS_PER_YEAR,
 72.2676 ++      sizeof (struct month), struct_month_cmp);
 72.2677 ++
 72.2678 ++  if (lc_time && lc_ctype)
 72.2679 ++    /* restore the original locales */
 72.2680 ++    setlocale (LC_CTYPE, lc_ctype);
 72.2681 ++
 72.2682 ++  free (lc_ctype);
 72.2683 ++  free (lc_time);
 72.2684 ++}
 72.2685 ++#endif
 72.2686 ++
 72.2687 + /* Specify the amount of main memory to use when sorting.  */
 72.2688 + static void
 72.2689 + specify_sort_size (int oi, char c, char const *s)
 72.2690 +@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf
 72.2691 +    by KEY in LINE. */
 72.2692 + 
 72.2693 + static char *
 72.2694 +-begfield (struct line const *line, struct keyfield const *key)
 72.2695 ++begfield_uni (const struct line *line, const struct keyfield *key)
 72.2696 + {
 72.2697 +   char *ptr = line->text, *lim = ptr + line->length - 1;
 72.2698 +   size_t sword = key->sword;
 72.2699 +@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struc
 72.2700 +   /* The leading field separator itself is included in a field when -t
 72.2701 +      is absent.  */
 72.2702 + 
 72.2703 +-  if (tab != TAB_DEFAULT)
 72.2704 ++  if (tab_length)
 72.2705 +     while (ptr < lim && sword--)
 72.2706 +       {
 72.2707 +-        while (ptr < lim && *ptr != tab)
 72.2708 ++        while (ptr < lim && *ptr != tab[0])
 72.2709 +           ++ptr;
 72.2710 +         if (ptr < lim)
 72.2711 +           ++ptr;
 72.2712 +@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struc
 72.2713 +   return ptr;
 72.2714 + }
 72.2715 + 
 72.2716 ++#if HAVE_MBRTOWC
 72.2717 ++static char *
 72.2718 ++begfield_mb (const struct line *line, const struct keyfield *key)
 72.2719 ++{
 72.2720 ++  int i;
 72.2721 ++  char *ptr = line->text, *lim = ptr + line->length - 1;
 72.2722 ++  size_t sword = key->sword;
 72.2723 ++  size_t schar = key->schar;
 72.2724 ++  size_t mblength;
 72.2725 ++  mbstate_t state;
 72.2726 ++
 72.2727 ++  memset (&state, '\0', sizeof(mbstate_t));
 72.2728 ++
 72.2729 ++  if (tab_length)
 72.2730 ++    while (ptr < lim && sword--)
 72.2731 ++      {
 72.2732 ++        while (ptr < lim && memcmp (ptr, tab, tab_length) != 0)
 72.2733 ++          {
 72.2734 ++            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 72.2735 ++            ptr += mblength;
 72.2736 ++          }
 72.2737 ++        if (ptr < lim)
 72.2738 ++          {
 72.2739 ++            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 72.2740 ++            ptr += mblength;
 72.2741 ++          }
 72.2742 ++      }
 72.2743 ++  else
 72.2744 ++    while (ptr < lim && sword--)
 72.2745 ++      {
 72.2746 ++        while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
 72.2747 ++          ptr += mblength;
 72.2748 ++        if (ptr < lim)
 72.2749 ++          {
 72.2750 ++            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 72.2751 ++            ptr += mblength;
 72.2752 ++          }
 72.2753 ++        while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength))
 72.2754 ++          ptr += mblength;
 72.2755 ++      }
 72.2756 ++
 72.2757 ++  if (key->skipsblanks)
 72.2758 ++    while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
 72.2759 ++      ptr += mblength;
 72.2760 ++
 72.2761 ++  for (i = 0; i < schar; i++)
 72.2762 ++    {
 72.2763 ++      GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 72.2764 ++
 72.2765 ++      if (ptr + mblength > lim)
 72.2766 ++        break;
 72.2767 ++      else
 72.2768 ++        ptr += mblength;
 72.2769 ++    }
 72.2770 ++
 72.2771 ++  return ptr;
 72.2772 ++}
 72.2773 ++#endif
 72.2774 ++
 72.2775 + /* Return the limit of (a pointer to the first character after) the field
 72.2776 +    in LINE specified by KEY. */
 72.2777 + 
 72.2778 + static char *
 72.2779 +-limfield (struct line const *line, struct keyfield const *key)
 72.2780 ++limfield_uni (const struct line *line, const struct keyfield *key)
 72.2781 + {
 72.2782 +   char *ptr = line->text, *lim = ptr + line->length - 1;
 72.2783 +   size_t eword = key->eword, echar = key->echar;
 72.2784 +@@ -1653,10 +1861,10 @@ limfield (struct line const *line, struc
 72.2785 +      'beginning' is the first character following the delimiting TAB.
 72.2786 +      Otherwise, leave PTR pointing at the first 'blank' character after
 72.2787 +      the preceding field.  */
 72.2788 +-  if (tab != TAB_DEFAULT)
 72.2789 ++  if (tab_length)
 72.2790 +     while (ptr < lim && eword--)
 72.2791 +       {
 72.2792 +-        while (ptr < lim && *ptr != tab)
 72.2793 ++        while (ptr < lim && *ptr != tab[0])
 72.2794 +           ++ptr;
 72.2795 +         if (ptr < lim && (eword || echar))
 72.2796 +           ++ptr;
 72.2797 +@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struc
 72.2798 +      */
 72.2799 + 
 72.2800 +   /* Make LIM point to the end of (one byte past) the current field.  */
 72.2801 +-  if (tab != TAB_DEFAULT)
 72.2802 ++  if (tab_length)
 72.2803 +     {
 72.2804 +       char *newlim;
 72.2805 +-      newlim = memchr (ptr, tab, lim - ptr);
 72.2806 ++      newlim = memchr (ptr, tab[0], lim - ptr);
 72.2807 +       if (newlim)
 72.2808 +         lim = newlim;
 72.2809 +     }
 72.2810 +@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struc
 72.2811 +   return ptr;
 72.2812 + }
 72.2813 + 
 72.2814 ++#if HAVE_MBRTOWC
 72.2815 ++static char *
 72.2816 ++limfield_mb (const struct line *line, const struct keyfield *key)
 72.2817 ++{
 72.2818 ++  char *ptr = line->text, *lim = ptr + line->length - 1;
 72.2819 ++  size_t eword = key->eword, echar = key->echar;
 72.2820 ++  int i;
 72.2821 ++  size_t mblength;
 72.2822 ++  mbstate_t state;
 72.2823 ++
 72.2824 ++  if (echar == 0)
 72.2825 ++    eword++; /* skip all of end field. */
 72.2826 ++
 72.2827 ++  memset (&state, '\0', sizeof(mbstate_t));
 72.2828 ++
 72.2829 ++  if (tab_length)
 72.2830 ++    while (ptr < lim && eword--)
 72.2831 ++      {
 72.2832 ++        while (ptr < lim && memcmp (ptr, tab, tab_length) != 0)
 72.2833 ++          {
 72.2834 ++            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 72.2835 ++            ptr += mblength;
 72.2836 ++          }
 72.2837 ++        if (ptr < lim && (eword | echar))
 72.2838 ++          {
 72.2839 ++            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 72.2840 ++            ptr += mblength;
 72.2841 ++          }
 72.2842 ++      }
 72.2843 ++  else
 72.2844 ++    while (ptr < lim && eword--)
 72.2845 ++      {
 72.2846 ++        while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
 72.2847 ++          ptr += mblength;
 72.2848 ++        if (ptr < lim)
 72.2849 ++          {
 72.2850 ++            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 72.2851 ++            ptr += mblength;
 72.2852 ++          }
 72.2853 ++        while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength))
 72.2854 ++          ptr += mblength;
 72.2855 ++      }
 72.2856 ++
 72.2857 ++
 72.2858 ++# ifdef POSIX_UNSPECIFIED
 72.2859 ++  /* Make LIM point to the end of (one byte past) the current field.  */
 72.2860 ++  if (tab_length)
 72.2861 ++    {
 72.2862 ++      char *newlim, *p;
 72.2863 ++
 72.2864 ++      newlim = NULL;
 72.2865 ++      for (p = ptr; p < lim;)
 72.2866 ++         {
 72.2867 ++          if (memcmp (p, tab, tab_length) == 0)
 72.2868 ++            {
 72.2869 ++              newlim = p;
 72.2870 ++              break;
 72.2871 ++            }
 72.2872 ++
 72.2873 ++          GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 72.2874 ++          p += mblength;
 72.2875 ++        }
 72.2876 ++    }
 72.2877 ++  else
 72.2878 ++    {
 72.2879 ++      char *newlim;
 72.2880 ++      newlim = ptr;
 72.2881 ++
 72.2882 ++      while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength))
 72.2883 ++        newlim += mblength;
 72.2884 ++      if (ptr < lim)
 72.2885 ++        {
 72.2886 ++          GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 72.2887 ++          ptr += mblength;
 72.2888 ++        }
 72.2889 ++      while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength))
 72.2890 ++        newlim += mblength;
 72.2891 ++      lim = newlim;
 72.2892 ++    }
 72.2893 ++# endif
 72.2894 ++
 72.2895 ++  if (echar != 0)
 72.2896 ++  {
 72.2897 ++    /* If we're skipping leading blanks, don't start counting characters
 72.2898 ++     *      until after skipping past any leading blanks.  */
 72.2899 ++    if (key->skipeblanks)
 72.2900 ++      while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
 72.2901 ++        ptr += mblength;
 72.2902 ++
 72.2903 ++    memset (&state, '\0', sizeof(mbstate_t));
 72.2904 ++
 72.2905 ++    /* Advance PTR by ECHAR (if possible), but no further than LIM.  */
 72.2906 ++    for (i = 0; i < echar; i++)
 72.2907 ++     {
 72.2908 ++        GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 72.2909 ++
 72.2910 ++        if (ptr + mblength > lim)
 72.2911 ++          break;
 72.2912 ++        else
 72.2913 ++          ptr += mblength;
 72.2914 ++      }
 72.2915 ++  }
 72.2916 ++
 72.2917 ++  return ptr;
 72.2918 ++}
 72.2919 ++#endif
 72.2920 ++
 72.2921 ++static void
 72.2922 ++skipblanks_uni (char **ptr, char *lim)
 72.2923 ++{
 72.2924 ++  while (*ptr < lim && blanks[to_uchar (**ptr)])
 72.2925 ++    ++(*ptr);
 72.2926 ++}
 72.2927 ++
 72.2928 ++#if HAVE_MBRTOWC
 72.2929 ++static void
 72.2930 ++skipblanks_mb (char **ptr, char *lim)
 72.2931 ++{
 72.2932 ++  size_t mblength;
 72.2933 ++  while (*ptr < lim && ismbblank (*ptr, lim - *ptr, &mblength))
 72.2934 ++    (*ptr) += mblength;
 72.2935 ++}
 72.2936 ++#endif
 72.2937 ++
 72.2938 + /* Fill BUF reading from FP, moving buf->left bytes from the end
 72.2939 +    of buf->buf to the beginning first.  If EOF is reached and the
 72.2940 +    file wasn't terminated by a newline, supply one.  Set up BUF's line
 72.2941 +@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, c
 72.2942 +                   else
 72.2943 +                     {
 72.2944 +                       if (key->skipsblanks)
 72.2945 +-                        while (blanks[to_uchar (*line_start)])
 72.2946 +-                          line_start++;
 72.2947 ++                        {
 72.2948 ++#if HAVE_MBRTOWC
 72.2949 ++                          if (MB_CUR_MAX > 1)
 72.2950 ++                            {
 72.2951 ++                              size_t mblength;
 72.2952 ++                              while (line_start < line->keylim &&
 72.2953 ++                                     ismbblank (line_start,
 72.2954 ++                                                line->keylim - line_start,
 72.2955 ++                                                &mblength))
 72.2956 ++                                line_start += mblength;
 72.2957 ++                            }
 72.2958 ++                          else
 72.2959 ++#endif
 72.2960 ++                          while (blanks[to_uchar (*line_start)])
 72.2961 ++                            line_start++;
 72.2962 ++                        }
 72.2963 +                       line->keybeg = line_start;
 72.2964 +                     }
 72.2965 +                 }
 72.2966 +@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char co
 72.2967 +    hideously fast. */
 72.2968 + 
 72.2969 + static int
 72.2970 +-numcompare (char const *a, char const *b)
 72.2971 ++numcompare_uni (const char *a, const char *b)
 72.2972 + {
 72.2973 +   while (blanks[to_uchar (*a)])
 72.2974 +     a++;
 72.2975 +@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b
 72.2976 +   return strnumcmp (a, b, decimal_point, thousands_sep);
 72.2977 + }
 72.2978 + 
 72.2979 ++#if HAVE_MBRTOWC
 72.2980 ++static int
 72.2981 ++numcompare_mb (const char *a, const char *b)
 72.2982 ++{
 72.2983 ++  size_t mblength, len;
 72.2984 ++  len = strlen (a); /* okay for UTF-8 */
 72.2985 ++  while (*a && ismbblank (a, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength))
 72.2986 ++    {
 72.2987 ++      a += mblength;
 72.2988 ++      len -= mblength;
 72.2989 ++    }
 72.2990 ++  len = strlen (b); /* okay for UTF-8 */
 72.2991 ++  while (*b && ismbblank (b, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength))
 72.2992 ++    b += mblength;
 72.2993 ++
 72.2994 ++  return strnumcmp (a, b, decimal_point, thousands_sep);
 72.2995 ++}
 72.2996 ++#endif /* HAV_EMBRTOWC */
 72.2997 ++
 72.2998 + /* Work around a problem whereby the long double value returned by glibc's
 72.2999 +    strtold ("NaN", ...) contains uninitialized bits: clear all bytes of
 72.3000 +    A and B before calling strtold.  FIXME: remove this function once
 72.3001 +@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char
 72.3002 +    Return 0 if the name in S is not recognized.  */
 72.3003 + 
 72.3004 + static int
 72.3005 +-getmonth (char const *month, char **ea)
 72.3006 ++getmonth_uni (char const *month, size_t len, char **ea)
 72.3007 + {
 72.3008 +   size_t lo = 0;
 72.3009 +   size_t hi = MONTHS_PER_YEAR;
 72.3010 +@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, stru
 72.3011 +           char saved = *lim;
 72.3012 +           *lim = '\0';
 72.3013 + 
 72.3014 +-          while (blanks[to_uchar (*beg)])
 72.3015 +-            beg++;
 72.3016 ++          skipblanks (&beg, lim);
 72.3017 + 
 72.3018 +           char *tighter_lim = beg;
 72.3019 + 
 72.3020 +           if (lim < beg)
 72.3021 +             tighter_lim = lim;
 72.3022 +           else if (key->month)
 72.3023 +-            getmonth (beg, &tighter_lim);
 72.3024 ++            getmonth (beg, lim-beg, &tighter_lim);
 72.3025 +           else if (key->general_numeric)
 72.3026 +             ignore_value (strtold (beg, &tighter_lim));
 72.3027 +           else if (key->numeric || key->human_numeric)
 72.3028 +@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gke
 72.3029 +       bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key)
 72.3030 +                                  && !(key->schar || key->echar);
 72.3031 +       bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y  */
 72.3032 +-      if (!gkey_only && tab == TAB_DEFAULT && !line_offset
 72.3033 ++      if (!gkey_only && !tab_length && !line_offset
 72.3034 +           && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned))
 72.3035 +               || (!key->skipsblanks && key->schar)
 72.3036 +               || (!key->skipeblanks && key->echar)))
 72.3037 +@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gke
 72.3038 +     error (0, 0, _("option '-r' only applies to last-resort comparison"));
 72.3039 + }
 72.3040 + 
 72.3041 ++#if HAVE_MBRTOWC
 72.3042 ++static int
 72.3043 ++getmonth_mb (const char *s, size_t len, char **ea)
 72.3044 ++{
 72.3045 ++  char *month;
 72.3046 ++  register size_t i;
 72.3047 ++  register int lo = 0, hi = MONTHS_PER_YEAR, result;
 72.3048 ++  char *tmp;
 72.3049 ++  size_t wclength, mblength;
 72.3050 ++  const char *pp;
 72.3051 ++  const wchar_t *wpp;
 72.3052 ++  wchar_t *month_wcs;
 72.3053 ++  mbstate_t state;
 72.3054 ++
 72.3055 ++  while (len > 0 && ismbblank (s, len, &mblength))
 72.3056 ++    {
 72.3057 ++      s += mblength;
 72.3058 ++      len -= mblength;
 72.3059 ++    }
 72.3060 ++
 72.3061 ++  if (len == 0)
 72.3062 ++    return 0;
 72.3063 ++
 72.3064 ++  if (SIZE_MAX - len < 1)
 72.3065 ++    xalloc_die ();
 72.3066 ++
 72.3067 ++  month = (char *) xnmalloc (len + 1, MB_CUR_MAX);
 72.3068 ++
 72.3069 ++  pp = tmp = (char *) xnmalloc (len + 1, MB_CUR_MAX);
 72.3070 ++  memcpy (tmp, s, len);
 72.3071 ++  tmp[len] = '\0';
 72.3072 ++  wpp = month_wcs = (wchar_t *) xnmalloc (len + 1, sizeof (wchar_t));
 72.3073 ++  memset (&state, '\0', sizeof (mbstate_t));
 72.3074 ++
 72.3075 ++  wclength = mbsrtowcs (month_wcs, &pp, len + 1, &state);
 72.3076 ++  if (wclength == (size_t)-1 || pp != NULL)
 72.3077 ++    error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s));
 72.3078 ++
 72.3079 ++  for (i = 0; i < wclength; i++)
 72.3080 ++    {
 72.3081 ++      month_wcs[i] = towupper(month_wcs[i]);
 72.3082 ++      if (iswblank (month_wcs[i]))
 72.3083 ++        {
 72.3084 ++          month_wcs[i] = L'\0';
 72.3085 ++          break;
 72.3086 ++        }
 72.3087 ++    }
 72.3088 ++
 72.3089 ++  mblength = wcsrtombs (month, &wpp, (len + 1) * MB_CUR_MAX, &state);
 72.3090 ++  assert (mblength != (-1) && wpp == NULL);
 72.3091 ++
 72.3092 ++  do
 72.3093 ++    {
 72.3094 ++      int ix = (lo + hi) / 2;
 72.3095 ++
 72.3096 ++      if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0)
 72.3097 ++        hi = ix;
 72.3098 ++      else
 72.3099 ++        lo = ix;
 72.3100 ++    }
 72.3101 ++  while (hi - lo > 1);
 72.3102 ++
 72.3103 ++  result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name))
 72.3104 ++      ? monthtab[lo].val : 0);
 72.3105 ++
 72.3106 ++  if (ea && result)
 72.3107 ++     *ea = (char*) s + strlen (monthtab[lo].name);
 72.3108 ++
 72.3109 ++  free (month);
 72.3110 ++  free (tmp);
 72.3111 ++  free (month_wcs);
 72.3112 ++
 72.3113 ++  return result;
 72.3114 ++}
 72.3115 ++#endif
 72.3116 ++
 72.3117 + /* Compare two lines A and B trying every key in sequence until there
 72.3118 +    are no more keys or a difference is found. */
 72.3119 + 
 72.3120 + static int
 72.3121 +-keycompare (struct line const *a, struct line const *b)
 72.3122 ++keycompare_uni (const struct line *a, const struct line *b)
 72.3123 + {
 72.3124 +   struct keyfield *key = keylist;
 72.3125 + 
 72.3126 +@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct
 72.3127 +           else if (key->human_numeric)
 72.3128 +             diff = human_numcompare (ta, tb);
 72.3129 +           else if (key->month)
 72.3130 +-            diff = getmonth (ta, NULL) - getmonth (tb, NULL);
 72.3131 ++            diff = getmonth (ta, tlena, NULL) - getmonth (tb, tlenb, NULL);
 72.3132 +           else if (key->random)
 72.3133 +             diff = compare_random (ta, tlena, tb, tlenb);
 72.3134 +           else if (key->version)
 72.3135 +@@ -2695,6 +3135,211 @@ keycompare (struct line const *a, struct
 72.3136 +   return key->reverse ? -diff : diff;
 72.3137 + }
 72.3138 + 
 72.3139 ++#if HAVE_MBRTOWC
 72.3140 ++static int
 72.3141 ++keycompare_mb (const struct line *a, const struct line *b)
 72.3142 ++{
 72.3143 ++  struct keyfield *key = keylist;
 72.3144 ++
 72.3145 ++  /* For the first iteration only, the key positions have been
 72.3146 ++     precomputed for us. */
 72.3147 ++  char *texta = a->keybeg;
 72.3148 ++  char *textb = b->keybeg;
 72.3149 ++  char *lima = a->keylim;
 72.3150 ++  char *limb = b->keylim;
 72.3151 ++
 72.3152 ++  size_t mblength_a, mblength_b;
 72.3153 ++  wchar_t wc_a, wc_b;
 72.3154 ++  mbstate_t state_a, state_b;
 72.3155 ++
 72.3156 ++  int diff = 0;
 72.3157 ++
 72.3158 ++  memset (&state_a, '\0', sizeof(mbstate_t));
 72.3159 ++  memset (&state_b, '\0', sizeof(mbstate_t));
 72.3160 ++  /* Ignore keys with start after end.  */
 72.3161 ++  if (a->keybeg - a->keylim > 0)
 72.3162 ++    return 0;
 72.3163 ++
 72.3164 ++
 72.3165 ++              /* Ignore and/or translate chars before comparing.  */
 72.3166 ++# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE)        \
 72.3167 ++  do                                                                        \
 72.3168 ++    {                                                                        \
 72.3169 ++      wchar_t uwc;                                                        \
 72.3170 ++      char mbc[MB_LEN_MAX];                                                \
 72.3171 ++      mbstate_t state_wc;                                                \
 72.3172 ++                                                                        \
 72.3173 ++      for (NEW_LEN = i = 0; i < LEN;)                                        \
 72.3174 ++        {                                                                \
 72.3175 ++          mbstate_t state_bak;                                                \
 72.3176 ++                                                                        \
 72.3177 ++          state_bak = STATE;                                                \
 72.3178 ++          MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE);                \
 72.3179 ++                                                                        \
 72.3180 ++          if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1                \
 72.3181 ++              || MBLENGTH == 0)                                                \
 72.3182 ++            {                                                                \
 72.3183 ++              if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1)        \
 72.3184 ++                STATE = state_bak;                                        \
 72.3185 ++              if (!ignore)                                                \
 72.3186 ++                COPY[NEW_LEN++] = TEXT[i];                                \
 72.3187 ++              i++;                                                         \
 72.3188 ++              continue;                                                        \
 72.3189 ++            }                                                                \
 72.3190 ++                                                                        \
 72.3191 ++          if (ignore)                                                        \
 72.3192 ++            {                                                                \
 72.3193 ++              if ((ignore == nonprinting && !iswprint (WC))                \
 72.3194 ++                   || (ignore == nondictionary                                \
 72.3195 ++                       && !iswalnum (WC) && !iswblank (WC)))                \
 72.3196 ++                {                                                        \
 72.3197 ++                  i += MBLENGTH;                                        \
 72.3198 ++                  continue;                                                \
 72.3199 ++                }                                                        \
 72.3200 ++            }                                                                \
 72.3201 ++                                                                        \
 72.3202 ++          if (translate)                                                \
 72.3203 ++            {                                                                \
 72.3204 ++                                                                        \
 72.3205 ++              uwc = towupper(WC);                                        \
 72.3206 ++              if (WC == uwc)                                                \
 72.3207 ++                {                                                        \
 72.3208 ++                  memcpy (mbc, TEXT + i, MBLENGTH);                        \
 72.3209 ++                  i += MBLENGTH;                                        \
 72.3210 ++                }                                                        \
 72.3211 ++              else                                                        \
 72.3212 ++                {                                                        \
 72.3213 ++                  i += MBLENGTH;                                        \
 72.3214 ++                  WC = uwc;                                                \
 72.3215 ++                  memset (&state_wc, '\0', sizeof (mbstate_t));                \
 72.3216 ++                                                                        \
 72.3217 ++                  MBLENGTH = wcrtomb (mbc, WC, &state_wc);                \
 72.3218 ++                  assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0);        \
 72.3219 ++                }                                                        \
 72.3220 ++                                                                        \
 72.3221 ++              for (j = 0; j < MBLENGTH; j++)                                \
 72.3222 ++                COPY[NEW_LEN++] = mbc[j];                                \
 72.3223 ++            }                                                                \
 72.3224 ++          else                                                                \
 72.3225 ++            for (j = 0; j < MBLENGTH; j++)                                \
 72.3226 ++              COPY[NEW_LEN++] = TEXT[i++];                                \
 72.3227 ++        }                                                                \
 72.3228 ++      COPY[NEW_LEN] = '\0';                                                \
 72.3229 ++    }                                                                        \
 72.3230 ++  while (0)
 72.3231 ++
 72.3232 ++      /* Actually compare the fields. */
 72.3233 ++
 72.3234 ++  for (;;)
 72.3235 ++    {
 72.3236 ++      /* Find the lengths. */
 72.3237 ++      size_t lena = lima <= texta ? 0 : lima - texta;
 72.3238 ++      size_t lenb = limb <= textb ? 0 : limb - textb;
 72.3239 ++
 72.3240 ++      char enda IF_LINT (= 0);
 72.3241 ++      char endb IF_LINT (= 0);
 72.3242 ++
 72.3243 ++      char const *translate = key->translate;
 72.3244 ++      bool const *ignore = key->ignore;
 72.3245 ++
 72.3246 ++      if (ignore || translate)
 72.3247 ++        {
 72.3248 ++          if (SIZE_MAX - lenb - 2 < lena)
 72.3249 ++            xalloc_die ();
 72.3250 ++          char *copy_a = (char *) xnmalloc (lena + lenb + 2, MB_CUR_MAX);
 72.3251 ++          char *copy_b = copy_a + lena * MB_CUR_MAX + 1;
 72.3252 ++          size_t new_len_a, new_len_b;
 72.3253 ++          size_t i, j;
 72.3254 ++
 72.3255 ++          IGNORE_CHARS (new_len_a, lena, texta, copy_a,
 72.3256 ++                        wc_a, mblength_a, state_a);
 72.3257 ++          IGNORE_CHARS (new_len_b, lenb, textb, copy_b,
 72.3258 ++                        wc_b, mblength_b, state_b);
 72.3259 ++          texta = copy_a; textb = copy_b;
 72.3260 ++          lena = new_len_a; lenb = new_len_b;
 72.3261 ++        }
 72.3262 ++      else
 72.3263 ++        {
 72.3264 ++          /* Use the keys in-place, temporarily null-terminated.  */
 72.3265 ++          enda = texta[lena]; texta[lena] = '\0';
 72.3266 ++          endb = textb[lenb]; textb[lenb] = '\0';
 72.3267 ++        }
 72.3268 ++
 72.3269 ++      if (key->random)
 72.3270 ++        diff = compare_random (texta, lena, textb, lenb);
 72.3271 ++      else if (key->numeric | key->general_numeric | key->human_numeric)
 72.3272 ++        {
 72.3273 ++          char savea = *lima, saveb = *limb;
 72.3274 ++
 72.3275 ++          *lima = *limb = '\0';
 72.3276 ++          diff = (key->numeric ? numcompare (texta, textb)
 72.3277 ++                  : key->general_numeric ? general_numcompare (texta, textb)
 72.3278 ++                  : human_numcompare (texta, textb));
 72.3279 ++          *lima = savea, *limb = saveb;
 72.3280 ++        }
 72.3281 ++      else if (key->version)
 72.3282 ++        diff = filevercmp (texta, textb);
 72.3283 ++      else if (key->month)
 72.3284 ++        diff = getmonth (texta, lena, NULL) - getmonth (textb, lenb, NULL);
 72.3285 ++      else if (lena == 0)
 72.3286 ++        diff = - NONZERO (lenb);
 72.3287 ++      else if (lenb == 0)
 72.3288 ++        diff = 1;
 72.3289 ++      else if (hard_LC_COLLATE && !folding)
 72.3290 ++        {
 72.3291 ++          diff = xmemcoll0 (texta, lena + 1, textb, lenb + 1);
 72.3292 ++        }
 72.3293 ++      else
 72.3294 ++        {
 72.3295 ++          diff = memcmp (texta, textb, MIN (lena, lenb));
 72.3296 ++          if (diff == 0)
 72.3297 ++            diff = lena < lenb ? -1 : lena != lenb;
 72.3298 ++        }
 72.3299 ++
 72.3300 ++      if (ignore || translate)
 72.3301 ++        free (texta);
 72.3302 ++      else
 72.3303 ++        {
 72.3304 ++          texta[lena] = enda;
 72.3305 ++          textb[lenb] = endb;
 72.3306 ++        }
 72.3307 ++
 72.3308 ++      if (diff)
 72.3309 ++        goto not_equal;
 72.3310 ++
 72.3311 ++      key = key->next;
 72.3312 ++      if (! key)
 72.3313 ++        break;
 72.3314 ++
 72.3315 ++      /* Find the beginning and limit of the next field.  */
 72.3316 ++      if (key->eword != -1)
 72.3317 ++        lima = limfield (a, key), limb = limfield (b, key);
 72.3318 ++      else
 72.3319 ++        lima = a->text + a->length - 1, limb = b->text + b->length - 1;
 72.3320 ++
 72.3321 ++      if (key->sword != -1)
 72.3322 ++        texta = begfield (a, key), textb = begfield (b, key);
 72.3323 ++      else
 72.3324 ++        {
 72.3325 ++          texta = a->text, textb = b->text;
 72.3326 ++          if (key->skipsblanks)
 72.3327 ++            {
 72.3328 ++              while (texta < lima && ismbblank (texta, lima - texta, &mblength_a))
 72.3329 ++                texta += mblength_a;
 72.3330 ++              while (textb < limb && ismbblank (textb, limb - textb, &mblength_b))
 72.3331 ++                textb += mblength_b;
 72.3332 ++            }
 72.3333 ++        }
 72.3334 ++    }
 72.3335 ++
 72.3336 ++not_equal:
 72.3337 ++  if (key && key->reverse)
 72.3338 ++    return -diff;
 72.3339 ++  else
 72.3340 ++    return diff;
 72.3341 ++}
 72.3342 ++#endif
 72.3343 ++
 72.3344 + /* Compare two lines A and B, returning negative, zero, or positive
 72.3345 +    depending on whether A compares less than, equal to, or greater than B. */
 72.3346 + 
 72.3347 +@@ -2722,7 +3367,7 @@ compare (struct line const *a, struct li
 72.3348 +     diff = - NONZERO (blen);
 72.3349 +   else if (blen == 0)
 72.3350 +     diff = 1;
 72.3351 +-  else if (hard_LC_COLLATE)
 72.3352 ++  else if (hard_LC_COLLATE && !folding)
 72.3353 +     {
 72.3354 +       /* Note xmemcoll0 is a performance enhancement as
 72.3355 +          it will not unconditionally write '\0' after the
 72.3356 +@@ -4121,6 +4766,7 @@ set_ordering (char const *s, struct keyf
 72.3357 +           break;
 72.3358 +         case 'f':
 72.3359 +           key->translate = fold_toupper;
 72.3360 ++          folding = true;
 72.3361 +           break;
 72.3362 +         case 'g':
 72.3363 +           key->general_numeric = true;
 72.3364 +@@ -4199,7 +4845,7 @@ main (int argc, char **argv)
 72.3365 +   initialize_exit_failure (SORT_FAILURE);
 72.3366 + 
 72.3367 +   hard_LC_COLLATE = hard_locale (LC_COLLATE);
 72.3368 +-#if HAVE_NL_LANGINFO
 72.3369 ++#if HAVE_LANGINFO_CODESET
 72.3370 +   hard_LC_TIME = hard_locale (LC_TIME);
 72.3371 + #endif
 72.3372 + 
 72.3373 +@@ -4220,6 +4866,29 @@ main (int argc, char **argv)
 72.3374 +       thousands_sep = -1;
 72.3375 +   }
 72.3376 + 
 72.3377 ++#if HAVE_MBRTOWC
 72.3378 ++  if (MB_CUR_MAX > 1)
 72.3379 ++    {
 72.3380 ++      inittables = inittables_mb;
 72.3381 ++      begfield = begfield_mb;
 72.3382 ++      limfield = limfield_mb;
 72.3383 ++      skipblanks = skipblanks_mb;
 72.3384 ++      getmonth = getmonth_mb;
 72.3385 ++      keycompare = keycompare_mb;
 72.3386 ++      numcompare = numcompare_mb;
 72.3387 ++    }
 72.3388 ++  else
 72.3389 ++#endif
 72.3390 ++    {
 72.3391 ++      inittables = inittables_uni;
 72.3392 ++      begfield = begfield_uni;
 72.3393 ++      limfield = limfield_uni;
 72.3394 ++      skipblanks = skipblanks_uni;
 72.3395 ++      getmonth = getmonth_uni;
 72.3396 ++      keycompare = keycompare_uni;
 72.3397 ++      numcompare = numcompare_uni;
 72.3398 ++    }
 72.3399 ++
 72.3400 +   have_read_stdin = false;
 72.3401 +   inittables ();
 72.3402 + 
 72.3403 +@@ -4494,13 +5163,34 @@ main (int argc, char **argv)
 72.3404 + 
 72.3405 +         case 't':
 72.3406 +           {
 72.3407 +-            char newtab = optarg[0];
 72.3408 +-            if (! newtab)
 72.3409 ++            char newtab[MB_LEN_MAX + 1];
 72.3410 ++            size_t newtab_length = 1;
 72.3411 ++            strncpy (newtab, optarg, MB_LEN_MAX);
 72.3412 ++            if (! newtab[0])
 72.3413 +               error (SORT_FAILURE, 0, _("empty tab"));
 72.3414 +-            if (optarg[1])
 72.3415 ++#if HAVE_MBRTOWC
 72.3416 ++            if (MB_CUR_MAX > 1)
 72.3417 ++              {
 72.3418 ++                wchar_t wc;
 72.3419 ++                mbstate_t state;
 72.3420 ++
 72.3421 ++                memset (&state, '\0', sizeof (mbstate_t));
 72.3422 ++                newtab_length = mbrtowc (&wc, newtab, strnlen (newtab,
 72.3423 ++                                                               MB_LEN_MAX),
 72.3424 ++                                         &state);
 72.3425 ++                switch (newtab_length)
 72.3426 ++                  {
 72.3427 ++                  case (size_t) -1:
 72.3428 ++                  case (size_t) -2:
 72.3429 ++                  case 0:
 72.3430 ++                    newtab_length = 1;
 72.3431 ++                  }
 72.3432 ++              }
 72.3433 ++#endif
 72.3434 ++            if (newtab_length == 1 && optarg[1])
 72.3435 +               {
 72.3436 +                 if (STREQ (optarg, "\\0"))
 72.3437 +-                  newtab = '\0';
 72.3438 ++                  newtab[0] = '\0';
 72.3439 +                 else
 72.3440 +                   {
 72.3441 +                     /* Provoke with 'sort -txx'.  Complain about
 72.3442 +@@ -4511,9 +5201,12 @@ main (int argc, char **argv)
 72.3443 +                            quote (optarg));
 72.3444 +                   }
 72.3445 +               }
 72.3446 +-            if (tab != TAB_DEFAULT && tab != newtab)
 72.3447 ++            if (tab_length
 72.3448 ++                && (tab_length != newtab_length
 72.3449 ++                    || memcmp (tab, newtab, tab_length) != 0))
 72.3450 +               error (SORT_FAILURE, 0, _("incompatible tabs"));
 72.3451 +-            tab = newtab;
 72.3452 ++            memcpy (tab, newtab, newtab_length);
 72.3453 ++            tab_length = newtab_length;
 72.3454 +           }
 72.3455 +           break;
 72.3456 + 
 72.3457 +@@ -4751,12 +5444,10 @@ main (int argc, char **argv)
 72.3458 +       sort (files, nfiles, outfile, nthreads);
 72.3459 +     }
 72.3460 + 
 72.3461 +-#ifdef lint
 72.3462 +   if (files_from)
 72.3463 +     readtokens0_free (&tok);
 72.3464 +   else
 72.3465 +     free (files);
 72.3466 +-#endif
 72.3467 + 
 72.3468 +   if (have_read_stdin && fclose (stdin) == EOF)
 72.3469 +     die (_("close failed"), "-");
 72.3470 +diff -Naurp coreutils-8.25-orig/src/unexpand.c coreutils-8.25/src/unexpand.c
 72.3471 +--- coreutils-8.25-orig/src/unexpand.c	2016-01-01 07:48:50.000000000 -0600
 72.3472 ++++ coreutils-8.25/src/unexpand.c	2016-02-08 19:07:10.311944651 -0600
 72.3473 +@@ -38,12 +38,29 @@
 72.3474 + #include <stdio.h>
 72.3475 + #include <getopt.h>
 72.3476 + #include <sys/types.h>
 72.3477 ++
 72.3478 ++/* Get mbstate_t, mbrtowc(), wcwidth(). */
 72.3479 ++#if HAVE_WCHAR_H
 72.3480 ++# include <wchar.h>
 72.3481 ++#endif
 72.3482 ++
 72.3483 + #include "system.h"
 72.3484 + #include "error.h"
 72.3485 + #include "fadvise.h"
 72.3486 + #include "quote.h"
 72.3487 + #include "xstrndup.h"
 72.3488 + 
 72.3489 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
 72.3490 ++      installation; work around this configuration error.  */
 72.3491 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
 72.3492 ++# define MB_LEN_MAX 16
 72.3493 ++#endif
 72.3494 ++
 72.3495 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
 72.3496 ++#if HAVE_MBRTOWC && defined mbstate_t
 72.3497 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
 72.3498 ++#endif
 72.3499 ++
 72.3500 + /* The official name of this program (e.g., no 'g' prefix).  */
 72.3501 + #define PROGRAM_NAME "unexpand"
 72.3502 + 
 72.3503 +@@ -103,6 +120,210 @@ static struct option const longopts[] =
 72.3504 +   {NULL, 0, NULL, 0}
 72.3505 + };
 72.3506 + 
 72.3507 ++static FILE *next_file (FILE *fp);
 72.3508 ++
 72.3509 ++#if HAVE_MBRTOWC
 72.3510 ++static void
 72.3511 ++unexpand_multibyte (void)
 72.3512 ++{
 72.3513 ++  FILE *fp;			/* Input stream. */
 72.3514 ++  mbstate_t i_state;		/* Current shift state of the input stream. */
 72.3515 ++  mbstate_t i_state_bak;	/* Back up the I_STATE. */
 72.3516 ++  mbstate_t o_state;		/* Current shift state of the output stream. */
 72.3517 ++  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
 72.3518 ++  char *bufpos = buf;			/* Next read position of BUF. */
 72.3519 ++  size_t buflen = 0;		/* The length of the byte sequence in buf. */
 72.3520 ++  wint_t wc;			/* A gotten wide character. */
 72.3521 ++  size_t mblength;		/* The byte size of a multibyte character
 72.3522 ++				   which shows as same character as WC. */
 72.3523 ++  bool prev_tab = false;
 72.3524 ++
 72.3525 ++  /* Index in `tab_list' of next tabstop: */
 72.3526 ++  int tab_index = 0;		/* For calculating width of pending tabs. */
 72.3527 ++  int print_tab_index = 0;	/* For printing as many tabs as possible. */
 72.3528 ++  unsigned int column = 0;	/* Column on screen of next char. */
 72.3529 ++  int next_tab_column;		/* Column the next tab stop is on. */
 72.3530 ++  int convert = 1;		/* If nonzero, perform translations. */
 72.3531 ++  unsigned int pending = 0;	/* Pending columns of blanks. */
 72.3532 ++
 72.3533 ++  fp = next_file ((FILE *) NULL);
 72.3534 ++  if (fp == NULL)
 72.3535 ++    return;
 72.3536 ++
 72.3537 ++  memset (&o_state, '\0', sizeof(mbstate_t));
 72.3538 ++  memset (&i_state, '\0', sizeof(mbstate_t));
 72.3539 ++
 72.3540 ++  for (;;)
 72.3541 ++    {
 72.3542 ++      if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp))
 72.3543 ++	{
 72.3544 ++	  memmove (buf, bufpos, buflen);
 72.3545 ++	  buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp);
 72.3546 ++	  bufpos = buf;
 72.3547 ++	}
 72.3548 ++
 72.3549 ++      /* Get a wide character. */
 72.3550 ++      if (buflen < 1)
 72.3551 ++	{
 72.3552 ++	  mblength = 1;
 72.3553 ++	  wc = WEOF;
 72.3554 ++	}
 72.3555 ++      else
 72.3556 ++	{
 72.3557 ++	  i_state_bak = i_state;
 72.3558 ++	  mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &i_state);
 72.3559 ++	}
 72.3560 ++
 72.3561 ++      if (mblength == (size_t)-1 || mblength == (size_t)-2)
 72.3562 ++	{
 72.3563 ++	  i_state = i_state_bak;
 72.3564 ++	  wc = L'\0';
 72.3565 ++	}
 72.3566 ++
 72.3567 ++      if (wc == L' ' && convert && column < INT_MAX)
 72.3568 ++	{
 72.3569 ++	  ++pending;
 72.3570 ++	  ++column;
 72.3571 ++	}
 72.3572 ++      else if (wc == L'\t' && convert)
 72.3573 ++	{
 72.3574 ++	  if (tab_size == 0)
 72.3575 ++	    {
 72.3576 ++	      /* Do not let tab_index == first_free_tab;
 72.3577 ++		 stop when it is 1 less. */
 72.3578 ++	      while (tab_index < first_free_tab - 1
 72.3579 ++		  && column >= tab_list[tab_index])
 72.3580 ++		tab_index++;
 72.3581 ++	      next_tab_column = tab_list[tab_index];
 72.3582 ++	      if (tab_index < first_free_tab - 1)
 72.3583 ++		tab_index++;
 72.3584 ++	      if (column >= next_tab_column)
 72.3585 ++		{
 72.3586 ++		  convert = 0;	/* Ran out of tab stops. */
 72.3587 ++		  goto flush_pend_mb;
 72.3588 ++		}
 72.3589 ++	    }
 72.3590 ++	  else
 72.3591 ++	    {
 72.3592 ++	      next_tab_column = column + tab_size - column % tab_size;
 72.3593 ++	    }
 72.3594 ++	  pending += next_tab_column - column;
 72.3595 ++	  column = next_tab_column;
 72.3596 ++	}
 72.3597 ++      else
 72.3598 ++	{
 72.3599 ++flush_pend_mb:
 72.3600 ++	  /* Flush pending spaces.  Print as many tabs as possible,
 72.3601 ++	     then print the rest as spaces. */
 72.3602 ++	  if (pending == 1 && column != 1 && !prev_tab)
 72.3603 ++	    {
 72.3604 ++	      putchar (' ');
 72.3605 ++	      pending = 0;
 72.3606 ++	    }
 72.3607 ++	  column -= pending;
 72.3608 ++	  while (pending > 0)
 72.3609 ++	    {
 72.3610 ++	      if (tab_size == 0)
 72.3611 ++		{
 72.3612 ++		  /* Do not let print_tab_index == first_free_tab;
 72.3613 ++		     stop when it is 1 less. */
 72.3614 ++		  while (print_tab_index < first_free_tab - 1
 72.3615 ++		      && column >= tab_list[print_tab_index])
 72.3616 ++		    print_tab_index++;
 72.3617 ++		  next_tab_column = tab_list[print_tab_index];
 72.3618 ++		  if (print_tab_index < first_free_tab - 1)
 72.3619 ++		    print_tab_index++;
 72.3620 ++		}
 72.3621 ++	      else
 72.3622 ++		{
 72.3623 ++		  next_tab_column =
 72.3624 ++		    column + tab_size - column % tab_size;
 72.3625 ++		}
 72.3626 ++	      if (next_tab_column - column <= pending)
 72.3627 ++		{
 72.3628 ++		  putchar ('\t');
 72.3629 ++		  pending -= next_tab_column - column;
 72.3630 ++		  column = next_tab_column;
 72.3631 ++		}
 72.3632 ++	      else
 72.3633 ++		{
 72.3634 ++		  --print_tab_index;
 72.3635 ++		  column += pending;
 72.3636 ++		  while (pending != 0)
 72.3637 ++		    {
 72.3638 ++		      putchar (' ');
 72.3639 ++		      pending--;
 72.3640 ++		    }
 72.3641 ++		}
 72.3642 ++	    }
 72.3643 ++
 72.3644 ++	  if (wc == WEOF)
 72.3645 ++	    {
 72.3646 ++	      fp = next_file (fp);
 72.3647 ++	      if (fp == NULL)
 72.3648 ++		break;          /* No more files. */
 72.3649 ++	      else
 72.3650 ++		{
 72.3651 ++		  memset (&i_state, '\0', sizeof(mbstate_t));
 72.3652 ++		  continue;
 72.3653 ++		}
 72.3654 ++	    }
 72.3655 ++
 72.3656 ++	  if (mblength == (size_t)-1 || mblength == (size_t)-2)
 72.3657 ++	    {
 72.3658 ++	      if (convert)
 72.3659 ++		{
 72.3660 ++		  ++column;
 72.3661 ++		  if (convert_entire_line == 0)
 72.3662 ++		    convert = 0;
 72.3663 ++		}
 72.3664 ++	      mblength = 1;
 72.3665 ++	      putchar (buf[0]);
 72.3666 ++	    }
 72.3667 ++	  else if (mblength == 0)
 72.3668 ++	    {
 72.3669 ++	      if (convert && convert_entire_line == 0)
 72.3670 ++		convert = 0;
 72.3671 ++	      mblength = 1;
 72.3672 ++	      putchar ('\0');
 72.3673 ++	    }
 72.3674 ++	  else
 72.3675 ++	    {
 72.3676 ++	      if (convert)
 72.3677 ++		{
 72.3678 ++		  if (wc == L'\b')
 72.3679 ++		    {
 72.3680 ++		      if (column > 0)
 72.3681 ++			--column;
 72.3682 ++		    }
 72.3683 ++		  else
 72.3684 ++		    {
 72.3685 ++		      int width;            /* The width of WC. */
 72.3686 ++
 72.3687 ++		      width = wcwidth (wc);
 72.3688 ++		      column += (width > 0) ? width : 0;
 72.3689 ++		      if (convert_entire_line == 0)
 72.3690 ++			convert = 0;
 72.3691 ++		    }
 72.3692 ++		}
 72.3693 ++
 72.3694 ++	      if (wc == L'\n')
 72.3695 ++		{
 72.3696 ++		  tab_index = print_tab_index = 0;
 72.3697 ++		  column = pending = 0;
 72.3698 ++		  convert = 1;
 72.3699 ++		}
 72.3700 ++	      fwrite (bufpos, sizeof(char), mblength, stdout);
 72.3701 ++	    }
 72.3702 ++	}
 72.3703 ++      prev_tab = wc == L'\t';
 72.3704 ++      buflen -= mblength;
 72.3705 ++      bufpos += mblength;
 72.3706 ++    }
 72.3707 ++}
 72.3708 ++#endif
 72.3709 ++
 72.3710 ++
 72.3711 + void
 72.3712 + usage (int status)
 72.3713 + {
 72.3714 +@@ -523,7 +744,12 @@ main (int argc, char **argv)
 72.3715 + 
 72.3716 +   file_list = (optind < argc ? &argv[optind] : stdin_argv);
 72.3717 + 
 72.3718 +-  unexpand ();
 72.3719 ++#if HAVE_MBRTOWC
 72.3720 ++  if (MB_CUR_MAX > 1)
 72.3721 ++    unexpand_multibyte ();
 72.3722 ++  else
 72.3723 ++#endif
 72.3724 ++    unexpand ();
 72.3725 + 
 72.3726 +   if (have_read_stdin && fclose (stdin) != 0)
 72.3727 +     error (EXIT_FAILURE, errno, "-");
 72.3728 +diff -Naurp coreutils-8.25-orig/src/uniq.c coreutils-8.25/src/uniq.c
 72.3729 +--- coreutils-8.25-orig/src/uniq.c	2016-01-13 05:08:59.000000000 -0600
 72.3730 ++++ coreutils-8.25/src/uniq.c	2016-02-08 19:07:10.312944654 -0600
 72.3731 +@@ -21,6 +21,17 @@
 72.3732 + #include <getopt.h>
 72.3733 + #include <sys/types.h>
 72.3734 + 
 72.3735 ++/* Get mbstate_t, mbrtowc(). */
 72.3736 ++#if HAVE_WCHAR_H
 72.3737 ++# include <wchar.h>
 72.3738 ++#endif
 72.3739 ++
 72.3740 ++/* Get isw* functions. */
 72.3741 ++#if HAVE_WCTYPE_H
 72.3742 ++# include <wctype.h>
 72.3743 ++#endif
 72.3744 ++#include <assert.h>
 72.3745 ++
 72.3746 + #include "system.h"
 72.3747 + #include "argmatch.h"
 72.3748 + #include "linebuffer.h"
 72.3749 +@@ -33,6 +44,18 @@
 72.3750 + #include "xstrtol.h"
 72.3751 + #include "memcasecmp.h"
 72.3752 + #include "quote.h"
 72.3753 ++#include "xmemcoll.h"
 72.3754 ++
 72.3755 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
 72.3756 ++   installation; work around this configuration error.  */
 72.3757 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
 72.3758 ++# define MB_LEN_MAX 16
 72.3759 ++#endif
 72.3760 ++
 72.3761 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
 72.3762 ++#if HAVE_MBRTOWC && defined mbstate_t
 72.3763 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
 72.3764 ++#endif
 72.3765 + 
 72.3766 + /* The official name of this program (e.g., no 'g' prefix).  */
 72.3767 + #define PROGRAM_NAME "uniq"
 72.3768 +@@ -143,6 +166,10 @@ enum
 72.3769 +   GROUP_OPTION = CHAR_MAX + 1
 72.3770 + };
 72.3771 + 
 72.3772 ++/* Function pointers. */
 72.3773 ++static char *
 72.3774 ++(*find_field) (struct linebuffer *line);
 72.3775 ++
 72.3776 + static struct option const longopts[] =
 72.3777 + {
 72.3778 +   {"count", no_argument, NULL, 'c'},
 72.3779 +@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *m
 72.3780 +    return a pointer to the beginning of the line's field to be compared. */
 72.3781 + 
 72.3782 + static char * _GL_ATTRIBUTE_PURE
 72.3783 +-find_field (struct linebuffer const *line)
 72.3784 ++find_field_uni (struct linebuffer *line)
 72.3785 + {
 72.3786 +   size_t count;
 72.3787 +   char const *lp = line->buffer;
 72.3788 +@@ -272,6 +299,83 @@ find_field (struct linebuffer const *lin
 72.3789 +   return line->buffer + i;
 72.3790 + }
 72.3791 + 
 72.3792 ++#if HAVE_MBRTOWC
 72.3793 ++
 72.3794 ++# define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL)  \
 72.3795 ++  do                                                                        \
 72.3796 ++    {                                                                        \
 72.3797 ++      mbstate_t state_bak;                                                \
 72.3798 ++                                                                        \
 72.3799 ++      CONVFAIL = 0;                                                        \
 72.3800 ++      state_bak = *STATEP;                                                \
 72.3801 ++                                                                        \
 72.3802 ++      MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP);                \
 72.3803 ++                                                                        \
 72.3804 ++      switch (MBLENGTH)                                                        \
 72.3805 ++        {                                                                \
 72.3806 ++        case (size_t)-2:                                                \
 72.3807 ++        case (size_t)-1:                                                \
 72.3808 ++          *STATEP = state_bak;                                                \
 72.3809 ++          CONVFAIL++;                                                        \
 72.3810 ++          /* Fall through */                                                \
 72.3811 ++        case 0:                                                                \
 72.3812 ++          MBLENGTH = 1;                                                        \
 72.3813 ++        }                                                                \
 72.3814 ++    }                                                                        \
 72.3815 ++  while (0)
 72.3816 ++
 72.3817 ++static char *
 72.3818 ++find_field_multi (struct linebuffer *line)
 72.3819 ++{
 72.3820 ++  size_t count;
 72.3821 ++  char *lp = line->buffer;
 72.3822 ++  size_t size = line->length - 1;
 72.3823 ++  size_t pos;
 72.3824 ++  size_t mblength;
 72.3825 ++  wchar_t wc;
 72.3826 ++  mbstate_t *statep;
 72.3827 ++  int convfail = 0;
 72.3828 ++
 72.3829 ++  pos = 0;
 72.3830 ++  statep = &(line->state);
 72.3831 ++
 72.3832 ++  /* skip fields. */
 72.3833 ++  for (count = 0; count < skip_fields && pos < size; count++)
 72.3834 ++    {
 72.3835 ++      while (pos < size)
 72.3836 ++        {
 72.3837 ++          MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
 72.3838 ++
 72.3839 ++          if (convfail || !(iswblank (wc) || wc == '\n'))
 72.3840 ++            {
 72.3841 ++              pos += mblength;
 72.3842 ++              break;
 72.3843 ++            }
 72.3844 ++          pos += mblength;
 72.3845 ++        }
 72.3846 ++
 72.3847 ++      while (pos < size)
 72.3848 ++        {
 72.3849 ++          MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
 72.3850 ++
 72.3851 ++          if (!convfail && (iswblank (wc) || wc == '\n'))
 72.3852 ++            break;
 72.3853 ++
 72.3854 ++          pos += mblength;
 72.3855 ++        }
 72.3856 ++    }
 72.3857 ++
 72.3858 ++  /* skip fields. */
 72.3859 ++  for (count = 0; count < skip_chars && pos < size; count++)
 72.3860 ++    {
 72.3861 ++      MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
 72.3862 ++      pos += mblength;
 72.3863 ++    }
 72.3864 ++
 72.3865 ++  return lp + pos;
 72.3866 ++}
 72.3867 ++#endif
 72.3868 ++
 72.3869 + /* Return false if two strings OLD and NEW match, true if not.
 72.3870 +    OLD and NEW point not to the beginnings of the lines
 72.3871 +    but rather to the beginnings of the fields to compare.
 72.3872 +@@ -280,6 +384,8 @@ find_field (struct linebuffer const *lin
 72.3873 + static bool
 72.3874 + different (char *old, char *new, size_t oldlen, size_t newlen)
 72.3875 + {
 72.3876 ++  char *copy_old, *copy_new;
 72.3877 ++
 72.3878 +   if (check_chars < oldlen)
 72.3879 +     oldlen = check_chars;
 72.3880 +   if (check_chars < newlen)
 72.3881 +@@ -287,15 +393,104 @@ different (char *old, char *new, size_t
 72.3882 + 
 72.3883 +   if (ignore_case)
 72.3884 +     {
 72.3885 +-      /* FIXME: This should invoke strcoll somehow.  */
 72.3886 +-      return oldlen != newlen || memcasecmp (old, new, oldlen);
 72.3887 ++      size_t i;
 72.3888 ++
 72.3889 ++      copy_old = xmalloc (oldlen + 1);
 72.3890 ++      copy_new = xmalloc (oldlen + 1);
 72.3891 ++
 72.3892 ++      for (i = 0; i < oldlen; i++)
 72.3893 ++        {
 72.3894 ++          copy_old[i] = toupper (old[i]);
 72.3895 ++          copy_new[i] = toupper (new[i]);
 72.3896 ++        }
 72.3897 ++      bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen);
 72.3898 ++      free (copy_old);
 72.3899 ++      free (copy_new);
 72.3900 ++      return rc;
 72.3901 +     }
 72.3902 +-  else if (hard_LC_COLLATE)
 72.3903 +-    return xmemcoll (old, oldlen, new, newlen) != 0;
 72.3904 +   else
 72.3905 +-    return oldlen != newlen || memcmp (old, new, oldlen);
 72.3906 ++    {
 72.3907 ++      copy_old = (char *)old;
 72.3908 ++      copy_new = (char *)new;
 72.3909 ++    }
 72.3910 ++
 72.3911 ++  return xmemcoll (copy_old, oldlen, copy_new, newlen);
 72.3912 ++
 72.3913 + }
 72.3914 + 
 72.3915 ++#if HAVE_MBRTOWC
 72.3916 ++static int
 72.3917 ++different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate)
 72.3918 ++{
 72.3919 ++  size_t i, j, chars;
 72.3920 ++  const char *str[2];
 72.3921 ++  char *copy[2];
 72.3922 ++  size_t len[2];
 72.3923 ++  mbstate_t state[2];
 72.3924 ++  size_t mblength;
 72.3925 ++  wchar_t wc, uwc;
 72.3926 ++  mbstate_t state_bak;
 72.3927 ++
 72.3928 ++  str[0] = old;
 72.3929 ++  str[1] = new;
 72.3930 ++  len[0] = oldlen;
 72.3931 ++  len[1] = newlen;
 72.3932 ++  state[0] = oldstate;
 72.3933 ++  state[1] = newstate;
 72.3934 ++
 72.3935 ++  for (i = 0; i < 2; i++)
 72.3936 ++    {
 72.3937 ++      copy[i] = xmalloc (len[i] + 1);
 72.3938 ++      memset (copy[i], '\0', len[i] + 1);
 72.3939 ++
 72.3940 ++      for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++)
 72.3941 ++        {
 72.3942 ++          state_bak = state[i];
 72.3943 ++          mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i]));
 72.3944 ++
 72.3945 ++          switch (mblength)
 72.3946 ++            {
 72.3947 ++            case (size_t)-1:
 72.3948 ++            case (size_t)-2:
 72.3949 ++              state[i] = state_bak;
 72.3950 ++              /* Fall through */
 72.3951 ++            case 0:
 72.3952 ++              mblength = 1;
 72.3953 ++              break;
 72.3954 ++
 72.3955 ++            default:
 72.3956 ++              if (ignore_case)
 72.3957 ++                {
 72.3958 ++                  uwc = towupper (wc);
 72.3959 ++
 72.3960 ++                  if (uwc != wc)
 72.3961 ++                    {
 72.3962 ++                      mbstate_t state_wc;
 72.3963 ++                      size_t mblen;
 72.3964 ++
 72.3965 ++                      memset (&state_wc, '\0', sizeof(mbstate_t));
 72.3966 ++                      mblen = wcrtomb (copy[i] + j, uwc, &state_wc);
 72.3967 ++                      assert (mblen != (size_t)-1);
 72.3968 ++                    }
 72.3969 ++                  else
 72.3970 ++                    memcpy (copy[i] + j, str[i] + j, mblength);
 72.3971 ++                }
 72.3972 ++              else
 72.3973 ++                memcpy (copy[i] + j, str[i] + j, mblength);
 72.3974 ++            }
 72.3975 ++          j += mblength;
 72.3976 ++        }
 72.3977 ++      copy[i][j] = '\0';
 72.3978 ++      len[i] = j;
 72.3979 ++    }
 72.3980 ++  int rc = xmemcoll (copy[0], len[0], copy[1], len[1]);
 72.3981 ++  free (copy[0]);
 72.3982 ++  free (copy[1]);
 72.3983 ++  return rc;
 72.3984 ++
 72.3985 ++}
 72.3986 ++#endif
 72.3987 ++
 72.3988 + /* Output the line in linebuffer LINE to standard output
 72.3989 +    provided that the switches say it should be output.
 72.3990 +    MATCH is true if the line matches the previous line.
 72.3991 +@@ -359,19 +554,38 @@ check_file (const char *infile, const ch
 72.3992 +       char *prevfield IF_LINT ( = NULL);
 72.3993 +       size_t prevlen IF_LINT ( = 0);
 72.3994 +       bool first_group_printed = false;
 72.3995 ++#if HAVE_MBRTOWC
 72.3996 ++      mbstate_t prevstate;
 72.3997 ++
 72.3998 ++      memset (&prevstate, '\0', sizeof (mbstate_t));
 72.3999 ++#endif
 72.4000 + 
 72.4001 +       while (!feof (stdin))
 72.4002 +         {
 72.4003 +           char *thisfield;
 72.4004 +           size_t thislen;
 72.4005 +           bool new_group;
 72.4006 ++#if HAVE_MBRTOWC
 72.4007 ++          mbstate_t thisstate;
 72.4008 ++#endif
 72.4009 + 
 72.4010 +           if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
 72.4011 +             break;
 72.4012 + 
 72.4013 +           thisfield = find_field (thisline);
 72.4014 +           thislen = thisline->length - 1 - (thisfield - thisline->buffer);
 72.4015 ++#if HAVE_MBRTOWC
 72.4016 ++          if (MB_CUR_MAX > 1)
 72.4017 ++            {
 72.4018 ++              thisstate = thisline->state;
 72.4019 + 
 72.4020 ++              new_group = (prevline->length == 0
 72.4021 ++                           || different_multi (thisfield, prevfield,
 72.4022 ++                                               thislen, prevlen,
 72.4023 ++                                               thisstate, prevstate));
 72.4024 ++            }
 72.4025 ++          else
 72.4026 ++#endif
 72.4027 +           new_group = (prevline->length == 0
 72.4028 +                        || different (thisfield, prevfield, thislen, prevlen));
 72.4029 + 
 72.4030 +@@ -389,6 +603,10 @@ check_file (const char *infile, const ch
 72.4031 +               SWAP_LINES (prevline, thisline);
 72.4032 +               prevfield = thisfield;
 72.4033 +               prevlen = thislen;
 72.4034 ++#if HAVE_MBRTOWC
 72.4035 ++              if (MB_CUR_MAX > 1)
 72.4036 ++                prevstate = thisstate;
 72.4037 ++#endif
 72.4038 +               first_group_printed = true;
 72.4039 +             }
 72.4040 +         }
 72.4041 +@@ -401,17 +619,26 @@ check_file (const char *infile, const ch
 72.4042 +       size_t prevlen;
 72.4043 +       uintmax_t match_count = 0;
 72.4044 +       bool first_delimiter = true;
 72.4045 ++#if HAVE_MBRTOWC
 72.4046 ++      mbstate_t prevstate;
 72.4047 ++#endif
 72.4048 + 
 72.4049 +       if (readlinebuffer_delim (prevline, stdin, delimiter) == 0)
 72.4050 +         goto closefiles;
 72.4051 +       prevfield = find_field (prevline);
 72.4052 +       prevlen = prevline->length - 1 - (prevfield - prevline->buffer);
 72.4053 ++#if HAVE_MBRTOWC
 72.4054 ++      prevstate = prevline->state;
 72.4055 ++#endif
 72.4056 + 
 72.4057 +       while (!feof (stdin))
 72.4058 +         {
 72.4059 +           bool match;
 72.4060 +           char *thisfield;
 72.4061 +           size_t thislen;
 72.4062 ++#if HAVE_MBRTOWC
 72.4063 ++          mbstate_t thisstate = thisline->state;
 72.4064 ++#endif
 72.4065 +           if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
 72.4066 +             {
 72.4067 +               if (ferror (stdin))
 72.4068 +@@ -420,6 +647,14 @@ check_file (const char *infile, const ch
 72.4069 +             }
 72.4070 +           thisfield = find_field (thisline);
 72.4071 +           thislen = thisline->length - 1 - (thisfield - thisline->buffer);
 72.4072 ++#if HAVE_MBRTOWC
 72.4073 ++          if (MB_CUR_MAX > 1)
 72.4074 ++            {
 72.4075 ++              match = !different_multi (thisfield, prevfield,
 72.4076 ++                                thislen, prevlen, thisstate, prevstate);
 72.4077 ++            }
 72.4078 ++          else
 72.4079 ++#endif
 72.4080 +           match = !different (thisfield, prevfield, thislen, prevlen);
 72.4081 +           match_count += match;
 72.4082 + 
 72.4083 +@@ -452,6 +687,9 @@ check_file (const char *infile, const ch
 72.4084 +               SWAP_LINES (prevline, thisline);
 72.4085 +               prevfield = thisfield;
 72.4086 +               prevlen = thislen;
 72.4087 ++#if HAVE_MBRTOWC
 72.4088 ++              prevstate = thisstate;
 72.4089 ++#endif
 72.4090 +               if (!match)
 72.4091 +                 match_count = 0;
 72.4092 +             }
 72.4093 +@@ -498,6 +736,19 @@ main (int argc, char **argv)
 72.4094 + 
 72.4095 +   atexit (close_stdout);
 72.4096 + 
 72.4097 ++#if HAVE_MBRTOWC
 72.4098 ++  if (MB_CUR_MAX > 1)
 72.4099 ++    {
 72.4100 ++      find_field = find_field_multi;
 72.4101 ++    }
 72.4102 ++  else
 72.4103 ++#endif
 72.4104 ++    {
 72.4105 ++      find_field = find_field_uni;
 72.4106 ++    }
 72.4107 ++
 72.4108 ++
 72.4109 ++
 72.4110 +   skip_chars = 0;
 72.4111 +   skip_fields = 0;
 72.4112 +   check_chars = SIZE_MAX;
 72.4113 +diff -Naurp coreutils-8.25-orig/tests/i18n/sort-month.sh coreutils-8.25/tests/i18n/sort-month.sh
 72.4114 +--- coreutils-8.25-orig/tests/i18n/sort-month.sh	1969-12-31 18:00:00.000000000 -0600
 72.4115 ++++ coreutils-8.25/tests/i18n/sort-month.sh	2016-02-08 19:07:10.312944654 -0600
 72.4116 +@@ -0,0 +1,34 @@
 72.4117 ++#!/bin/sh
 72.4118 ++# Verify sort -M multi-byte support.
 72.4119 ++
 72.4120 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 72.4121 ++print_ver_ sort
 72.4122 ++require_valgrind_
 72.4123 ++
 72.4124 ++# Skip this test if some deallocations are
 72.4125 ++# avoided at process end.
 72.4126 ++grep '^#define lint 1' $CONFIG_HEADER > /dev/null ||
 72.4127 ++  skip_ 'Allocation checks only work reliably in "lint" mode'
 72.4128 ++
 72.4129 ++export LC_ALL=en_US.UTF-8
 72.4130 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \
 72.4131 ++  || skip_ "No UTF-8 locale available"
 72.4132 ++
 72.4133 ++# Note the use of ɑ here which expands to
 72.4134 ++# a wider representation upon case conversion
 72.4135 ++# which triggered an assertion in sort -M
 72.4136 ++cat <<EOF > exp
 72.4137 ++.
 72.4138 ++ɑ
 72.4139 ++EOF
 72.4140 ++
 72.4141 ++
 72.4142 ++# check large mem leak with --month-sort
 72.4143 ++# https://bugzilla.redhat.com/show_bug.cgi?id=1259942
 72.4144 ++valgrind --leak-check=full \
 72.4145 ++         --error-exitcode=1 --errors-for-leak-kinds=definite \
 72.4146 ++         sort -M < exp > out || fail=1
 72.4147 ++compare exp out || { fail=1; cat out; }
 72.4148 ++
 72.4149 ++
 72.4150 ++Exit $fail
 72.4151 +diff -Naurp coreutils-8.25-orig/tests/i18n/sort.sh coreutils-8.25/tests/i18n/sort.sh
 72.4152 +--- coreutils-8.25-orig/tests/i18n/sort.sh	1969-12-31 18:00:00.000000000 -0600
 72.4153 ++++ coreutils-8.25/tests/i18n/sort.sh	2016-02-08 19:07:10.312944654 -0600
 72.4154 +@@ -0,0 +1,29 @@
 72.4155 ++#!/bin/sh
 72.4156 ++# Verify sort's multi-byte support.
 72.4157 ++
 72.4158 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 72.4159 ++print_ver_ sort
 72.4160 ++
 72.4161 ++export LC_ALL=en_US.UTF-8
 72.4162 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \
 72.4163 ++  || skip_ "No UTF-8 locale available"
 72.4164 ++
 72.4165 ++# Enable heap consistency checkng on older systems
 72.4166 ++export MALLOC_CHECK_=2
 72.4167 ++
 72.4168 ++
 72.4169 ++# check buffer overflow issue due to
 72.4170 ++# expanding multi-byte representation due to case conversion
 72.4171 ++# https://bugzilla.suse.com/show_bug.cgi?id=928749
 72.4172 ++cat <<EOF > exp
 72.4173 ++.
 72.4174 ++ɑ
 72.4175 ++EOF
 72.4176 ++cat <<EOF | sort -f > out || fail=1
 72.4177 ++.
 72.4178 ++ɑ
 72.4179 ++EOF
 72.4180 ++compare exp out || { fail=1; cat out; }
 72.4181 ++
 72.4182 ++
 72.4183 ++Exit $fail
 72.4184 +diff -Naurp coreutils-8.25-orig/tests/local.mk coreutils-8.25/tests/local.mk
 72.4185 +--- coreutils-8.25-orig/tests/local.mk	2016-01-16 12:18:13.000000000 -0600
 72.4186 ++++ coreutils-8.25/tests/local.mk	2016-02-08 19:07:10.313944658 -0600
 72.4187 +@@ -344,6 +344,9 @@ all_tests =					\
 72.4188 +   tests/misc/sort-discrim.sh			\
 72.4189 +   tests/misc/sort-files0-from.pl		\
 72.4190 +   tests/misc/sort-float.sh			\
 72.4191 ++  tests/misc/sort-mb-tests.sh			\
 72.4192 ++  tests/i18n/sort.sh				\
 72.4193 ++  tests/i18n/sort-month.sh			\
 72.4194 +   tests/misc/sort-merge.pl			\
 72.4195 +   tests/misc/sort-merge-fdlimit.sh		\
 72.4196 +   tests/misc/sort-month.sh			\
 72.4197 +diff -Naurp coreutils-8.25-orig/tests/misc/cut.pl coreutils-8.25/tests/misc/cut.pl
 72.4198 +--- coreutils-8.25-orig/tests/misc/cut.pl	2016-01-16 12:18:13.000000000 -0600
 72.4199 ++++ coreutils-8.25/tests/misc/cut.pl	2016-02-08 19:07:10.314944661 -0600
 72.4200 +@@ -23,9 +23,11 @@ use strict;
 72.4201 + # Turn off localization of executable's output.
 72.4202 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 72.4203 + 
 72.4204 +-my $mb_locale = $ENV{LOCALE_FR_UTF8};
 72.4205 ++my $mb_locale;
 72.4206 ++# uncommented enable multibyte paths
 72.4207 ++$mb_locale = $ENV{LOCALE_FR_UTF8};
 72.4208 + ! defined $mb_locale || $mb_locale eq 'none'
 72.4209 +-  and $mb_locale = 'C';
 72.4210 ++ and $mb_locale = 'C';
 72.4211 + 
 72.4212 + my $prog = 'cut';
 72.4213 + my $try = "Try '$prog --help' for more information.\n";
 72.4214 +@@ -240,6 +242,7 @@ if ($mb_locale ne 'C')
 72.4215 +         my @new_t = @$t;
 72.4216 +         my $test_name = shift @new_t;
 72.4217 + 
 72.4218 ++        next if ($test_name =~ "newline-[12][0-9]");
 72.4219 +         push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 72.4220 +       }
 72.4221 +     push @Tests, @new;
 72.4222 +diff -Naurp coreutils-8.25-orig/tests/misc/expand.pl coreutils-8.25/tests/misc/expand.pl
 72.4223 +--- coreutils-8.25-orig/tests/misc/expand.pl	2016-01-16 12:18:13.000000000 -0600
 72.4224 ++++ coreutils-8.25/tests/misc/expand.pl	2016-02-08 19:07:10.314944661 -0600
 72.4225 +@@ -23,6 +23,15 @@ use strict;
 72.4226 + # Turn off localization of executable's output.
 72.4227 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 72.4228 + 
 72.4229 ++#comment out next line to disable multibyte tests
 72.4230 ++my $mb_locale = $ENV{LOCALE_FR_UTF8};
 72.4231 ++! defined $mb_locale || $mb_locale eq 'none'
 72.4232 ++ and $mb_locale = 'C';
 72.4233 ++
 72.4234 ++my $prog = 'expand';
 72.4235 ++my $try = "Try \`$prog --help' for more information.\n";
 72.4236 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 72.4237 ++
 72.4238 + my @Tests =
 72.4239 +   (
 72.4240 +    ['t1', '--tabs=3',     {IN=>"a\tb"}, {OUT=>"a  b"}],
 72.4241 +@@ -31,6 +40,37 @@ my @Tests =
 72.4242 +    ['i2', '--tabs=3 -i', {IN=>" \ta\tb"}, {OUT=>"   a\tb"}],
 72.4243 +   );
 72.4244 + 
 72.4245 ++if ($mb_locale ne 'C')
 72.4246 ++  {
 72.4247 ++    # Duplicate each test vector, appending "-mb" to the test name and
 72.4248 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 72.4249 ++    # provide coverage for the distro-added multi-byte code paths.
 72.4250 ++    my @new;
 72.4251 ++    foreach my $t (@Tests)
 72.4252 ++      {
 72.4253 ++        my @new_t = @$t;
 72.4254 ++        my $test_name = shift @new_t;
 72.4255 ++
 72.4256 ++        # Depending on whether expand is multi-byte-patched,
 72.4257 ++        # it emits different diagnostics:
 72.4258 ++        #   non-MB: invalid byte or field list
 72.4259 ++        #   MB:     invalid byte, character or field list
 72.4260 ++        # Adjust the expected error output accordingly.
 72.4261 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 72.4262 ++            (@new_t))
 72.4263 ++          {
 72.4264 ++            my $sub = {ERR_SUBST => 's/, character//'};
 72.4265 ++            push @new_t, $sub;
 72.4266 ++            push @$t, $sub;
 72.4267 ++          }
 72.4268 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 72.4269 ++      }
 72.4270 ++    push @Tests, @new;
 72.4271 ++  }
 72.4272 ++
 72.4273 ++
 72.4274 ++@Tests = triple_test \@Tests;
 72.4275 ++
 72.4276 + my $save_temps = $ENV{DEBUG};
 72.4277 + my $verbose = $ENV{VERBOSE};
 72.4278 + 
 72.4279 +diff -Naurp coreutils-8.25-orig/tests/misc/fold.pl coreutils-8.25/tests/misc/fold.pl
 72.4280 +--- coreutils-8.25-orig/tests/misc/fold.pl	2016-01-16 12:18:13.000000000 -0600
 72.4281 ++++ coreutils-8.25/tests/misc/fold.pl	2016-02-08 19:07:10.314944661 -0600
 72.4282 +@@ -20,9 +20,18 @@ use strict;
 72.4283 + 
 72.4284 + (my $program_name = $0) =~ s|.*/||;
 72.4285 + 
 72.4286 ++my $prog = 'fold';
 72.4287 ++my $try = "Try \`$prog --help' for more information.\n";
 72.4288 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 72.4289 ++
 72.4290 + # Turn off localization of executable's output.
 72.4291 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 72.4292 + 
 72.4293 ++# uncommented to enable multibyte paths
 72.4294 ++my $mb_locale = $ENV{LOCALE_FR_UTF8};
 72.4295 ++! defined $mb_locale || $mb_locale eq 'none'
 72.4296 ++ and $mb_locale = 'C';
 72.4297 ++
 72.4298 + my @Tests =
 72.4299 +   (
 72.4300 +    ['s1', '-w2 -s', {IN=>"a\t"}, {OUT=>"a\n\t"}],
 72.4301 +@@ -31,9 +40,48 @@ my @Tests =
 72.4302 +    ['s4', '-w4 -s', {IN=>"abc ef\n"}, {OUT=>"abc \nef\n"}],
 72.4303 +   );
 72.4304 + 
 72.4305 ++# Add _POSIX2_VERSION=199209 to the environment of each test
 72.4306 ++# that uses an old-style option like +1.
 72.4307 ++if ($mb_locale ne 'C')
 72.4308 ++  {
 72.4309 ++    # Duplicate each test vector, appending "-mb" to the test name and
 72.4310 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 72.4311 ++    # provide coverage for the distro-added multi-byte code paths.
 72.4312 ++    my @new;
 72.4313 ++    foreach my $t (@Tests)
 72.4314 ++      {
 72.4315 ++        my @new_t = @$t;
 72.4316 ++        my $test_name = shift @new_t;
 72.4317 ++
 72.4318 ++        # Depending on whether fold is multi-byte-patched,
 72.4319 ++        # it emits different diagnostics:
 72.4320 ++        #   non-MB: invalid byte or field list
 72.4321 ++        #   MB:     invalid byte, character or field list
 72.4322 ++        # Adjust the expected error output accordingly.
 72.4323 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 72.4324 ++            (@new_t))
 72.4325 ++          {
 72.4326 ++            my $sub = {ERR_SUBST => 's/, character//'};
 72.4327 ++            push @new_t, $sub;
 72.4328 ++            push @$t, $sub;
 72.4329 ++          }
 72.4330 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 72.4331 ++      }
 72.4332 ++    push @Tests, @new;
 72.4333 ++  }
 72.4334 ++
 72.4335 ++@Tests = triple_test \@Tests;
 72.4336 ++
 72.4337 ++# Remember that triple_test creates from each test with exactly one "IN"
 72.4338 ++# file two more tests (.p and .r suffix on name) corresponding to reading
 72.4339 ++# input from a file and from a pipe.  The pipe-reading test would fail
 72.4340 ++# due to a race condition about 1 in 20 times.
 72.4341 ++# Remove the IN_PIPE version of the "output-is-input" test above.
 72.4342 ++# The others aren't susceptible because they have three inputs each.
 72.4343 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
 72.4344 ++
 72.4345 + my $save_temps = $ENV{DEBUG};
 72.4346 + my $verbose = $ENV{VERBOSE};
 72.4347 + 
 72.4348 +-my $prog = 'fold';
 72.4349 + my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose);
 72.4350 + exit $fail;
 72.4351 +diff -Naurp coreutils-8.25-orig/tests/misc/join.pl coreutils-8.25/tests/misc/join.pl
 72.4352 +--- coreutils-8.25-orig/tests/misc/join.pl	2016-01-16 12:18:13.000000000 -0600
 72.4353 ++++ coreutils-8.25/tests/misc/join.pl	2016-02-08 19:07:10.315944664 -0600
 72.4354 +@@ -25,6 +25,15 @@ my $limits = getlimits ();
 72.4355 + 
 72.4356 + my $prog = 'join';
 72.4357 + 
 72.4358 ++my $try = "Try \`$prog --help' for more information.\n";
 72.4359 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 72.4360 ++
 72.4361 ++my $mb_locale;
 72.4362 ++#Comment out next line to disable multibyte tests
 72.4363 ++$mb_locale = $ENV{LOCALE_FR_UTF8};
 72.4364 ++! defined $mb_locale || $mb_locale eq 'none'
 72.4365 ++  and $mb_locale = 'C';
 72.4366 ++
 72.4367 + my $delim = chr 0247;
 72.4368 + sub t_subst ($)
 72.4369 + {
 72.4370 +@@ -329,8 +338,49 @@ foreach my $t (@tv)
 72.4371 +     push @Tests, $new_ent;
 72.4372 +   }
 72.4373 + 
 72.4374 ++# Add _POSIX2_VERSION=199209 to the environment of each test
 72.4375 ++# that uses an old-style option like +1.
 72.4376 ++if ($mb_locale ne 'C')
 72.4377 ++  {
 72.4378 ++    # Duplicate each test vector, appending "-mb" to the test name and
 72.4379 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 72.4380 ++    # provide coverage for the distro-added multi-byte code paths.
 72.4381 ++    my @new;
 72.4382 ++    foreach my $t (@Tests)
 72.4383 ++      {
 72.4384 ++        my @new_t = @$t;
 72.4385 ++        my $test_name = shift @new_t;
 72.4386 ++
 72.4387 ++        # Depending on whether join is multi-byte-patched,
 72.4388 ++        # it emits different diagnostics:
 72.4389 ++        #   non-MB: invalid byte or field list
 72.4390 ++        #   MB:     invalid byte, character or field list
 72.4391 ++        # Adjust the expected error output accordingly.
 72.4392 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 72.4393 ++            (@new_t))
 72.4394 ++          {
 72.4395 ++            my $sub = {ERR_SUBST => 's/, character//'};
 72.4396 ++            push @new_t, $sub;
 72.4397 ++            push @$t, $sub;
 72.4398 ++          }
 72.4399 ++        #Adjust the output some error messages including test_name for mb
 72.4400 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR}}
 72.4401 ++             (@new_t))
 72.4402 ++          {
 72.4403 ++            my $sub2 = {ERR_SUBST => "s/$test_name-mb/$test_name/"};
 72.4404 ++            push @new_t, $sub2;
 72.4405 ++            push @$t, $sub2;
 72.4406 ++          }
 72.4407 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 72.4408 ++      }
 72.4409 ++    push @Tests, @new;
 72.4410 ++  }
 72.4411 ++
 72.4412 + @Tests = triple_test \@Tests;
 72.4413 + 
 72.4414 ++#skip invalid-j-mb test, it is failing because of the format
 72.4415 ++@Tests = grep {$_->[0] ne 'invalid-j-mb'} @Tests;
 72.4416 ++
 72.4417 + my $save_temps = $ENV{DEBUG};
 72.4418 + my $verbose = $ENV{VERBOSE};
 72.4419 + 
 72.4420 +diff -Naurp coreutils-8.25-orig/tests/misc/sort-mb-tests.sh coreutils-8.25/tests/misc/sort-mb-tests.sh
 72.4421 +--- coreutils-8.25-orig/tests/misc/sort-mb-tests.sh	1969-12-31 18:00:00.000000000 -0600
 72.4422 ++++ coreutils-8.25/tests/misc/sort-mb-tests.sh	2016-02-08 19:07:10.315944664 -0600
 72.4423 +@@ -0,0 +1,45 @@
 72.4424 ++#!/bin/sh
 72.4425 ++# Verify sort's multi-byte support.
 72.4426 ++
 72.4427 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 72.4428 ++print_ver_ sort
 72.4429 ++
 72.4430 ++export LC_ALL=en_US.UTF-8
 72.4431 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \
 72.4432 ++  || skip_ "No UTF-8 locale available"
 72.4433 ++
 72.4434 ++
 72.4435 ++cat <<EOF > exp
 72.4436 ++Banana@5
 72.4437 ++Apple@10
 72.4438 ++Citrus@20
 72.4439 ++Cherry@30
 72.4440 ++EOF
 72.4441 ++
 72.4442 ++cat <<EOF | sort -t @ -k2 -n > out || fail=1
 72.4443 ++Apple@10
 72.4444 ++Banana@5
 72.4445 ++Citrus@20
 72.4446 ++Cherry@30
 72.4447 ++EOF
 72.4448 ++
 72.4449 ++compare exp out || { fail=1; cat out; }
 72.4450 ++
 72.4451 ++
 72.4452 ++cat <<EOF > exp
 72.4453 ++Citrus@AA20@@5
 72.4454 ++Cherry@AA30@@10
 72.4455 ++Apple@AA10@@20
 72.4456 ++Banana@AA5@@30
 72.4457 ++EOF
 72.4458 ++
 72.4459 ++cat <<EOF | sort -t @ -k4 -n > out || fail=1
 72.4460 ++Apple@AA10@@20
 72.4461 ++Banana@AA5@@30
 72.4462 ++Citrus@AA20@@5
 72.4463 ++Cherry@AA30@@10
 72.4464 ++EOF
 72.4465 ++
 72.4466 ++compare exp out || { fail=1; cat out; }
 72.4467 ++
 72.4468 ++Exit $fail
 72.4469 +diff -Naurp coreutils-8.25-orig/tests/misc/sort-merge.pl coreutils-8.25/tests/misc/sort-merge.pl
 72.4470 +--- coreutils-8.25-orig/tests/misc/sort-merge.pl	2016-01-16 12:18:14.000000000 -0600
 72.4471 ++++ coreutils-8.25/tests/misc/sort-merge.pl	2016-02-08 19:07:10.316944667 -0600
 72.4472 +@@ -26,6 +26,15 @@ my $prog = 'sort';
 72.4473 + # Turn off localization of executable's output.
 72.4474 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 72.4475 + 
 72.4476 ++my $mb_locale;
 72.4477 ++# uncommented according to upstream commit enabling multibyte paths
 72.4478 ++$mb_locale = $ENV{LOCALE_FR_UTF8};
 72.4479 ++! defined $mb_locale || $mb_locale eq 'none'
 72.4480 ++ and $mb_locale = 'C';
 72.4481 ++
 72.4482 ++my $try = "Try \`$prog --help' for more information.\n";
 72.4483 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 72.4484 ++
 72.4485 + # three empty files and one that says 'foo'
 72.4486 + my @inputs = (+(map{{IN=> {"empty$_"=> ''}}}1..3), {IN=> {foo=> "foo\n"}});
 72.4487 + 
 72.4488 +@@ -77,6 +86,39 @@ my @Tests =
 72.4489 +         {OUT=>$big_input}],
 72.4490 +     );
 72.4491 + 
 72.4492 ++# Add _POSIX2_VERSION=199209 to the environment of each test
 72.4493 ++# that uses an old-style option like +1.
 72.4494 ++if ($mb_locale ne 'C')
 72.4495 ++  {
 72.4496 ++    # Duplicate each test vector, appending "-mb" to the test name and
 72.4497 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 72.4498 ++    # provide coverage for the distro-added multi-byte code paths.
 72.4499 ++    my @new;
 72.4500 ++    foreach my $t (@Tests)
 72.4501 ++      {
 72.4502 ++        my @new_t = @$t;
 72.4503 ++        my $test_name = shift @new_t;
 72.4504 ++
 72.4505 ++        # Depending on whether sort is multi-byte-patched,
 72.4506 ++        # it emits different diagnostics:
 72.4507 ++        #   non-MB: invalid byte or field list
 72.4508 ++        #   MB:     invalid byte, character or field list
 72.4509 ++        # Adjust the expected error output accordingly.
 72.4510 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 72.4511 ++            (@new_t))
 72.4512 ++          {
 72.4513 ++            my $sub = {ERR_SUBST => 's/, character//'};
 72.4514 ++            push @new_t, $sub;
 72.4515 ++            push @$t, $sub;
 72.4516 ++          }
 72.4517 ++        next if ($test_name =~ "nmerge-.");
 72.4518 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 72.4519 ++      }
 72.4520 ++    push @Tests, @new;
 72.4521 ++  }
 72.4522 ++
 72.4523 ++@Tests = triple_test \@Tests;
 72.4524 ++
 72.4525 + my $save_temps = $ENV{DEBUG};
 72.4526 + my $verbose = $ENV{VERBOSE};
 72.4527 + 
 72.4528 +diff -Naurp coreutils-8.25-orig/tests/misc/sort.pl coreutils-8.25/tests/misc/sort.pl
 72.4529 +--- coreutils-8.25-orig/tests/misc/sort.pl	2016-01-16 12:18:14.000000000 -0600
 72.4530 ++++ coreutils-8.25/tests/misc/sort.pl	2016-02-08 19:07:10.316944667 -0600
 72.4531 +@@ -24,10 +24,15 @@ my $prog = 'sort';
 72.4532 + # Turn off localization of executable's output.
 72.4533 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 72.4534 + 
 72.4535 +-my $mb_locale = $ENV{LOCALE_FR_UTF8};
 72.4536 ++my $mb_locale;
 72.4537 ++#Comment out next line to disable multibyte tests
 72.4538 ++$mb_locale = $ENV{LOCALE_FR_UTF8};
 72.4539 + ! defined $mb_locale || $mb_locale eq 'none'
 72.4540 +   and $mb_locale = 'C';
 72.4541 + 
 72.4542 ++my $try = "Try \`$prog --help' for more information.\n";
 72.4543 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 72.4544 ++
 72.4545 + # Since each test is run with a file name and with redirected stdin,
 72.4546 + # the name in the diagnostic is either the file name or "-".
 72.4547 + # Normalize each diagnostic to use '-'.
 72.4548 +@@ -424,6 +429,38 @@ foreach my $t (@Tests)
 72.4549 +       }
 72.4550 +   }
 72.4551 + 
 72.4552 ++if ($mb_locale ne 'C')
 72.4553 ++   {
 72.4554 ++    # Duplicate each test vector, appending "-mb" to the test name and
 72.4555 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 72.4556 ++    # provide coverage for the distro-added multi-byte code paths.
 72.4557 ++    my @new;
 72.4558 ++    foreach my $t (@Tests)
 72.4559 ++       {
 72.4560 ++        my @new_t = @$t;
 72.4561 ++        my $test_name = shift @new_t;
 72.4562 ++
 72.4563 ++        # Depending on whether sort is multi-byte-patched,
 72.4564 ++        # it emits different diagnostics:
 72.4565 ++        #   non-MB: invalid byte or field list
 72.4566 ++        #   MB:     invalid byte, character or field list
 72.4567 ++        # Adjust the expected error output accordingly.
 72.4568 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 72.4569 ++            (@new_t))
 72.4570 ++          {
 72.4571 ++            my $sub = {ERR_SUBST => 's/, character//'};
 72.4572 ++            push @new_t, $sub;
 72.4573 ++            push @$t, $sub;
 72.4574 ++          }
 72.4575 ++        #disable several failing tests until investigation, disable all tests with envvars set
 72.4576 ++        next if (grep {ref $_ eq 'HASH' && exists $_->{ENV}} (@new_t));
 72.4577 ++        next if ($test_name =~ "18g" or $test_name =~ "sort-numeric" or $test_name =~ "08[ab]" or $test_name =~ "03[def]" or $test_name =~ "h4" or $test_name =~ "n1" or $test_name =~ "2[01]a");
 72.4578 ++        next if ($test_name =~ "11[ab]"); # avoid FP: expected result differs to MB result due to collation rules.
 72.4579 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 72.4580 ++       }
 72.4581 ++    push @Tests, @new;
 72.4582 ++   }
 72.4583 ++
 72.4584 + @Tests = triple_test \@Tests;
 72.4585 + 
 72.4586 + # Remember that triple_test creates from each test with exactly one "IN"
 72.4587 +@@ -433,6 +470,7 @@ foreach my $t (@Tests)
 72.4588 + # Remove the IN_PIPE version of the "output-is-input" test above.
 72.4589 + # The others aren't susceptible because they have three inputs each.
 72.4590 + @Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
 72.4591 ++@Tests = grep {$_->[0] ne 'output-is-input-mb.p'} @Tests;
 72.4592 + 
 72.4593 + my $save_temps = $ENV{DEBUG};
 72.4594 + my $verbose = $ENV{VERBOSE};
 72.4595 +diff -Naurp coreutils-8.25-orig/tests/misc/unexpand.pl coreutils-8.25/tests/misc/unexpand.pl
 72.4596 +--- coreutils-8.25-orig/tests/misc/unexpand.pl	2016-01-16 12:18:14.000000000 -0600
 72.4597 ++++ coreutils-8.25/tests/misc/unexpand.pl	2016-02-08 19:07:10.317944671 -0600
 72.4598 +@@ -27,6 +27,14 @@ my $limits = getlimits ();
 72.4599 + 
 72.4600 + my $prog = 'unexpand';
 72.4601 + 
 72.4602 ++# comment out next line to disable multibyte tests
 72.4603 ++my $mb_locale = $ENV{LOCALE_FR_UTF8};
 72.4604 ++! defined $mb_locale || $mb_locale eq 'none'
 72.4605 ++ and $mb_locale = 'C';
 72.4606 ++
 72.4607 ++my $try = "Try \`$prog --help' for more information.\n";
 72.4608 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 72.4609 ++
 72.4610 + my @Tests =
 72.4611 +     (
 72.4612 +      ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}],
 72.4613 +@@ -92,6 +100,37 @@ my @Tests =
 72.4614 +       {EXIT => 1}, {ERR => "$prog: tab stop value is too large\n"}],
 72.4615 +     );
 72.4616 + 
 72.4617 ++if ($mb_locale ne 'C')
 72.4618 ++  {
 72.4619 ++    # Duplicate each test vector, appending "-mb" to the test name and
 72.4620 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 72.4621 ++    # provide coverage for the distro-added multi-byte code paths.
 72.4622 ++    my @new;
 72.4623 ++    foreach my $t (@Tests)
 72.4624 ++      {
 72.4625 ++        my @new_t = @$t;
 72.4626 ++        my $test_name = shift @new_t;
 72.4627 ++
 72.4628 ++        # Depending on whether unexpand is multi-byte-patched,
 72.4629 ++        # it emits different diagnostics:
 72.4630 ++        #   non-MB: invalid byte or field list
 72.4631 ++        #   MB:     invalid byte, character or field list
 72.4632 ++        # Adjust the expected error output accordingly.
 72.4633 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 72.4634 ++            (@new_t))
 72.4635 ++          {
 72.4636 ++            my $sub = {ERR_SUBST => 's/, character//'};
 72.4637 ++            push @new_t, $sub;
 72.4638 ++            push @$t, $sub;
 72.4639 ++          }
 72.4640 ++        next if ($test_name =~ 'b-1');
 72.4641 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 72.4642 ++      }
 72.4643 ++    push @Tests, @new;
 72.4644 ++  }
 72.4645 ++
 72.4646 ++@Tests = triple_test \@Tests;
 72.4647 ++
 72.4648 + my $save_temps = $ENV{DEBUG};
 72.4649 + my $verbose = $ENV{VERBOSE};
 72.4650 + 
 72.4651 +diff -Naurp coreutils-8.25-orig/tests/misc/uniq.pl coreutils-8.25/tests/misc/uniq.pl
 72.4652 +--- coreutils-8.25-orig/tests/misc/uniq.pl	2016-01-16 12:18:14.000000000 -0600
 72.4653 ++++ coreutils-8.25/tests/misc/uniq.pl	2016-02-08 19:07:10.317944671 -0600
 72.4654 +@@ -23,9 +23,17 @@ my $limits = getlimits ();
 72.4655 + my $prog = 'uniq';
 72.4656 + my $try = "Try '$prog --help' for more information.\n";
 72.4657 + 
 72.4658 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 72.4659 ++
 72.4660 + # Turn off localization of executable's output.
 72.4661 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 72.4662 + 
 72.4663 ++my $mb_locale;
 72.4664 ++#Comment out next line to disable multibyte tests
 72.4665 ++$mb_locale = $ENV{LOCALE_FR_UTF8};
 72.4666 ++! defined $mb_locale || $mb_locale eq 'none'
 72.4667 ++  and $mb_locale = 'C';
 72.4668 ++
 72.4669 + # When possible, create a "-z"-testing variant of each test.
 72.4670 + sub add_z_variants($)
 72.4671 + {
 72.4672 +@@ -262,6 +270,53 @@ foreach my $t (@Tests)
 72.4673 +       and push @$t, {ENV=>'_POSIX2_VERSION=199209'};
 72.4674 +   }
 72.4675 + 
 72.4676 ++if ($mb_locale ne 'C')
 72.4677 ++  {
 72.4678 ++    # Duplicate each test vector, appending "-mb" to the test name and
 72.4679 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 72.4680 ++    # provide coverage for the distro-added multi-byte code paths.
 72.4681 ++    my @new;
 72.4682 ++    foreach my $t (@Tests)
 72.4683 ++      {
 72.4684 ++        my @new_t = @$t;
 72.4685 ++        my $test_name = shift @new_t;
 72.4686 ++
 72.4687 ++        # Depending on whether uniq is multi-byte-patched,
 72.4688 ++        # it emits different diagnostics:
 72.4689 ++        #   non-MB: invalid byte or field list
 72.4690 ++        #   MB:     invalid byte, character or field list
 72.4691 ++        # Adjust the expected error output accordingly.
 72.4692 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 72.4693 ++            (@new_t))
 72.4694 ++          {
 72.4695 ++            my $sub = {ERR_SUBST => 's/, character//'};
 72.4696 ++            push @new_t, $sub;
 72.4697 ++            push @$t, $sub;
 72.4698 ++          }
 72.4699 ++        # In test #145, replace the each ‘...’ by '...'.
 72.4700 ++        if ($test_name =~ "145")
 72.4701 ++          {
 72.4702 ++            my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"};
 72.4703 ++            push @new_t, $sub;
 72.4704 ++            push @$t, $sub;
 72.4705 ++          }
 72.4706 ++        next if (   $test_name =~ "schar"
 72.4707 ++                 or $test_name =~ "^obs-plus"
 72.4708 ++                 or $test_name =~ "119");
 72.4709 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 72.4710 ++      }
 72.4711 ++    push @Tests, @new;
 72.4712 ++   }
 72.4713 ++
 72.4714 ++# Remember that triple_test creates from each test with exactly one "IN"
 72.4715 ++# file two more tests (.p and .r suffix on name) corresponding to reading
 72.4716 ++# input from a file and from a pipe.  The pipe-reading test would fail
 72.4717 ++# due to a race condition about 1 in 20 times.
 72.4718 ++# Remove the IN_PIPE version of the "output-is-input" test above.
 72.4719 ++# The others aren't susceptible because they have three inputs each.
 72.4720 ++
 72.4721 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
 72.4722 ++
 72.4723 + @Tests = add_z_variants \@Tests;
 72.4724 + @Tests = triple_test \@Tests;
 72.4725 + 
 72.4726 +diff -Naurp coreutils-8.25-orig/tests/pr/pr-tests.pl coreutils-8.25/tests/pr/pr-tests.pl
 72.4727 +--- coreutils-8.25-orig/tests/pr/pr-tests.pl	2016-01-16 12:18:14.000000000 -0600
 72.4728 ++++ coreutils-8.25/tests/pr/pr-tests.pl	2016-02-08 19:07:10.318944674 -0600
 72.4729 +@@ -24,6 +24,15 @@ use strict;
 72.4730 + my $prog = 'pr';
 72.4731 + my $normalize_strerror = "s/': .*/'/";
 72.4732 + 
 72.4733 ++my $mb_locale;
 72.4734 ++#Uncomment the following line to enable multibyte tests
 72.4735 ++$mb_locale = $ENV{LOCALE_FR_UTF8};
 72.4736 ++! defined $mb_locale || $mb_locale eq 'none'
 72.4737 ++  and $mb_locale = 'C';
 72.4738 ++
 72.4739 ++my $try = "Try \`$prog --help' for more information.\n";
 72.4740 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 72.4741 ++
 72.4742 + my @tv = (
 72.4743 + 
 72.4744 + # -b option is no longer an official option. But it's still working to
 72.4745 +@@ -467,8 +476,48 @@ push @Tests,
 72.4746 +     {IN=>{3=>"x\ty\tz\n"}},
 72.4747 +      {OUT=>join("\t", qw(a b c m n o x y z)) . "\n"} ];
 72.4748 + 
 72.4749 ++# Add _POSIX2_VERSION=199209 to the environment of each test
 72.4750 ++# that uses an old-style option like +1.
 72.4751 ++if ($mb_locale ne 'C')
 72.4752 ++  {
 72.4753 ++    # Duplicate each test vector, appending "-mb" to the test name and
 72.4754 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 72.4755 ++    # provide coverage for the distro-added multi-byte code paths.
 72.4756 ++    my @new;
 72.4757 ++    foreach my $t (@Tests)
 72.4758 ++      {
 72.4759 ++        my @new_t = @$t;
 72.4760 ++        my $test_name = shift @new_t;
 72.4761 ++
 72.4762 ++        # Depending on whether pr is multi-byte-patched,
 72.4763 ++        # it emits different diagnostics:
 72.4764 ++        #   non-MB: invalid byte or field list
 72.4765 ++        #   MB:     invalid byte, character or field list
 72.4766 ++        # Adjust the expected error output accordingly.
 72.4767 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 72.4768 ++            (@new_t))
 72.4769 ++          {
 72.4770 ++            my $sub = {ERR_SUBST => 's/, character//'};
 72.4771 ++            push @new_t, $sub;
 72.4772 ++            push @$t, $sub;
 72.4773 ++          }
 72.4774 ++        #temporarily skip some failing tests
 72.4775 ++        next if ($test_name =~ "col-0" or $test_name =~ "col-inval");
 72.4776 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 72.4777 ++      }
 72.4778 ++    push @Tests, @new;
 72.4779 ++  }
 72.4780 ++
 72.4781 + @Tests = triple_test \@Tests;
 72.4782 + 
 72.4783 ++# Remember that triple_test creates from each test with exactly one "IN"
 72.4784 ++# file two more tests (.p and .r suffix on name) corresponding to reading
 72.4785 ++# input from a file and from a pipe.  The pipe-reading test would fail
 72.4786 ++# due to a race condition about 1 in 20 times.
 72.4787 ++# Remove the IN_PIPE version of the "output-is-input" test above.
 72.4788 ++# The others aren't susceptible because they have three inputs each.
 72.4789 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
 72.4790 ++
 72.4791 + my $save_temps = $ENV{DEBUG};
 72.4792 + my $verbose = $ENV{VERBOSE};
 72.4793 + 
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/coreutils/stuff/patches/coreutils-fix-po.patch	Sat May 27 16:55:17 2017 +0300
    73.3 @@ -0,0 +1,84 @@
    73.4 +--- a/po/nb.po
    73.5 ++++ b/po/nb.po
    73.6 +@@ -2721,7 +2721,7 @@
    73.7 + "A line OFFSET is a required '+' or '-' followed by a positive integer.\n"
    73.8 + msgstr ""
    73.9 + "\n"
   73.10 +-"\vMØNSTER må utformes slik:\n"
   73.11 ++"MØNSTER må utformes slik:\n"
   73.12 + "  INTEGER            kopier frem til - men ikke inkludert - angitt "
   73.13 + "linjenummer\n"
   73.14 + "  /REGEXP/[OFFSET]   kopier frem til - men ikke inkludert - en samsvarende "
   73.15 +@@ -7132,7 +7132,7 @@
   73.16 + "Multiple fields/ranges can be separated with commas\n"
   73.17 + msgstr ""
   73.18 + "\n"
   73.19 +-"\vFELT støtter feltrekkevidder i cut(1)-stil:\n"
   73.20 ++"FELT støtter feltrekkevidder i cut(1)-stil:\n"
   73.21 + "  N    N'te byte, tegn eller felt, talt fra 1\n"
   73.22 + "  N-   fra N'te byte, tegn eller felt, til slutten av linja\n"
   73.23 + "  N-M  fra N'te til M'te (inklusive) byte, tegn eller felt\n"
   73.24 +--- a/po/sl.po
   73.25 ++++ b/po/sl.po
   73.26 +@@ -2641,7 +2641,7 @@
   73.27 + #: src/csplit.c:1299
   73.28 + #, c-format
   73.29 + msgid "invalid conversion specifier in suffix: \\%.3o"
   73.30 +-msgstr "neveljavno določilo pretvorbe v priponi: \\\\%.3o"
   73.31 ++msgstr "neveljavno določilo pretvorbe v priponi: \\%.3o"
   73.32 + 
   73.33 + #: src/csplit.c:1304
   73.34 + #, c-format
   73.35 +@@ -6711,7 +6711,7 @@
   73.36 + "ločitvena\n"
   73.37 + "znaka za ločevanje logičnih strani; če je drugi znak izpuščen, se "
   73.38 + "privzame :.\n"
   73.39 +-"Uporabite \\\\\\\\ za \\\\. SLOG je nekaj od naštetega:\n"
   73.40 ++"Uporabite \\\\ za \\. SLOG je nekaj od naštetega:\n"
   73.41 + 
   73.42 + #: src/nl.c:211
   73.43 + msgid ""
   73.44 +@@ -7951,8 +7951,8 @@
   73.45 + msgstr ""
   73.46 + "  -h, --header=ZGLAVJE\n"
   73.47 + "                    uporabimo navedeno osredinjeno ZGLAVJE namesto imena\n"
   73.48 +-"                    datoteke; -h \\\"\\\" izpiše prazno vrstica; ne "
   73.49 +-"uporabljajte -h\\\"\\\"\n"
   73.50 ++"                    datoteke; -h \"\" izpiše prazno vrstica; ne "
   73.51 ++"uporabljajte -h\"\"\n"
   73.52 + "  -i[ZNAK[ŠIRINA]], --output-tabs[=ZNAK[ŠIRINA]]\n"
   73.53 + "                    presledke skrčimo v ZNAK (privzeto TAB) do ŠIRINE\n"
   73.54 + "                    tabulatorja (privzeto 8)\n"
   73.55 +@@ -12078,15 +12078,15 @@
   73.56 + "MNOŽICE določajo nizi znakov. Večinoma predstavljajo sebe, posebej pa se\n"
   73.57 + "tolmačijo naslednja zaporedja:\n"
   73.58 + "\n"
   73.59 +-"  \\\\NNN            znak z osmiško kodo NNN (dolžina 1, 2 ali 3 osmiške "
   73.60 ++"  \\NNN            znak z osmiško kodo NNN (dolžina 1, 2 ali 3 osmiške "
   73.61 + "števke)\n"
   73.62 +-"  \\\\\\\\             obratna poševnica\n"
   73.63 +-"  \\\\a              zvonček\n"
   73.64 +-"  \\\\b              pomik za en znak v levo\n"
   73.65 +-"  \\\\f              skok na novo stran\n"
   73.66 +-"  \\\\n              skok v novo vrstico\n"
   73.67 +-"  \\\\r              pomik na levi rob\n"
   73.68 +-"  \\\\t              vodoravni tabulator\n"
   73.69 ++"  \\\\             obratna poševnica\n"
   73.70 ++"  \\a              zvonček\n"
   73.71 ++"  \\b              pomik za en znak v levo\n"
   73.72 ++"  \\f              skok na novo stran\n"
   73.73 ++"  \\n              skok v novo vrstico\n"
   73.74 ++"  \\r              pomik na levi rob\n"
   73.75 ++"  \\t              vodoravni tabulator\n"
   73.76 + 
   73.77 + #: src/tr.c:317
   73.78 + msgid ""
   73.79 +@@ -12100,7 +12100,7 @@
   73.80 + "  [:cntrl:]       all control characters\n"
   73.81 + "  [:digit:]       all digits\n"
   73.82 + msgstr ""
   73.83 +-"  \\\\v              navpični tabulator\n"
   73.84 ++"  \\v              navpični tabulator\n"
   73.85 + "  ZNAK1-ZNAK2     naraščajoče zaporedje znakov od ZNAKA1 do ZNAKA2\n"
   73.86 + "  [ZNAK1-ZNAK2]   isto kot ZNAK1-ZNAK2, če to uporabljata obe množici\n"
   73.87 + "  [ZNAK*]         v MNOŽICI 2; toliko ponovitev ZNAKA kot v MNOŽICI 1\n"
    74.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.2 +++ b/coreutils/stuff/patches/series	Sat May 27 16:55:17 2017 +0300
    74.3 @@ -0,0 +1,3 @@
    74.4 +coreutils-8.25-i18n-2.patch
    74.5 +uname.u
    74.6 +coreutils-fix-po.patch
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/coreutils/stuff/patches/uname.u	Sat May 27 16:55:17 2017 +0300
    75.3 @@ -0,0 +1,173 @@
    75.4 +On linux platforms, grok /proc/cpuinfo for the CPU/vendor info.
    75.5 +
    75.6 +Prob not suitable for upstream seeing as how it's 100% linux-specific
    75.7 +http://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html
    75.8 +
    75.9 +Patch originally by Carlos E. Gorges <carlos@techlinux.com.br>, but 
   75.10 +heavily reworked to suck less.
   75.11 +
   75.12 +To add support for additional platforms, check out the show_cpuinfo()
   75.13 +func in the linux/arch/<ARCH>/ source tree of the kernel.
   75.14 +
   75.15 +--- coreutils/src/uname.c
   75.16 ++++ coreutils/src/uname.c
   75.17 +@@ -50,6 +50,11 @@
   75.18 + # include <mach-o/arch.h>
   75.19 + #endif
   75.20 + 
   75.21 ++#if defined(__linux__)
   75.22 ++# define USE_PROCINFO
   75.23 ++# define UNAME_HARDWARE_PLATFORM
   75.24 ++#endif
   75.25 ++
   75.26 + #include "system.h"
   75.27 + #include "error.h"
   75.28 + #include "quote.h"
   75.29 +@@ -138,6 +143,117 @@
   75.30 +   exit (status);
   75.31 + }
   75.32 + 
   75.33 ++#if defined(USE_PROCINFO)
   75.34 ++
   75.35 ++# if defined(__s390__) || defined(__s390x__)
   75.36 ++#  define CPUINFO_FILE    "/proc/sysinfo"
   75.37 ++#  define CPUINFO_FORMAT  "%64[^\t :]%*[ :]%256[^\n]%c"
   75.38 ++# else
   75.39 ++#  define CPUINFO_FILE    "/proc/cpuinfo"
   75.40 ++#  define CPUINFO_FORMAT  "%64[^\t:]\t:%256[^\n]%c"
   75.41 ++# endif
   75.42 ++
   75.43 ++# define PROCINFO_PROCESSOR      0
   75.44 ++# define PROCINFO_HARDWARE_PLATFORM 1
   75.45 ++
   75.46 ++static void __eat_cpuinfo_space(char *buf)
   75.47 ++{
   75.48 ++	/* first eat trailing space */
   75.49 ++	char *tmp = buf + strlen(buf) - 1;
   75.50 ++	while (tmp > buf && isspace(*tmp))
   75.51 ++		*tmp-- = '\0';
   75.52 ++	/* then eat leading space */
   75.53 ++	tmp = buf;
   75.54 ++	while (*tmp && isspace(*tmp))
   75.55 ++		tmp++;
   75.56 ++	if (tmp != buf)
   75.57 ++		memmove(buf, tmp, strlen(tmp)+1);
   75.58 ++	/* finally collapse whitespace */
   75.59 ++	tmp = buf;
   75.60 ++	while (tmp[0] && tmp[1]) {
   75.61 ++		if (isspace(tmp[0]) && isspace(tmp[1])) {
   75.62 ++			memmove(tmp, tmp+1, strlen(tmp));
   75.63 ++			continue;
   75.64 ++		}
   75.65 ++		++tmp;
   75.66 ++	}
   75.67 ++}
   75.68 ++
   75.69 ++static int __linux_procinfo(int x, char *fstr, size_t s)
   75.70 ++{
   75.71 ++	FILE *fp;
   75.72 ++
   75.73 ++	char *procinfo_keys[] = {
   75.74 ++		/* --processor --hardware-platform */
   75.75 ++		#if defined(__alpha__)
   75.76 ++			"cpu model", "system type"
   75.77 ++		#elif defined(__arm__)
   75.78 ++			"Processor", "Hardware"
   75.79 ++		#elif defined(__avr32__)
   75.80 ++			"processor", "cpu family"
   75.81 ++		#elif defined(__bfin__)
   75.82 ++			"CPU", "BOARD Name"
   75.83 ++		#elif defined(__cris__)
   75.84 ++			"cpu", "cpu model"
   75.85 ++		#elif defined(__frv__)
   75.86 ++			"CPU-Core", "System"
   75.87 ++		#elif defined(__i386__) || defined(__x86_64__)
   75.88 ++			"model name", "vendor_id"
   75.89 ++		#elif defined(__ia64__)
   75.90 ++			"family", "vendor"
   75.91 ++		#elif defined(__hppa__)
   75.92 ++			"cpu", "model"
   75.93 ++		#elif defined(__m68k__)
   75.94 ++			"CPU", "MMU"
   75.95 ++		#elif defined(__mips__)
   75.96 ++			"cpu model", "system type"
   75.97 ++		#elif defined(__powerpc__) || defined(__powerpc64__)
   75.98 ++			"cpu", "machine"
   75.99 ++		#elif defined(__s390__) || defined(__s390x__)
  75.100 ++			"Type", "Manufacturer"
  75.101 ++		#elif defined(__sh__)
  75.102 ++			"cpu type", "machine"
  75.103 ++		#elif defined(sparc) || defined(__sparc__)
  75.104 ++			"type", "cpu"
  75.105 ++		#elif defined(__vax__)
  75.106 ++			"cpu type", "cpu"
  75.107 ++		#else
  75.108 ++			"unknown", "unknown"
  75.109 ++		#endif
  75.110 ++	};
  75.111 ++
  75.112 ++	if ((fp = fopen(CPUINFO_FILE, "r")) != NULL) {
  75.113 ++		char key[65], value[257], eol, *ret = NULL;
  75.114 ++
  75.115 ++		while (fscanf(fp, CPUINFO_FORMAT, key, value, &eol) != EOF) {
  75.116 ++			__eat_cpuinfo_space(key);
  75.117 ++			if (!strcmp(key, procinfo_keys[x])) {
  75.118 ++				__eat_cpuinfo_space(value);
  75.119 ++				ret = value;
  75.120 ++				break;
  75.121 ++			}
  75.122 ++			if (eol != '\n') {
  75.123 ++				/* we need two fscanf's here in case the previous
  75.124 ++				 * length limit caused us to read right up to the
  75.125 ++				 * newline ... doing "%*[^\n]\n" wont eat the newline
  75.126 ++				 */
  75.127 ++				fscanf(fp, "%*[^\n]");
  75.128 ++				fscanf(fp, "\n");
  75.129 ++			}
  75.130 ++		}
  75.131 ++		fclose(fp);
  75.132 ++
  75.133 ++		if (ret) {
  75.134 ++			strncpy(fstr, ret, s);
  75.135 ++			return 0;
  75.136 ++		}
  75.137 ++	}
  75.138 ++
  75.139 ++	return -1;
  75.140 ++}
  75.141 ++
  75.142 ++#endif
  75.143 ++
  75.144 + /* Print ELEMENT, preceded by a space if something has already been
  75.145 +    printed.  */
  75.146 + 
  75.147 +@@ -250,10 +344,14 @@ main (int argc, char **argv)
  75.148 +   if (toprint & PRINT_PROCESSOR)
  75.149 +     {
  75.150 +       char const *element = unknown;
  75.151 +-#if HAVE_SYSINFO && defined SI_ARCHITECTURE
  75.152 ++#if ( HAVE_SYSINFO && defined SI_ARCHITECTURE ) || defined(USE_PROCINFO)
  75.153 +       {
  75.154 +         static char processor[257];
  75.155 ++#if defined(USE_PROCINFO)
  75.156 ++        if (0 <= __linux_procinfo (PROCINFO_PROCESSOR, processor, sizeof processor))
  75.157 ++#else
  75.158 +         if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
  75.159 ++#endif
  75.160 +           element = processor;
  75.161 +       }
  75.162 + #endif
  75.163 +@@ -306,9 +404,13 @@ main (int argc, char **argv)
  75.164 +       if (element == unknown)
  75.165 +         {
  75.166 +           static char hardware_platform[257];
  75.167 ++#if defined(USE_PROCINFO)
  75.168 ++          if (0 <= __linux_procinfo (PROCINFO_HARDWARE_PLATFORM, hardware_platform, sizeof hardware_platform))
  75.169 ++#else
  75.170 +           size_t s = sizeof hardware_platform;
  75.171 +           static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };
  75.172 +           if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)
  75.173 ++#endif
  75.174 +             element = hardware_platform;
  75.175 +         }
  75.176 + #endif
    76.1 --- a/coreutils/stuff/sigcontext.h	Sat May 27 16:29:45 2017 +0300
    76.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.3 @@ -1,143 +0,0 @@
    76.4 -#ifndef _ASM_X86_SIGCONTEXT_H
    76.5 -#define _ASM_X86_SIGCONTEXT_H
    76.6 -
    76.7 -#include <asm/types.h>
    76.8 -
    76.9 -#ifdef __i386__
   76.10 -/*
   76.11 - * As documented in the iBCS2 standard..
   76.12 - *
   76.13 - * The first part of "struct _fpstate" is just the normal i387
   76.14 - * hardware setup, the extra "status" word is used to save the
   76.15 - * coprocessor status word before entering the handler.
   76.16 - *
   76.17 - * Pentium III FXSR, SSE support
   76.18 - *	Gareth Hughes <gareth@valinux.com>, May 2000
   76.19 - *
   76.20 - * The FPU state data structure has had to grow to accommodate the
   76.21 - * extended FPU state required by the Streaming SIMD Extensions.
   76.22 - * There is no documented standard to accomplish this at the moment.
   76.23 - */
   76.24 -struct _fpreg {
   76.25 -	unsigned short significand[4];
   76.26 -	unsigned short exponent;
   76.27 -};
   76.28 -
   76.29 -struct _fpxreg {
   76.30 -	unsigned short significand[4];
   76.31 -	unsigned short exponent;
   76.32 -	unsigned short padding[3];
   76.33 -};
   76.34 -
   76.35 -struct _xmmreg {
   76.36 -	unsigned long element[4];
   76.37 -};
   76.38 -
   76.39 -struct _fpstate {
   76.40 -	/* Regular FPU environment */
   76.41 -	unsigned long	cw;
   76.42 -	unsigned long	sw;
   76.43 -	unsigned long	tag;
   76.44 -	unsigned long	ipoff;
   76.45 -	unsigned long	cssel;
   76.46 -	unsigned long	dataoff;
   76.47 -	unsigned long	datasel;
   76.48 -	struct _fpreg	_st[8];
   76.49 -	unsigned short	status;
   76.50 -	unsigned short	magic;		/* 0xffff = regular FPU data only */
   76.51 -
   76.52 -	/* FXSR FPU environment */
   76.53 -	unsigned long	_fxsr_env[6];	/* FXSR FPU env is ignored */
   76.54 -	unsigned long	mxcsr;
   76.55 -	unsigned long	reserved;
   76.56 -	struct _fpxreg	_fxsr_st[8];	/* FXSR FPU reg data is ignored */
   76.57 -	struct _xmmreg	_xmm[8];
   76.58 -	unsigned long	padding[56];
   76.59 -};
   76.60 -
   76.61 -#define X86_FXSR_MAGIC		0x0000
   76.62 -
   76.63 -/*
   76.64 - * User-space might still rely on the old definition:
   76.65 - */
   76.66 -struct sigcontext {
   76.67 -	unsigned short gs, __gsh;
   76.68 -	unsigned short fs, __fsh;
   76.69 -	unsigned short es, __esh;
   76.70 -	unsigned short ds, __dsh;
   76.71 -	unsigned long edi;
   76.72 -	unsigned long esi;
   76.73 -	unsigned long ebp;
   76.74 -	unsigned long esp;
   76.75 -	unsigned long ebx;
   76.76 -	unsigned long edx;
   76.77 -	unsigned long ecx;
   76.78 -	unsigned long eax;
   76.79 -	unsigned long trapno;
   76.80 -	unsigned long err;
   76.81 -	unsigned long eip;
   76.82 -	unsigned short cs, __csh;
   76.83 -	unsigned long eflags;
   76.84 -	unsigned long esp_at_signal;
   76.85 -	unsigned short ss, __ssh;
   76.86 -	struct _fpstate * fpstate;
   76.87 -	unsigned long oldmask;
   76.88 -	unsigned long cr2;
   76.89 -};
   76.90 -
   76.91 -#else /* __i386__ */
   76.92 -
   76.93 -/* FXSAVE frame */
   76.94 -/* Note: reserved1/2 may someday contain valuable data. Always save/restore
   76.95 -   them when you change signal frames. */
   76.96 -struct _fpstate {
   76.97 -	__u16	cwd;
   76.98 -	__u16	swd;
   76.99 -	__u16	twd;	/* Note this is not the same as the 32bit/x87/FSAVE twd */
  76.100 -	__u16	fop;
  76.101 -	__u64	rip;
  76.102 -	__u64	rdp;
  76.103 -	__u32	mxcsr;
  76.104 -	__u32	mxcsr_mask;
  76.105 -	__u32	st_space[32];	/* 8*16 bytes for each FP-reg */
  76.106 -	__u32	xmm_space[64];	/* 16*16 bytes for each XMM-reg  */
  76.107 -	__u32	reserved2[24];
  76.108 -};
  76.109 -
  76.110 -/*
  76.111 - * User-space might still rely on the old definition:
  76.112 - */
  76.113 -struct sigcontext {
  76.114 -	unsigned long r8;
  76.115 -	unsigned long r9;
  76.116 -	unsigned long r10;
  76.117 -	unsigned long r11;
  76.118 -	unsigned long r12;
  76.119 -	unsigned long r13;
  76.120 -	unsigned long r14;
  76.121 -	unsigned long r15;
  76.122 -	unsigned long rdi;
  76.123 -	unsigned long rsi;
  76.124 -	unsigned long rbp;
  76.125 -	unsigned long rbx;
  76.126 -	unsigned long rdx;
  76.127 -	unsigned long rax;
  76.128 -	unsigned long rcx;
  76.129 -	unsigned long rsp;
  76.130 -	unsigned long rip;
  76.131 -	unsigned long eflags;		/* RFLAGS */
  76.132 -	unsigned short cs;
  76.133 -	unsigned short gs;
  76.134 -	unsigned short fs;
  76.135 -	unsigned short __pad0;
  76.136 -	unsigned long err;
  76.137 -	unsigned long trapno;
  76.138 -	unsigned long oldmask;
  76.139 -	unsigned long cr2;
  76.140 -	struct _fpstate *fpstate;	/* zero when no FPU context */
  76.141 -	unsigned long reserved1[8];
  76.142 -};
  76.143 -
  76.144 -#endif /* !__i386__ */
  76.145 -
  76.146 -#endif
    77.1 --- a/coreutils/stuff/uname.u	Sat May 27 16:29:45 2017 +0300
    77.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.3 @@ -1,173 +0,0 @@
    77.4 -On linux platforms, grok /proc/cpuinfo for the CPU/vendor info.
    77.5 -
    77.6 -Prob not suitable for upstream seeing as how it's 100% linux-specific
    77.7 -http://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html
    77.8 -
    77.9 -Patch originally by Carlos E. Gorges <carlos@techlinux.com.br>, but 
   77.10 -heavily reworked to suck less.
   77.11 -
   77.12 -To add support for additional platforms, check out the show_cpuinfo()
   77.13 -func in the linux/arch/<ARCH>/ source tree of the kernel.
   77.14 -
   77.15 ---- coreutils/src/uname.c
   77.16 -+++ coreutils/src/uname.c
   77.17 -@@ -50,6 +50,11 @@
   77.18 - # include <mach-o/arch.h>
   77.19 - #endif
   77.20 - 
   77.21 -+#if defined(__linux__)
   77.22 -+# define USE_PROCINFO
   77.23 -+# define UNAME_HARDWARE_PLATFORM
   77.24 -+#endif
   77.25 -+
   77.26 - #include "system.h"
   77.27 - #include "error.h"
   77.28 - #include "quote.h"
   77.29 -@@ -138,6 +143,117 @@
   77.30 -   exit (status);
   77.31 - }
   77.32 - 
   77.33 -+#if defined(USE_PROCINFO)
   77.34 -+
   77.35 -+# if defined(__s390__) || defined(__s390x__)
   77.36 -+#  define CPUINFO_FILE    "/proc/sysinfo"
   77.37 -+#  define CPUINFO_FORMAT  "%64[^\t :]%*[ :]%256[^\n]%c"
   77.38 -+# else
   77.39 -+#  define CPUINFO_FILE    "/proc/cpuinfo"
   77.40 -+#  define CPUINFO_FORMAT  "%64[^\t:]\t:%256[^\n]%c"
   77.41 -+# endif
   77.42 -+
   77.43 -+# define PROCINFO_PROCESSOR      0
   77.44 -+# define PROCINFO_HARDWARE_PLATFORM 1
   77.45 -+
   77.46 -+static void __eat_cpuinfo_space(char *buf)
   77.47 -+{
   77.48 -+	/* first eat trailing space */
   77.49 -+	char *tmp = buf + strlen(buf) - 1;
   77.50 -+	while (tmp > buf && isspace(*tmp))
   77.51 -+		*tmp-- = '\0';
   77.52 -+	/* then eat leading space */
   77.53 -+	tmp = buf;
   77.54 -+	while (*tmp && isspace(*tmp))
   77.55 -+		tmp++;
   77.56 -+	if (tmp != buf)
   77.57 -+		memmove(buf, tmp, strlen(tmp)+1);
   77.58 -+	/* finally collapse whitespace */
   77.59 -+	tmp = buf;
   77.60 -+	while (tmp[0] && tmp[1]) {
   77.61 -+		if (isspace(tmp[0]) && isspace(tmp[1])) {
   77.62 -+			memmove(tmp, tmp+1, strlen(tmp));
   77.63 -+			continue;
   77.64 -+		}
   77.65 -+		++tmp;
   77.66 -+	}
   77.67 -+}
   77.68 -+
   77.69 -+static int __linux_procinfo(int x, char *fstr, size_t s)
   77.70 -+{
   77.71 -+	FILE *fp;
   77.72 -+
   77.73 -+	char *procinfo_keys[] = {
   77.74 -+		/* --processor --hardware-platform */
   77.75 -+		#if defined(__alpha__)
   77.76 -+			"cpu model", "system type"
   77.77 -+		#elif defined(__arm__)
   77.78 -+			"Processor", "Hardware"
   77.79 -+		#elif defined(__avr32__)
   77.80 -+			"processor", "cpu family"
   77.81 -+		#elif defined(__bfin__)
   77.82 -+			"CPU", "BOARD Name"
   77.83 -+		#elif defined(__cris__)
   77.84 -+			"cpu", "cpu model"
   77.85 -+		#elif defined(__frv__)
   77.86 -+			"CPU-Core", "System"
   77.87 -+		#elif defined(__i386__) || defined(__x86_64__)
   77.88 -+			"model name", "vendor_id"
   77.89 -+		#elif defined(__ia64__)
   77.90 -+			"family", "vendor"
   77.91 -+		#elif defined(__hppa__)
   77.92 -+			"cpu", "model"
   77.93 -+		#elif defined(__m68k__)
   77.94 -+			"CPU", "MMU"
   77.95 -+		#elif defined(__mips__)
   77.96 -+			"cpu model", "system type"
   77.97 -+		#elif defined(__powerpc__) || defined(__powerpc64__)
   77.98 -+			"cpu", "machine"
   77.99 -+		#elif defined(__s390__) || defined(__s390x__)
  77.100 -+			"Type", "Manufacturer"
  77.101 -+		#elif defined(__sh__)
  77.102 -+			"cpu type", "machine"
  77.103 -+		#elif defined(sparc) || defined(__sparc__)
  77.104 -+			"type", "cpu"
  77.105 -+		#elif defined(__vax__)
  77.106 -+			"cpu type", "cpu"
  77.107 -+		#else
  77.108 -+			"unknown", "unknown"
  77.109 -+		#endif
  77.110 -+	};
  77.111 -+
  77.112 -+	if ((fp = fopen(CPUINFO_FILE, "r")) != NULL) {
  77.113 -+		char key[65], value[257], eol, *ret = NULL;
  77.114 -+
  77.115 -+		while (fscanf(fp, CPUINFO_FORMAT, key, value, &eol) != EOF) {
  77.116 -+			__eat_cpuinfo_space(key);
  77.117 -+			if (!strcmp(key, procinfo_keys[x])) {
  77.118 -+				__eat_cpuinfo_space(value);
  77.119 -+				ret = value;
  77.120 -+				break;
  77.121 -+			}
  77.122 -+			if (eol != '\n') {
  77.123 -+				/* we need two fscanf's here in case the previous
  77.124 -+				 * length limit caused us to read right up to the
  77.125 -+				 * newline ... doing "%*[^\n]\n" wont eat the newline
  77.126 -+				 */
  77.127 -+				fscanf(fp, "%*[^\n]");
  77.128 -+				fscanf(fp, "\n");
  77.129 -+			}
  77.130 -+		}
  77.131 -+		fclose(fp);
  77.132 -+
  77.133 -+		if (ret) {
  77.134 -+			strncpy(fstr, ret, s);
  77.135 -+			return 0;
  77.136 -+		}
  77.137 -+	}
  77.138 -+
  77.139 -+	return -1;
  77.140 -+}
  77.141 -+
  77.142 -+#endif
  77.143 -+
  77.144 - /* Print ELEMENT, preceded by a space if something has already been
  77.145 -    printed.  */
  77.146 - 
  77.147 -@@ -250,10 +344,14 @@ main (int argc, char **argv)
  77.148 -   if (toprint & PRINT_PROCESSOR)
  77.149 -     {
  77.150 -       char const *element = unknown;
  77.151 --#if HAVE_SYSINFO && defined SI_ARCHITECTURE
  77.152 -+#if ( HAVE_SYSINFO && defined SI_ARCHITECTURE ) || defined(USE_PROCINFO)
  77.153 -       {
  77.154 -         static char processor[257];
  77.155 -+#if defined(USE_PROCINFO)
  77.156 -+        if (0 <= __linux_procinfo (PROCINFO_PROCESSOR, processor, sizeof processor))
  77.157 -+#else
  77.158 -         if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
  77.159 -+#endif
  77.160 -           element = processor;
  77.161 -       }
  77.162 - #endif
  77.163 -@@ -306,9 +404,13 @@ main (int argc, char **argv)
  77.164 -       if (element == unknown)
  77.165 -         {
  77.166 -           static char hardware_platform[257];
  77.167 -+#if defined(USE_PROCINFO)
  77.168 -+          if (0 <= __linux_procinfo (PROCINFO_HARDWARE_PLATFORM, hardware_platform, sizeof hardware_platform))
  77.169 -+#else
  77.170 -           size_t s = sizeof hardware_platform;
  77.171 -           static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };
  77.172 -           if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)
  77.173 -+#endif
  77.174 -             element = hardware_platform;
  77.175 -         }
  77.176 - #endif
    78.1 --- a/libpng-dev/receipt	Sat May 27 16:29:45 2017 +0300
    78.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.3 @@ -1,19 +0,0 @@
    78.4 -# SliTaz package receipt.
    78.5 -
    78.6 -PACKAGE="libpng-dev"
    78.7 -VERSION="1.6.28"
    78.8 -CATEGORY="development"
    78.9 -SHORT_DESC="Development files for libpng (with APNG support)"
   78.10 -MAINTAINER="al.bobylev@gmail.com"
   78.11 -LICENSE="zlib/libpng"
   78.12 -WEB_SITE="http://libpng.org/pub/png/libpng.html"
   78.13 -HOST_ARCH="i486 arm"
   78.14 -
   78.15 -WANTED="libpng"
   78.16 -DEPENDS="libpng"
   78.17 -
   78.18 -# Rules to gen a SliTaz package suitable for Tazpkg.
   78.19 -genpkg_rules()
   78.20 -{
   78.21 -	cook_copy_files libpng*-config *.h *.la *.pc
   78.22 -}
    79.1 --- a/libpng/receipt	Sat May 27 16:29:45 2017 +0300
    79.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.3 @@ -1,42 +0,0 @@
    79.4 -# SliTaz package receipt.
    79.5 -
    79.6 -PACKAGE="libpng"
    79.7 -VERSION="1.6.28"
    79.8 -CATEGORY="libs"
    79.9 -SHORT_DESC="PNG images library (with APNG support)"
   79.10 -MAINTAINER="al.bobylev@gmail.com"
   79.11 -LICENSE="zlib/libpng"
   79.12 -WEB_SITE="http://www.libpng.org/pub/png/libpng.html"
   79.13 -HOST_ARCH="i486 arm"
   79.14 -
   79.15 -TARBALL="$PACKAGE-$VERSION.tar.xz"
   79.16 -WGET_URL="$SF_MIRROR/libpng/$TARBALL"
   79.17 -
   79.18 -PATCH="$PACKAGE-$VERSION-apng.patch.gz"
   79.19 -PATCH_URL="$SF_MIRROR/apng/$PATCH"
   79.20 -
   79.21 -DEPENDS="zlib"
   79.22 -BUILD_DEPENDS="gawk zlib-dev"
   79.23 -
   79.24 -# Rules to configure and make the package.
   79.25 -compile_rules()
   79.26 -{
   79.27 -	[ -s "$SRC/$PATCH" ] || wget -O "$SRC/$PATCH" $PATCH_URL
   79.28 -	gzip -cd $SRC/$PATCH | patch -p0
   79.29 -
   79.30 -	./configure \
   79.31 -		--disable-static \
   79.32 -		$CONFIGURE_ARGS &&
   79.33 -	make && make install
   79.34 -
   79.35 -	# Misc png tools
   79.36 -	cd contrib/pngminus
   79.37 -	make PNGLIB="-L$DESTDIR/usr/lib -lpng" -f makefile.std png2pnm pnm2png
   79.38 -	cp -a png2pnm pnm2png $DESTDIR/usr/bin
   79.39 -}
   79.40 -
   79.41 -# Rules to gen a SliTaz package suitable for Tazpkg.
   79.42 -genpkg_rules()
   79.43 -{
   79.44 -	cook_copy_files png2pnm pnm2png pngfix png-fix-itxt *.so*
   79.45 -}
    80.1 --- a/libpng12-dev/receipt	Sat May 27 16:29:45 2017 +0300
    80.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.3 @@ -1,19 +0,0 @@
    80.4 -# SliTaz package receipt.
    80.5 -
    80.6 -PACKAGE="libpng12-dev"
    80.7 -VERSION="1.2.57"
    80.8 -CATEGORY="development"
    80.9 -SHORT_DESC="PNG images library (1.2 series, with APNG support, development files)"
   80.10 -MAINTAINER="al.bobylev@gmail.com"
   80.11 -LICENSE="zlib/libpng"
   80.12 -WEB_SITE="http://libpng.org/pub/png/libpng.html"
   80.13 -HOST_ARCH="i486 arm"
   80.14 -
   80.15 -WANTED="libpng12"
   80.16 -DEPENDS="libpng12"
   80.17 -
   80.18 -# Rules to gen a SliTaz package suitable for Tazpkg.
   80.19 -genpkg_rules()
   80.20 -{
   80.21 -	cook_copy_files libpng*-config *.h *.la *.pc
   80.22 -}
    81.1 --- a/libpng12/receipt	Sat May 27 16:29:45 2017 +0300
    81.2 +++ b/libpng12/receipt	Sat May 27 16:55:17 2017 +0300
    81.3 @@ -1,9 +1,9 @@
    81.4 -# SliTaz package receipt.
    81.5 +# SliTaz package receipt v2.
    81.6  
    81.7  PACKAGE="libpng12"
    81.8  VERSION="1.2.57"
    81.9  CATEGORY="libs"
   81.10 -SHORT_DESC="PNG images library (1.2 series, with APNG support)"
   81.11 +SHORT_DESC="PNG images library 1.2 series with APNG support"
   81.12  MAINTAINER="al.bobylev@gmail.com"
   81.13  LICENSE="zlib/libpng"
   81.14  WEB_SITE="http://www.libpng.org/pub/png/libpng.html"
   81.15 @@ -15,8 +15,8 @@
   81.16  PATCH="libpng-$VERSION-apng.patch.gz"
   81.17  PATCH_URL="$SF_MIRROR/apng/$PATCH"
   81.18  
   81.19 -DEPENDS="zlib"
   81.20  BUILD_DEPENDS="gawk zlib-dev"
   81.21 +SPLIT="libpng12-dev"
   81.22  
   81.23  # Rules to configure and make the package.
   81.24  compile_rules()
   81.25 @@ -33,5 +33,13 @@
   81.26  # Rules to gen a SliTaz package suitable for Tazpkg.
   81.27  genpkg_rules()
   81.28  {
   81.29 -	cook_copy_files *.so*
   81.30 +	case $PACKAGE in
   81.31 +		libpng12)
   81.32 +			copy @std
   81.33 +			DEPENDS="zlib"
   81.34 +			;;
   81.35 +		libpng12-dev)
   81.36 +			copy @dev
   81.37 +			;;
   81.38 +	esac
   81.39  }
    82.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.2 +++ b/libpng16/receipt	Sat May 27 16:55:17 2017 +0300
    82.3 @@ -0,0 +1,52 @@
    82.4 +# SliTaz package receipt v2.
    82.5 +
    82.6 +PACKAGE="libpng16"
    82.7 +VERSION="1.6.28"
    82.8 +CATEGORY="libs"
    82.9 +SHORT_DESC="PNG images library 1.6 series with APNG support"
   82.10 +MAINTAINER="al.bobylev@gmail.com"
   82.11 +LICENSE="zlib/libpng"
   82.12 +WEB_SITE="http://www.libpng.org/pub/png/libpng.html"
   82.13 +HOST_ARCH="i486 arm"
   82.14 +
   82.15 +TARBALL="libpng-$VERSION.tar.xz"
   82.16 +WGET_URL="$SF_MIRROR/libpng/$TARBALL"
   82.17 +
   82.18 +PATCH="libpng-$VERSION-apng.patch.gz"
   82.19 +PATCH_URL="$SF_MIRROR/apng/$PATCH"
   82.20 +
   82.21 +BUILD_DEPENDS="gawk zlib-dev"
   82.22 +SPLIT="libpng16-dev"
   82.23 +
   82.24 +# Rules to configure and make the package.
   82.25 +compile_rules()
   82.26 +{
   82.27 +	[ -s "$SRC/$PATCH" ] || wget -O "$SRC/$PATCH" $PATCH_URL
   82.28 +	gzip -cd $SRC/$PATCH | patch -p0
   82.29 +
   82.30 +	./configure \
   82.31 +		--disable-static \
   82.32 +		$CONFIGURE_ARGS &&
   82.33 +	make && make install
   82.34 +
   82.35 +	# Misc png tools
   82.36 +	cd contrib/pngminus
   82.37 +	make PNGLIB="-L$DESTDIR/usr/lib -lpng" -f makefile.std png2pnm pnm2png
   82.38 +	cp -a png2pnm pnm2png $DESTDIR/usr/bin
   82.39 +}
   82.40 +
   82.41 +# Rules to gen a SliTaz package suitable for Tazpkg.
   82.42 +genpkg_rules()
   82.43 +{
   82.44 +	case $PACKAGE in
   82.45 +		libpng16)
   82.46 +			copy @std
   82.47 +			DEPENDS="zlib"
   82.48 +			PROVIDE="libpng"
   82.49 +			;;
   82.50 +		libpng16-dev)
   82.51 +			copy @dev
   82.52 +			PROVIDE="libpng-dev"
   82.53 +			;;
   82.54 +	esac
   82.55 +}
    83.1 --- a/libwebp-apps/receipt	Sat May 27 16:29:45 2017 +0300
    83.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.3 @@ -1,19 +0,0 @@
    83.4 -# SliTaz package receipt.
    83.5 -
    83.6 -PACKAGE="libwebp-apps"
    83.7 -VERSION="0.5.1"
    83.8 -CATEGORY="x-window"
    83.9 -SHORT_DESC="WebP image library (applications)"
   83.10 -MAINTAINER="al.bobylev@gmail.com"
   83.11 -LICENSE="BSD"
   83.12 -WEB_SITE="https://www.webmproject.org/"
   83.13 -HOST_ARCH="i486 arm"
   83.14 -
   83.15 -WANTED="libwebp"
   83.16 -DEPENDS="giflib libjpeg-turbo libpng libwebp tiff"
   83.17 -
   83.18 -# Rules to gen a SliTaz package suitable for Tazpkg.
   83.19 -genpkg_rules()
   83.20 -{
   83.21 -	cook_copy_folders bin
   83.22 -}
    84.1 --- a/libwebp-dev/receipt	Sat May 27 16:29:45 2017 +0300
    84.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.3 @@ -1,18 +0,0 @@
    84.4 -# SliTaz package receipt.
    84.5 -
    84.6 -PACKAGE="libwebp-dev"
    84.7 -VERSION="0.5.1"
    84.8 -CATEGORY="development"
    84.9 -SHORT_DESC="WebP image library (development files)"
   84.10 -MAINTAINER="pankso@slitaz.org"
   84.11 -LICENSE="BSD"
   84.12 -WEB_SITE="https://www.webmproject.org/"
   84.13 -HOST_ARCH="i486 arm"
   84.14 -
   84.15 -WANTED="libwebp"
   84.16 -
   84.17 -# Rules to gen a SliTaz package suitable for Tazpkg.
   84.18 -genpkg_rules()
   84.19 -{
   84.20 -	cook_copy_files *.h *.la *.pc
   84.21 -}
    85.1 --- a/libwebp/receipt	Sat May 27 16:29:45 2017 +0300
    85.2 +++ b/libwebp/receipt	Sat May 27 16:55:17 2017 +0300
    85.3 @@ -1,9 +1,9 @@
    85.4 -# SliTaz package receipt.
    85.5 +# SliTaz package receipt v2.
    85.6  
    85.7  PACKAGE="libwebp"
    85.8  VERSION="0.5.1"
    85.9  CATEGORY="x-window"
   85.10 -SHORT_DESC="WebP image library."
   85.11 +SHORT_DESC="WebP image library"
   85.12  MAINTAINER="devl547@gmail.com"
   85.13  LICENSE="BSD"
   85.14  WEB_SITE="https://www.webmproject.org/"
   85.15 @@ -32,5 +32,17 @@
   85.16  # Rules to gen a SliTaz package suitable for Tazpkg.
   85.17  genpkg_rules()
   85.18  {
   85.19 -	cook_copy_files *.so*
   85.20 +	case $PACKAGE in
   85.21 +		libwebp)
   85.22 +			copy *.so*
   85.23 +			;;
   85.24 +		libwebp-apps)
   85.25 +			copy bin/
   85.26 +			CAT="x-window|applications"
   85.27 +			DEPENDS="giflib libjpeg-turbo libpng libwebp tiff"
   85.28 +			;;
   85.29 +		libwebp-dev)
   85.30 +			copy @dev
   85.31 +			;;
   85.32 +	esac
   85.33  }
    86.1 --- a/libxml2-dev/receipt	Sat May 27 16:29:45 2017 +0300
    86.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.3 @@ -1,19 +0,0 @@
    86.4 -# SliTaz package receipt.
    86.5 -
    86.6 -PACKAGE="libxml2-dev"
    86.7 -VERSION="2.9.4"
    86.8 -CATEGORY="development"
    86.9 -SHORT_DESC="XML C parser and toolkit devel files."
   86.10 -MAINTAINER="pankso@slitaz.org"
   86.11 -LICENSE="MIT"
   86.12 -WEB_SITE="http://xmlsoft.org/"
   86.13 -HOST_ARCH="i486 arm"
   86.14 -
   86.15 -WANTED="libxml2"
   86.16 -DEPENDS="libxml2-tools pkg-config   zlib-dev liblzma-dev"
   86.17 -
   86.18 -# Rules to gen a SliTaz package suitable for Tazpkg.
   86.19 -genpkg_rules()
   86.20 -{
   86.21 -	cook_copy_files xml2-config *.h *.cmake *.pc libxml2.la *.sh *.m4
   86.22 -}
    87.1 --- a/libxml2-python/receipt	Sat May 27 16:29:45 2017 +0300
    87.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.3 @@ -1,20 +0,0 @@
    87.4 -# SliTaz package receipt.
    87.5 -
    87.6 -PACKAGE="libxml2-python"
    87.7 -VERSION="2.9.4"
    87.8 -CATEGORY="development"
    87.9 -SHORT_DESC="Libxml2 adapter for the Python."
   87.10 -MAINTAINER="pascal.bellard@slitaz.org"
   87.11 -LICENSE="MIT"
   87.12 -WEB_SITE="http://xmlsoft.org/"
   87.13 -#HOST_ARCH="arm i486"
   87.14 -
   87.15 -WANTED="libxml2"
   87.16 -DEPENDS="python libxml2 libxslt"
   87.17 -
   87.18 -# Rules to gen a SliTaz package suitable for Tazpkg.
   87.19 -genpkg_rules()
   87.20 -{
   87.21 -	mkdir -p $fs/usr/lib
   87.22 -	cp -a $install/usr/lib/python* $fs/usr/lib
   87.23 -}
    88.1 --- a/libxml2-tools/receipt	Sat May 27 16:29:45 2017 +0300
    88.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.3 @@ -1,19 +0,0 @@
    88.4 -# SliTaz package receipt.
    88.5 -
    88.6 -PACKAGE="libxml2-tools"
    88.7 -VERSION="2.9.4"
    88.8 -CATEGORY="system-tools"
    88.9 -SHORT_DESC="The xmllint tester and xmlcatalog parser utility."
   88.10 -MAINTAINER="pankso@slitaz.org"
   88.11 -LICENSE="MIT"
   88.12 -WEB_SITE="http://xmlsoft.org/"
   88.13 -HOST_ARCH="i486 arm"
   88.14 -
   88.15 -WANTED="libxml2"
   88.16 -DEPENDS="libxml2"
   88.17 -
   88.18 -# Rules to gen a SliTaz package suitable for Tazpkg.
   88.19 -genpkg_rules()
   88.20 -{
   88.21 -	cook_copy_files xmllint xmlcatalog
   88.22 -}
    89.1 --- a/libxml2/receipt	Sat May 27 16:29:45 2017 +0300
    89.2 +++ b/libxml2/receipt	Sat May 27 16:55:17 2017 +0300
    89.3 @@ -1,9 +1,9 @@
    89.4 -# SliTaz package receipt.
    89.5 +# SliTaz package receipt v2.
    89.6  
    89.7  PACKAGE="libxml2"
    89.8  VERSION="2.9.4"
    89.9  CATEGORY="system-tools"
   89.10 -SHORT_DESC="Libxml2 is the XML C parser and toolkit."
   89.11 +SHORT_DESC="XML C parser and toolkit"
   89.12  MAINTAINER="pankso@slitaz.org"
   89.13  LICENSE="MIT"
   89.14  WEB_SITE="http://xmlsoft.org/"
   89.15 @@ -12,19 +12,15 @@
   89.16  TARBALL="$PACKAGE-$VERSION.tar.gz"
   89.17  WGET_URL="ftp://xmlsoft.org/libxml2/$TARBALL"
   89.18  
   89.19 -DEPENDS="zlib liblzma"
   89.20  BUILD_DEPENDS="zlib-dev liblzma-dev python-dev ncurses-dev readline-dev"
   89.21 -# autoconf automake libtool
   89.22 +BUILD_DEPENDS_arm=" "
   89.23  SPLIT="libxml2-tools libxml2-python libxml2-dev"
   89.24  
   89.25  # When cross compiling Python is installed in chroot and is used
   89.26 -# by cross tools, cook dont need to install it in /usr/cross/arm
   89.27 +# by cross tools, cook don't need to install it in /usr/cross/arm
   89.28  # Building with LZMA support is buggy and build fails
   89.29  case "$ARCH" in
   89.30 -	arm)
   89.31 -		BUILD_DEPENDS=""
   89.32 -		DEPENDS="zlib"
   89.33 -		ARCH_ARGS="--without-lzma" ;;
   89.34 +	arm) ARCH_ARGS="--without-lzma" ;;
   89.35  esac
   89.36  
   89.37  # Rules to configure and make the package.
   89.38 @@ -49,5 +45,26 @@
   89.39  # Rules to gen a SliTaz package suitable for Tazpkg.
   89.40  genpkg_rules()
   89.41  {
   89.42 -	cook_copy_files libxml2.so*
   89.43 +	case $PACKAGE in
   89.44 +		libxml2)
   89.45 +			copy libxml2.so*
   89.46 +			DEPENDS="zlib liblzma"
   89.47 +			case "$ARCH" in
   89.48 +				arm) DEPENDS="zlib" ;;
   89.49 +			esac
   89.50 +			;;
   89.51 +		libxml2-tools)
   89.52 +			copy xmllint xmlcatalog
   89.53 +			CAT="system-tools|xmllint tester and xmlcatalog parser utility"
   89.54 +			;;
   89.55 +		libxml2-python)
   89.56 +			copy python2.7/; find $fs -name '*.la' -delete
   89.57 +			CAT="development|adapter for the Python"
   89.58 +			DEPENDS="python libxml2 libxslt"
   89.59 +			;;
   89.60 +		libxml2-dev)
   89.61 +			copy @dev *.sh
   89.62 +			DEPENDS="libxml2-tools pkg-config   zlib-dev liblzma-dev"
   89.63 +			;;
   89.64 +	esac
   89.65  }