wok rev 19215

Up coreutils(8.25)
author Aleksej Bobylev <al.bobylev@gmail.com>
date Wed Jun 15 17:23:11 2016 +0300 (2016-06-15)
parents 728e891f2504
children 5b84caa85ec8
files 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.txt coreutils/receipt coreutils/stuff/coreutils-8.25-i18n-2.patch
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/coreutils-character/description.txt	Wed Jun 15 17:23:11 2016 +0300
     1.3 @@ -0,0 +1,5 @@
     1.4 +Coreutils: Core GNU (file, text, shell) utilities.
     1.5 +
     1.6 +  * expand:    convert tabs to spaces
     1.7 +  * tr:        translate or delete characters
     1.8 +  * unexpand:  convert spaces to tabs
     2.1 --- a/coreutils-character/receipt	Tue Jun 14 23:10:20 2016 +0300
     2.2 +++ b/coreutils-character/receipt	Wed Jun 15 17:23:11 2016 +0300
     2.3 @@ -1,33 +1,41 @@
     2.4  # SliTaz package receipt.
     2.5  
     2.6  PACKAGE="coreutils-character"
     2.7 -VERSION="8.12"
     2.8 +VERSION="8.25"
     2.9  CATEGORY="system-tools"
    2.10  SHORT_DESC="GNU utilities that operate on characters."
    2.11  MAINTAINER="rcx@zoominternet.net"
    2.12  LICENSE="GPL3"
    2.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
    2.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
    2.15 +
    2.16  WANTED="coreutils"
    2.17 -
    2.18  DEPENDS="glibc-base"
    2.19  
    2.20  # Rules to gen a SliTaz package suitable for Tazpkg.
    2.21 -#
    2.22 -# This is a special package for installed system or developer. We only take
    2.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
    2.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
    2.25 -#
    2.26  genpkg_rules()
    2.27  {
    2.28 -	mkdir -p $fs/usr/bin
    2.29 -	cp -a $install/usr/bin/tr $fs/usr/bin
    2.30 -	cp -a $install/usr/bin/expand $fs/usr/bin
    2.31 -	cp -a $install/usr/bin/unexpand $fs/usr/bin
    2.32 +	mandir="$fs/usr/share/man/man1"
    2.33 +	mkdir -p $mandir
    2.34 +
    2.35 +	while read i; do
    2.36 +		mkdir -p $fs$(dirname $i)
    2.37 +		cp -a $install$i $fs$i
    2.38 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
    2.39 +	done <<EOT
    2.40 +/usr/bin/expand
    2.41 +/usr/bin/tr
    2.42 +/usr/bin/unexpand
    2.43 +EOT
    2.44  }
    2.45  
    2.46  post_remove()
    2.47  {
    2.48 -	ln -s /bin/busybox "$1/usr/bin/tr"
    2.49 -	ln -s /bin/busybox "$1/usr/bin/expand"
    2.50 -	ln -s /bin/busybox "$1/usr/bin/unexpand"
    2.51 +	# Restore all Busybox applets that have been replaced
    2.52 +	while read i; do
    2.53 +		busybox ln -s /bin/busybox "$1$i"
    2.54 +	done <<EOT
    2.55 +/usr/bin/expand
    2.56 +/usr/bin/tr
    2.57 +/usr/bin/unexpand
    2.58 +EOT
    2.59  }
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/coreutils-command/description.txt	Wed Jun 15 17:23:11 2016 +0300
     3.3 @@ -0,0 +1,11 @@
     3.4 +Coreutils: Core GNU (file, text, shell) utilities.
     3.5 +
     3.6 +  * chroot:    run command or interactive shell with special root directory
     3.7 +  * env:       run a program in a modified environment
     3.8 +  * kill:      send signals to processes, or list signals
     3.9 +  * nice:      run a program with modified scheduling priority
    3.10 +  * nohup:     run a command immune to hangups, with output to a non-tty
    3.11 +  * sleep:     delay for a specified amount of time
    3.12 +  * stdbuf:    run command with modified buffering operations for its standard
    3.13 +               streams
    3.14 +  * timeout:   run a command with a time limit
     4.1 --- a/coreutils-command/receipt	Tue Jun 14 23:10:20 2016 +0300
     4.2 +++ b/coreutils-command/receipt	Wed Jun 15 17:23:11 2016 +0300
     4.3 @@ -1,45 +1,62 @@
     4.4  # SliTaz package receipt.
     4.5  
     4.6  PACKAGE="coreutils-command"
     4.7 -VERSION="8.12"
     4.8 +VERSION="8.25"
     4.9  CATEGORY="system-tools"
    4.10  SHORT_DESC="GNU command utilities."
    4.11  MAINTAINER="rcx@zoominternet.net"
    4.12  LICENSE="GPL3"
    4.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
    4.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
    4.15 +
    4.16  WANTED="coreutils"
    4.17 -
    4.18  DEPENDS="glibc-base"
    4.19  
    4.20  # Rules to gen a SliTaz package suitable for Tazpkg.
    4.21 -#
    4.22 -# This is a special package for installed system or developer. We only take
    4.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
    4.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
    4.25 -#
    4.26  genpkg_rules()
    4.27  {
    4.28 -	mkdir -p $fs/bin
    4.29 -	cp -a $install/usr/bin/nice $fs/bin
    4.30 -	cp -a $install/usr/bin/kill $fs/bin
    4.31 -	cp -a $install/usr/bin/sleep $fs/bin
    4.32 +	mandir="$fs/usr/share/man/man1"
    4.33 +	mkdir -p $mandir ${mandir/1/8}
    4.34  
    4.35 -	mkdir -p $fs/usr/bin
    4.36 -	cp -a $install/usr/bin/env $fs/usr/bin
    4.37 -	cp -a $install/usr/bin/nohup $fs/usr/bin
    4.38 -	cp -a $install/usr/bin/timeout $fs/usr/bin
    4.39 +	while read i; do
    4.40 +		mkdir -p $fs$(dirname $i)
    4.41 +		cp -a $install$i $fs$i
    4.42 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
    4.43 +	done <<EOT
    4.44 +/usr/bin/env
    4.45 +/usr/bin/kill
    4.46 +/usr/bin/nice
    4.47 +/usr/bin/nohup
    4.48 +/usr/bin/sleep
    4.49 +/usr/bin/stdbuf
    4.50 +/usr/bin/timeout
    4.51 +/usr/libexec/coreutils/libstdbuf.so
    4.52 +/usr/sbin/chroot
    4.53 +EOT
    4.54  
    4.55 -	mkdir -p $fs/usr/sbin
    4.56 -	cp -a $install/usr/bin/chroot $fs/usr/sbin
    4.57 +	mv $mandir/chroot.* ${mandir/1/8}
    4.58 +}
    4.59 +
    4.60 +post_install()
    4.61 +{
    4.62 +	# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
    4.63 +	# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
    4.64 +	rm "$1/bin/kill"     # /usr/bin/kill
    4.65 +	rm "$1/bin/nice"     # /usr/bin/nice
    4.66 +	rm "$1/bin/sleep"    # /usr/bin/sleep
    4.67  }
    4.68  
    4.69  post_remove()
    4.70  {
    4.71 -	ln -s /bin/busybox "$1/bin/nice"
    4.72 -	ln -s /bin/busybox "$1/bin/kill"
    4.73 -	ln -s /bin/busybox "$1/bin/sleep"
    4.74 -	ln -s /bin/busybox "$1/usr/bin/env"
    4.75 -	ln -s /bin/busybox "$1/usr/bin/nohup"
    4.76 -	ln -s /bin/busybox "$1/usr/bin/timeout"
    4.77 -	ln -s /bin/busybox "$1/usr/sbin/chroot"
    4.78 +	# Restore all Busybox applets that have been replaced
    4.79 +	while read i; do
    4.80 +		busybox ln -s /bin/busybox "$1$i"
    4.81 +	done <<EOT
    4.82 +/bin/kill
    4.83 +/bin/nice
    4.84 +/bin/sleep
    4.85 +/usr/bin/env
    4.86 +/usr/bin/nohup
    4.87 +/usr/bin/timeout
    4.88 +/usr/sbin/chroot
    4.89 +EOT
    4.90  }
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/coreutils-conditions/description.txt	Wed Jun 15 17:23:11 2016 +0300
     5.3 @@ -0,0 +1,7 @@
     5.4 +Coreutils: Core GNU (file, text, shell) utilities.
     5.5 +
     5.6 +  * [          exit with the status determined by expression
     5.7 +  * expr:      evaluate expressions
     5.8 +  * false:     do nothing, unsuccessfully
     5.9 +  * test:      check file types and compare values
    5.10 +  * true:      do nothing, successfully
     6.1 --- a/coreutils-conditions/receipt	Tue Jun 14 23:10:20 2016 +0300
     6.2 +++ b/coreutils-conditions/receipt	Wed Jun 15 17:23:11 2016 +0300
     6.3 @@ -1,39 +1,45 @@
     6.4  # SliTaz package receipt.
     6.5  
     6.6  PACKAGE="coreutils-conditions"
     6.7 -VERSION="8.12"
     6.8 +VERSION="8.25"
     6.9  CATEGORY="system-tools"
    6.10  SHORT_DESC="GNU utilities for conditions."
    6.11  MAINTAINER="rcx@zoominternet.net"
    6.12  LICENSE="GPL3"
    6.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
    6.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
    6.15 +
    6.16  WANTED="coreutils"
    6.17 -
    6.18  DEPENDS="glibc-base gmp"
    6.19  
    6.20  # Rules to gen a SliTaz package suitable for Tazpkg.
    6.21 -#
    6.22 -# This is a special package for installed system or developer. We only take
    6.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
    6.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
    6.25 -#
    6.26  genpkg_rules()
    6.27  {
    6.28 -	mkdir -p $fs/bin
    6.29 -	cp -a $install/usr/bin/false $fs/bin
    6.30 -	cp -a $install/usr/bin/true $fs/bin
    6.31 +	mandir="$fs/usr/share/man/man1"
    6.32 +	mkdir -p $mandir
    6.33  
    6.34 -	mkdir -p $fs/usr/bin
    6.35 -	cp -a $install/usr/bin/test $fs/usr/bin
    6.36 -	cp -a $install/usr/bin/[ $fs/usr/bin
    6.37 -	cp -a $install/usr/bin/expr $fs/usr/bin
    6.38 +	while read i; do
    6.39 +		mkdir -p $fs$(dirname $i)
    6.40 +		cp -a $install$i $fs$i
    6.41 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
    6.42 +	done <<EOT
    6.43 +/bin/false
    6.44 +/bin/true
    6.45 +/usr/bin/[
    6.46 +/usr/bin/expr
    6.47 +/usr/bin/test
    6.48 +EOT
    6.49  }
    6.50  
    6.51  post_remove()
    6.52  {
    6.53 -	ln -s /bin/busybox "$1/bin/false"
    6.54 -	ln -s /bin/busybox "$1/bin/true"
    6.55 -	ln -s /bin/busybox "$1/usr/bin/test"
    6.56 -	ln -s /bin/busybox "$1/usr/bin/["
    6.57 -	ln -s /bin/busybox "$1/usr/bin/expr"
    6.58 +	# Restore all Busybox applets that have been replaced
    6.59 +	while read i; do
    6.60 +		busybox ln -s /bin/busybox "$1$i"
    6.61 +	done <<EOT
    6.62 +/bin/false
    6.63 +/bin/true
    6.64 +/usr/bin/[
    6.65 +/usr/bin/expr
    6.66 +/usr/bin/test
    6.67 +EOT
    6.68  }
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/coreutils-context-system/description.txt	Wed Jun 15 17:23:11 2016 +0300
     7.3 @@ -0,0 +1,9 @@
     7.4 +Coreutils: Core GNU (file, text, shell) utilities.
     7.5 +
     7.6 +  * chcon:     change file SELinux security context
     7.7 +  * date:      print or set the system date and time
     7.8 +  * hostid:    print the numeric identifier for the current host
     7.9 +  * nproc:     print the number of processing units available
    7.10 +  * runcon:    run command with specified SELinux security context
    7.11 +  * uname:     print system information
    7.12 +  * uptime:    tell how long the system has been running
     8.1 --- a/coreutils-context-system/receipt	Tue Jun 14 23:10:20 2016 +0300
     8.2 +++ b/coreutils-context-system/receipt	Wed Jun 15 17:23:11 2016 +0300
     8.3 @@ -1,39 +1,46 @@
     8.4  # SliTaz package receipt.
     8.5  
     8.6  PACKAGE="coreutils-context-system"
     8.7 -VERSION="8.12"
     8.8 +VERSION="8.25"
     8.9  CATEGORY="system-tools"
    8.10  SHORT_DESC="GNU utilities related to the system context."
    8.11  MAINTAINER="rcx@zoominternet.net"
    8.12  LICENSE="GPL3"
    8.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
    8.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
    8.15 +
    8.16  WANTED="coreutils"
    8.17 -
    8.18  DEPENDS="glibc-base"
    8.19  
    8.20  # Rules to gen a SliTaz package suitable for Tazpkg.
    8.21 -#
    8.22 -# This is a special package for installed system or developer. We only take
    8.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
    8.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
    8.25 -#
    8.26  genpkg_rules()
    8.27  {
    8.28 -	mkdir -p $fs/bin
    8.29 -	cp -a $install/usr/bin/date $fs/bin
    8.30 -	cp -a $install/usr/bin/uname $fs/bin
    8.31 +	mandir="$fs/usr/share/man/man1"
    8.32 +	mkdir -p $mandir
    8.33  
    8.34 -	mkdir -p $fs/usr/bin
    8.35 -	cp -a $install/usr/bin/chcon $fs/usr/bin
    8.36 -	cp -a $install/usr/bin/runcon $fs/usr/bin
    8.37 -	cp -a $install/usr/bin/hostid $fs/usr/bin
    8.38 -	cp -a $install/usr/bin/uptime $fs/usr/bin
    8.39 +	while read i; do
    8.40 +		mkdir -p $fs$(dirname $i)
    8.41 +		cp -a $install$i $fs$i
    8.42 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
    8.43 +	done <<EOT
    8.44 +/bin/date
    8.45 +/bin/uname
    8.46 +/usr/bin/chcon
    8.47 +/usr/bin/hostid
    8.48 +/usr/bin/nproc
    8.49 +/usr/bin/runcon
    8.50 +/usr/bin/uptime
    8.51 +EOT
    8.52  }
    8.53  
    8.54  post_remove()
    8.55  {
    8.56 -	ln -s /bin/busybox "$1/bin/date"
    8.57 -	ln -s /bin/busybox "$1/bin/uname"
    8.58 -	ln -s /bin/busybox "$1/usr/bin/hostid"
    8.59 -	ln -s /bin/busybox "$1/usr/bin/uptime"
    8.60 +	# Restore all Busybox applets that have been replaced
    8.61 +	while read i; do
    8.62 +		busybox ln -s /bin/busybox "$1$i"
    8.63 +	done <<EOT
    8.64 +/bin/date
    8.65 +/bin/uname
    8.66 +/usr/bin/hostid
    8.67 +/usr/bin/uptime
    8.68 +EOT
    8.69  }
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/coreutils-context-user/description.txt	Wed Jun 15 17:23:11 2016 +0300
     9.3 @@ -0,0 +1,10 @@
     9.4 +Coreutils: Core GNU (file, text, shell) utilities.
     9.5 +
     9.6 +  * groups:    print the groups a user is in
     9.7 +  * id:        print real and effective user and group IDs
     9.8 +  * logname:   print user's login name
     9.9 +  * pinky:     lightweight finger
    9.10 +  * users:     print the user names of users currently logged in to the current
    9.11 +               host
    9.12 +  * who:       show who is logged on
    9.13 +  * whoami:    print effective user ID
    10.1 --- a/coreutils-context-user/receipt	Tue Jun 14 23:10:20 2016 +0300
    10.2 +++ b/coreutils-context-user/receipt	Wed Jun 15 17:23:11 2016 +0300
    10.3 @@ -1,40 +1,48 @@
    10.4  # SliTaz package receipt.
    10.5  
    10.6  PACKAGE="coreutils-context-user"
    10.7 -VERSION="8.12"
    10.8 +VERSION="8.25"
    10.9  CATEGORY="system-tools"
   10.10  SHORT_DESC="GNU utilities related to the user context."
   10.11  MAINTAINER="rcx@zoominternet.net"
   10.12  LICENSE="GPL3"
   10.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   10.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   10.15 +
   10.16  WANTED="coreutils"
   10.17 -
   10.18  DEPENDS="glibc-base"
   10.19  
   10.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   10.21 -#
   10.22 -# This is a special package for installed system or developer. We only take
   10.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   10.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   10.25 -#
   10.26  genpkg_rules()
   10.27  {
   10.28 -	mkdir -p $fs/bin
   10.29 -	cp -a $install/usr/bin/id $fs/bin
   10.30 +	mandir="$fs/usr/share/man/man1"
   10.31 +	mkdir -p $mandir
   10.32  
   10.33 -	mkdir -p $fs/usr/bin
   10.34 -	cp -a $install/usr/bin/logname $fs/usr/bin
   10.35 -	cp -a $install/usr/bin/whoami $fs/usr/bin
   10.36 -	cp -a $install/usr/bin/groups $fs/usr/bin
   10.37 -	cp -a $install/usr/bin/pinky $fs/usr/bin
   10.38 -	cp -a $install/usr/bin/users $fs/usr/bin
   10.39 -	cp -a $install/usr/bin/who $fs/usr/bin
   10.40 +	while read i; do
   10.41 +		mkdir -p $fs$(dirname $i)
   10.42 +		cp -a $install$i $fs$i
   10.43 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   10.44 +	done <<EOT
   10.45 +/usr/bin/groups
   10.46 +/usr/bin/id
   10.47 +/usr/bin/logname
   10.48 +/usr/bin/pinky
   10.49 +/usr/bin/users
   10.50 +/usr/bin/who
   10.51 +/usr/bin/whoami
   10.52 +EOT
   10.53  }
   10.54  
   10.55  post_remove()
   10.56  {
   10.57 -	ln -s /bin/busybox "$1/bin/id"
   10.58 -	ln -s /bin/busybox "$1/usr/bin/logname"
   10.59 -	ln -s /bin/busybox "$1/usr/bin/whoami"
   10.60 -	ln -s /bin/busybox "$1/usr/bin/who"
   10.61 +	# Restore all Busybox applets that have been replaced
   10.62 +	while read i; do
   10.63 +		busybox ln -s /bin/busybox "$1$i"
   10.64 +	done <<EOT
   10.65 +/usr/bin/groups
   10.66 +/usr/bin/id
   10.67 +/usr/bin/logname
   10.68 +/usr/bin/users
   10.69 +/usr/bin/who
   10.70 +/usr/bin/whoami
   10.71 +EOT
   10.72  }
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/coreutils-context-working/description.txt	Wed Jun 15 17:23:11 2016 +0300
    11.3 @@ -0,0 +1,6 @@
    11.4 +Coreutils: Core GNU (file, text, shell) utilities.
    11.5 +
    11.6 +  * printenv:  print all or part of environment
    11.7 +  * pwd:       print name of current/working directory
    11.8 +  * stty:      change and print terminal line settings
    11.9 +  * tty:       print the file name of the terminal connected to standard input
    12.1 --- a/coreutils-context-working/receipt	Tue Jun 14 23:10:20 2016 +0300
    12.2 +++ b/coreutils-context-working/receipt	Wed Jun 15 17:23:11 2016 +0300
    12.3 @@ -1,37 +1,50 @@
    12.4  # SliTaz package receipt.
    12.5  
    12.6  PACKAGE="coreutils-context-working"
    12.7 -VERSION="8.12"
    12.8 +VERSION="8.25"
    12.9  CATEGORY="system-tools"
   12.10  SHORT_DESC="GNU utilities related to the working context."
   12.11  MAINTAINER="rcx@zoominternet.net"
   12.12  LICENSE="GPL3"
   12.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   12.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   12.15 +
   12.16  WANTED="coreutils"
   12.17 -
   12.18  DEPENDS="glibc-base"
   12.19  
   12.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   12.21 -#
   12.22 -# This is a special package for installed system or developer. We only take
   12.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   12.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   12.25 -#
   12.26  genpkg_rules()
   12.27  {
   12.28 -	mkdir -p $fs/bin
   12.29 -	cp -a $install/usr/bin/pwd $fs/bin
   12.30 -	cp -a $install/usr/bin/stty $fs/bin
   12.31 -	cp -a $install/usr/bin/printenv $fs/bin
   12.32 +	mandir="$fs/usr/share/man/man1"
   12.33 +	mkdir -p $mandir
   12.34  
   12.35 -	mkdir -p $fs/usr/bin
   12.36 -	cp -a $install/usr/bin/tty $fs/usr/bin
   12.37 +	while read i; do
   12.38 +		mkdir -p $fs$(dirname $i)
   12.39 +		cp -a $install$i $fs$i
   12.40 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   12.41 +	done <<EOT
   12.42 +/bin/pwd
   12.43 +/bin/stty
   12.44 +/usr/bin/printenv
   12.45 +/usr/bin/tty
   12.46 +EOT
   12.47 +}
   12.48 +
   12.49 +post_install()
   12.50 +{
   12.51 +	# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
   12.52 +	# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
   12.53 +	rm "$1/bin/printenv" # /usr/bin/printenv
   12.54  }
   12.55  
   12.56  post_remove()
   12.57  {
   12.58 -	ln -s /bin/busybox "$1/bin/pwd"
   12.59 -	ln -s /bin/busybox "$1/bin/stty"
   12.60 -	ln -s /bin/busybox "$1/bin/printenv"
   12.61 -	ln -s /bin/busybox "$1/usr/bin/tty"
   12.62 +	# Restore all Busybox applets that have been replaced
   12.63 +	while read i; do
   12.64 +		busybox ln -s /bin/busybox "$1$i"
   12.65 +	done <<EOT
   12.66 +/bin/printenv
   12.67 +/bin/pwd
   12.68 +/bin/stty
   12.69 +/usr/bin/tty
   12.70 +EOT
   12.71  }
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/coreutils-directory/description.txt	Wed Jun 15 17:23:11 2016 +0300
    13.3 @@ -0,0 +1,6 @@
    13.4 +Coreutils: Core GNU (file, text, shell) utilities.
    13.5 +
    13.6 +  * dir:       list directory contents
    13.7 +  * dircolors: color setup for ls
    13.8 +  * ls:        list directory contents
    13.9 +  * vdir:      list directory contents
    14.1 --- a/coreutils-directory/receipt	Tue Jun 14 23:10:20 2016 +0300
    14.2 +++ b/coreutils-directory/receipt	Wed Jun 15 17:23:11 2016 +0300
    14.3 @@ -1,37 +1,40 @@
    14.4  # SliTaz package receipt.
    14.5  
    14.6  PACKAGE="coreutils-directory"
    14.7 -VERSION="8.12"
    14.8 +VERSION="8.25"
    14.9  CATEGORY="system-tools"
   14.10  SHORT_DESC="GNU utilities that list directories."
   14.11  MAINTAINER="rcx@zoominternet.net"
   14.12  LICENSE="GPL3"
   14.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   14.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   14.15 +
   14.16  WANTED="coreutils"
   14.17 -
   14.18 -DEPENDS="glibc-base libcap acl"
   14.19 +DEPENDS="glibc-base attr libcap"
   14.20  
   14.21  # Rules to gen a SliTaz package suitable for Tazpkg.
   14.22 -#
   14.23 -# This is a special package for installed system or developer. We only take
   14.24 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   14.25 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   14.26 -#
   14.27  genpkg_rules()
   14.28  {
   14.29 -	mkdir -p $fs/bin
   14.30 -	cp -a $install/usr/bin/ls $fs/bin
   14.31 +	mandir="$fs/usr/share/man/man1"
   14.32 +	mkdir -p $mandir
   14.33  
   14.34 -	mkdir -p $fs/usr/bin
   14.35 -	cp -a $install/usr/bin/dir $fs/usr/bin
   14.36 -	cp -a $install/usr/bin/vdir $fs/usr/bin
   14.37 -	cp -a $install/usr/bin/dircolors $fs/usr/bin
   14.38 +	while read i; do
   14.39 +		mkdir -p $fs$(dirname $i)
   14.40 +		cp -a $install$i $fs$i
   14.41 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   14.42 +	done <<EOT
   14.43 +/bin/ls
   14.44 +/usr/bin/dir
   14.45 +/usr/bin/dircolors
   14.46 +/usr/bin/vdir
   14.47 +EOT
   14.48  }
   14.49  
   14.50  post_remove()
   14.51  {
   14.52 -	ln -s /bin/busybox "$1/bin/ls"
   14.53 -	ln -s /bin/busybox "$1/usr/bin/dir"
   14.54 -	ln -s /bin/busybox "$1/usr/bin/vdir"
   14.55 -	ln -s /bin/busybox "$1/usr/bin/dircolors"
   14.56 +	# Restore all Busybox applets that have been replaced
   14.57 +	while read i; do
   14.58 +		busybox ln -s /bin/busybox "$1$i"
   14.59 +	done <<EOT
   14.60 +/bin/ls
   14.61 +EOT
   14.62  }
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/coreutils-disk/description.txt	Wed Jun 15 17:23:11 2016 +0300
    15.3 @@ -0,0 +1,7 @@
    15.4 +Coreutils: Core GNU (file, text, shell) utilities.
    15.5 +
    15.6 +  * df:        report file system disk space usage
    15.7 +  * du:        estimate file space usage
    15.8 +  * stat:      display file or file system status
    15.9 +  * sync:      synchronize cached writes to persistent storage
   15.10 +  * truncate:  shrink or extend the size of a file to the specified size
    16.1 --- a/coreutils-disk/receipt	Tue Jun 14 23:10:20 2016 +0300
    16.2 +++ b/coreutils-disk/receipt	Wed Jun 15 17:23:11 2016 +0300
    16.3 @@ -1,38 +1,51 @@
    16.4  # SliTaz package receipt.
    16.5  
    16.6  PACKAGE="coreutils-disk"
    16.7 -VERSION="8.12"
    16.8 +VERSION="8.25"
    16.9  CATEGORY="system-tools"
   16.10  SHORT_DESC="GNU utilities that work with disks."
   16.11  MAINTAINER="rcx@zoominternet.net"
   16.12  LICENSE="GPL3"
   16.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   16.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   16.15 +
   16.16  WANTED="coreutils"
   16.17 -
   16.18  DEPENDS="glibc-base"
   16.19  
   16.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   16.21 -#
   16.22 -# This is a special package for installed system or developer. We only take
   16.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   16.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   16.25 -#
   16.26  genpkg_rules()
   16.27  {
   16.28 -	mkdir -p $fs/bin
   16.29 -	cp -a $install/usr/bin/df $fs/bin
   16.30 -	cp -a $install/usr/bin/stat $fs/bin
   16.31 -	cp -a $install/usr/bin/sync $fs/bin
   16.32 +	mandir="$fs/usr/share/man/man1"
   16.33 +	mkdir -p $mandir
   16.34  
   16.35 -	mkdir -p $fs/usr/bin
   16.36 -	cp -a $install/usr/bin/du $fs/usr/bin
   16.37 -	cp -a $install/usr/bin/truncate $fs/usr/bin
   16.38 +	while read i; do
   16.39 +		mkdir -p $fs$(dirname $i)
   16.40 +		cp -a $install$i $fs$i
   16.41 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   16.42 +	done <<EOT
   16.43 +/bin/df
   16.44 +/bin/sync
   16.45 +/usr/bin/du
   16.46 +/usr/bin/stat
   16.47 +/usr/bin/truncate
   16.48 +EOT
   16.49 +}
   16.50 +
   16.51 +post_install()
   16.52 +{
   16.53 +	# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
   16.54 +	# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
   16.55 +	rm "$1/bin/stat"     # /usr/bin/stat
   16.56  }
   16.57  
   16.58  post_remove()
   16.59  {
   16.60 -	ln -s /bin/busybox "$1/bin/df"
   16.61 -	ln -s /bin/busybox "$1/bin/stat"
   16.62 -	ln -s /bin/busybox "$1/bin/sync"
   16.63 -	ln -s /bin/busybox "$1/usr/bin/du"
   16.64 +	# Restore all Busybox applets that have been replaced
   16.65 +	while read i; do
   16.66 +		busybox ln -s /bin/busybox "$1$i"
   16.67 +	done <<EOT
   16.68 +/bin/df
   16.69 +/bin/stat
   16.70 +/bin/sync
   16.71 +/usr/bin/du
   16.72 +EOT
   16.73  }
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/coreutils-file-attributes/description.txt	Wed Jun 15 17:23:11 2016 +0300
    17.3 @@ -0,0 +1,6 @@
    17.4 +Coreutils: Core GNU (file, text, shell) utilities.
    17.5 +
    17.6 +  * chgrp:     change group ownership
    17.7 +  * chmod:     change file mode bits
    17.8 +  * chown:     change file owner and group
    17.9 +  * touch:     change file timestamps
    18.1 --- a/coreutils-file-attributes/receipt	Tue Jun 14 23:10:20 2016 +0300
    18.2 +++ b/coreutils-file-attributes/receipt	Wed Jun 15 17:23:11 2016 +0300
    18.3 @@ -1,35 +1,50 @@
    18.4  # SliTaz package receipt.
    18.5  
    18.6  PACKAGE="coreutils-file-attributes"
    18.7 -VERSION="8.12"
    18.8 +VERSION="8.25"
    18.9  CATEGORY="system-tools"
   18.10  SHORT_DESC="GNU utilities that change file attributes."
   18.11  MAINTAINER="rcx@zoominternet.net"
   18.12  LICENSE="GPL3"
   18.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   18.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   18.15 +
   18.16  WANTED="coreutils"
   18.17 -
   18.18  DEPENDS="glibc-base"
   18.19  
   18.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   18.21 -#
   18.22 -# This is a special package for installed system or developer. We only take
   18.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   18.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   18.25 -#
   18.26  genpkg_rules()
   18.27  {
   18.28 -	mkdir -p $fs/bin
   18.29 -	cp -a $install/usr/bin/chown $fs/bin
   18.30 -	cp -a $install/usr/bin/chgrp $fs/bin
   18.31 -	cp -a $install/usr/bin/chmod $fs/bin
   18.32 -	cp -a $install/usr/bin/touch $fs/bin
   18.33 +	mandir="$fs/usr/share/man/man1"
   18.34 +	mkdir -p $mandir
   18.35 +
   18.36 +	while read i; do
   18.37 +		mkdir -p $fs$(dirname $i)
   18.38 +		cp -a $install$i $fs$i
   18.39 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   18.40 +	done <<EOT
   18.41 +/bin/chgrp
   18.42 +/bin/chmod
   18.43 +/bin/chown
   18.44 +/usr/bin/touch
   18.45 +EOT
   18.46 +}
   18.47 +
   18.48 +post_install()
   18.49 +{
   18.50 +	# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
   18.51 +	# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
   18.52 +	rm "$1/bin/touch"    # /usr/bin/touch
   18.53  }
   18.54  
   18.55  post_remove()
   18.56  {
   18.57 -	ln -s /bin/busybox "$1/bin/chown"
   18.58 -	ln -s /bin/busybox "$1/bin/chgrp"
   18.59 -	ln -s /bin/busybox "$1/bin/chmod"
   18.60 -	ln -s /bin/busybox "$1/bin/touch"
   18.61 +	# Restore all Busybox applets that have been replaced
   18.62 +	while read i; do
   18.63 +		busybox ln -s /bin/busybox "$1$i"
   18.64 +	done <<EOT
   18.65 +/bin/chgrp
   18.66 +/bin/chmod
   18.67 +/bin/chown
   18.68 +/bin/touch
   18.69 +EOT
   18.70  }
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/coreutils-file-format/description.txt	Wed Jun 15 17:23:11 2016 +0300
    19.3 @@ -0,0 +1,5 @@
    19.4 +Coreutils: Core GNU (file, text, shell) utilities.
    19.5 +
    19.6 +  * fmt:       simple optimal text formatter
    19.7 +  * fold:      wrap each input line to fit in specified width
    19.8 +  * pr:        convert text files for printing
    20.1 --- a/coreutils-file-format/receipt	Tue Jun 14 23:10:20 2016 +0300
    20.2 +++ b/coreutils-file-format/receipt	Wed Jun 15 17:23:11 2016 +0300
    20.3 @@ -1,31 +1,39 @@
    20.4  # SliTaz package receipt.
    20.5  
    20.6  PACKAGE="coreutils-file-format"
    20.7 -VERSION="8.12"
    20.8 +VERSION="8.25"
    20.9  CATEGORY="system-tools"
   20.10  SHORT_DESC="GNU utilities that format file contents."
   20.11  MAINTAINER="rcx@zoominternet.net"
   20.12  LICENSE="GPL3"
   20.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   20.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   20.15 +
   20.16  WANTED="coreutils"
   20.17 -
   20.18  DEPENDS="glibc-base"
   20.19  
   20.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   20.21 -#
   20.22 -# This is a special package for installed system or developer. We only take
   20.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   20.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   20.25 -#
   20.26  genpkg_rules()
   20.27  {
   20.28 -	mkdir -p $fs/usr/bin
   20.29 -	cp -a $install/usr/bin/fmt $fs/usr/bin
   20.30 -	cp -a $install/usr/bin/pr $fs/usr/bin
   20.31 -	cp -a $install/usr/bin/fold $fs/usr/bin
   20.32 +	mandir="$fs/usr/share/man/man1"
   20.33 +	mkdir -p $mandir
   20.34 +
   20.35 +	while read i; do
   20.36 +		mkdir -p $fs$(dirname $i)
   20.37 +		cp -a $install$i $fs$i
   20.38 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   20.39 +	done <<EOT
   20.40 +/usr/bin/fmt
   20.41 +/usr/bin/fold
   20.42 +/usr/bin/pr
   20.43 +EOT
   20.44  }
   20.45  
   20.46  post_remove()
   20.47  {
   20.48 -	ln -s /bin/busybox "$1/usr/bin/fold"
   20.49 +	# Restore all Busybox applets that have been replaced
   20.50 +	while read i; do
   20.51 +		busybox ln -s /bin/busybox "$1$i"
   20.52 +	done <<EOT
   20.53 +/usr/bin/fold
   20.54 +EOT
   20.55  }
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/coreutils-file-output-full/description.txt	Wed Jun 15 17:23:11 2016 +0300
    21.3 @@ -0,0 +1,8 @@
    21.4 +Coreutils: Core GNU (file, text, shell) utilities.
    21.5 +
    21.6 +  * base32:    base32 encode/decode data and print to standard output
    21.7 +  * base64:    base64 encode/decode data and print to standard output
    21.8 +  * cat:       concatenate files and print on the standard output
    21.9 +  * nl:        number lines of files
   21.10 +  * od:        dump files in octal and other formats
   21.11 +  * tac:       concatenate and print files in reverse
    22.1 --- a/coreutils-file-output-full/receipt	Tue Jun 14 23:10:20 2016 +0300
    22.2 +++ b/coreutils-file-output-full/receipt	Wed Jun 15 17:23:11 2016 +0300
    22.3 @@ -1,37 +1,52 @@
    22.4  # SliTaz package receipt.
    22.5  
    22.6  PACKAGE="coreutils-file-output-full"
    22.7 -VERSION="8.12"
    22.8 +VERSION="8.25"
    22.9  CATEGORY="system-tools"
   22.10  SHORT_DESC="GNU utilities that output entire files."
   22.11  MAINTAINER="rcx@zoominternet.net"
   22.12  LICENSE="GPL3"
   22.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   22.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   22.15 +
   22.16  WANTED="coreutils"
   22.17 -
   22.18  DEPENDS="glibc-base"
   22.19  
   22.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   22.21 -#
   22.22 -# This is a special package for installed system or developer. We only take
   22.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   22.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   22.25 -#
   22.26  genpkg_rules()
   22.27  {
   22.28 -	mkdir -p $fs/bin
   22.29 -	cp -a $install/usr/bin/cat $fs/bin
   22.30 +	mandir="$fs/usr/share/man/man1"
   22.31 +	mkdir -p $mandir
   22.32  
   22.33 -	mkdir -p $fs/usr/bin
   22.34 -	cp -a $install/usr/bin/tac $fs/usr/bin
   22.35 -	cp -a $install/usr/bin/nl $fs/usr/bin
   22.36 -	cp -a $install/usr/bin/od $fs/usr/bin
   22.37 -	cp -a $install/usr/bin/base64 $fs/usr/bin
   22.38 +	while read i; do
   22.39 +		mkdir -p $fs$(dirname $i)
   22.40 +		cp -a $install$i $fs$i
   22.41 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   22.42 +	done <<EOT
   22.43 +/bin/cat
   22.44 +/usr/bin/base32
   22.45 +/usr/bin/base64
   22.46 +/usr/bin/nl
   22.47 +/usr/bin/od
   22.48 +/usr/bin/tac
   22.49 +EOT
   22.50 +}
   22.51 +
   22.52 +post_install()
   22.53 +{
   22.54 +	# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
   22.55 +	# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
   22.56 +	rm "$1/bin/base64"   # /usr/bin/base64
   22.57  }
   22.58  
   22.59  post_remove()
   22.60  {
   22.61 -	ln -s /bin/busybox "$1/bin/cat"
   22.62 -	ln -s /bin/busybox "$1/usr/bin/od"
   22.63 -	ln -s /bin/busybox "$1/usr/bin/tac"
   22.64 +	# Restore all Busybox applets that have been replaced
   22.65 +	while read i; do
   22.66 +		busybox ln -s /bin/busybox "$1$i"
   22.67 +	done <<EOT
   22.68 +/bin/base64
   22.69 +/bin/cat
   22.70 +/usr/bin/od
   22.71 +/usr/bin/tac
   22.72 +EOT
   22.73  }
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/coreutils-file-output-part/description.txt	Wed Jun 15 17:23:11 2016 +0300
    23.3 @@ -0,0 +1,6 @@
    23.4 +Coreutils: Core GNU (file, text, shell) utilities.
    23.5 +
    23.6 +  * csplit:    split a file into sections determined by context lines
    23.7 +  * head:      output the first part of files
    23.8 +  * split:     split a file into pieces
    23.9 +  * tail:      output the last part of files
    24.1 --- a/coreutils-file-output-part/receipt	Tue Jun 14 23:10:20 2016 +0300
    24.2 +++ b/coreutils-file-output-part/receipt	Wed Jun 15 17:23:11 2016 +0300
    24.3 @@ -1,34 +1,42 @@
    24.4  # SliTaz package receipt.
    24.5  
    24.6  PACKAGE="coreutils-file-output-part"
    24.7 -VERSION="8.12"
    24.8 +VERSION="8.25"
    24.9  CATEGORY="system-tools"
   24.10  SHORT_DESC="GNU utilities that output file parts."
   24.11  MAINTAINER="rcx@zoominternet.net"
   24.12  LICENSE="GPL3"
   24.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   24.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   24.15 +
   24.16  WANTED="coreutils"
   24.17 -
   24.18  DEPENDS="glibc-base"
   24.19  
   24.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   24.21 -#
   24.22 -# This is a special package for installed system or developer. We only take
   24.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   24.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   24.25 -#
   24.26  genpkg_rules()
   24.27  {
   24.28 -	mkdir -p $fs/usr/bin
   24.29 -	cp -a $install/usr/bin/head $fs/usr/bin
   24.30 -	cp -a $install/usr/bin/tail $fs/usr/bin
   24.31 -	cp -a $install/usr/bin/split $fs/usr/bin
   24.32 -	cp -a $install/usr/bin/csplit $fs/usr/bin
   24.33 +	mandir="$fs/usr/share/man/man1"
   24.34 +	mkdir -p $mandir
   24.35 +
   24.36 +	while read i; do
   24.37 +		mkdir -p $fs$(dirname $i)
   24.38 +		cp -a $install$i $fs$i
   24.39 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   24.40 +	done <<EOT
   24.41 +/usr/bin/csplit
   24.42 +/usr/bin/head
   24.43 +/usr/bin/split
   24.44 +/usr/bin/tail
   24.45 +EOT
   24.46  }
   24.47  
   24.48  post_remove()
   24.49  {
   24.50 -	ln -s /bin/busybox "$1/usr/bin/head"
   24.51 -	ln -s /bin/busybox "$1/usr/bin/tail"
   24.52 -	ln -s /bin/busybox "$1/usr/bin/split"
   24.53 +	# Restore all Busybox applets that have been replaced
   24.54 +	while read i; do
   24.55 +		busybox ln -s /bin/busybox "$1$i"
   24.56 +	done <<EOT
   24.57 +/usr/bin/head
   24.58 +/usr/bin/split
   24.59 +/usr/bin/tail
   24.60 +EOT
   24.61  }
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/coreutils-file-sort/description.txt	Wed Jun 15 17:23:11 2016 +0300
    25.3 @@ -0,0 +1,8 @@
    25.4 +Coreutils: Core GNU (file, text, shell) utilities.
    25.5 +
    25.6 +  * comm:      compare two sorted files line by line
    25.7 +  * ptx:       produce a permuted index of file contents
    25.8 +  * shuf:      generate random permutations
    25.9 +  * sort:      sort lines of text files
   25.10 +  * tsort:     perform topological sort
   25.11 +  * uniq:      report or omit repeated lines
    26.1 --- a/coreutils-file-sort/receipt	Tue Jun 14 23:10:20 2016 +0300
    26.2 +++ b/coreutils-file-sort/receipt	Wed Jun 15 17:23:11 2016 +0300
    26.3 @@ -1,36 +1,44 @@
    26.4  # SliTaz package receipt.
    26.5  
    26.6  PACKAGE="coreutils-file-sort"
    26.7 -VERSION="8.12"
    26.8 +VERSION="8.25"
    26.9  CATEGORY="system-tools"
   26.10  SHORT_DESC="GNU utilities that operate on sorted files."
   26.11  MAINTAINER="rcx@zoominternet.net"
   26.12  LICENSE="GPL3"
   26.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   26.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   26.15 +
   26.16  WANTED="coreutils"
   26.17 -
   26.18  DEPENDS="glibc-base"
   26.19  
   26.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   26.21 -#
   26.22 -# This is a special package for installed system or developer. We only take
   26.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   26.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   26.25 -#
   26.26  genpkg_rules()
   26.27  {
   26.28 -	mkdir -p $fs/usr/bin
   26.29 -	cp -a $install/usr/bin/sort $fs/usr/bin
   26.30 -	cp -a $install/usr/bin/shuf $fs/usr/bin
   26.31 -	cp -a $install/usr/bin/uniq $fs/usr/bin
   26.32 -	cp -a $install/usr/bin/comm $fs/usr/bin
   26.33 -	cp -a $install/usr/bin/ptx  $fs/usr/bin
   26.34 -	cp -a $install/usr/bin/tsort $fs/usr/bin
   26.35 +	mandir="$fs/usr/share/man/man1"
   26.36 +	mkdir -p $mandir
   26.37 +
   26.38 +	while read i; do
   26.39 +		mkdir -p $fs$(dirname $i)
   26.40 +		cp -a $install$i $fs$i
   26.41 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   26.42 +	done <<EOT
   26.43 +/usr/bin/comm
   26.44 +/usr/bin/ptx
   26.45 +/usr/bin/shuf
   26.46 +/usr/bin/sort
   26.47 +/usr/bin/tsort
   26.48 +/usr/bin/uniq
   26.49 +EOT
   26.50  }
   26.51  
   26.52  post_remove()
   26.53  {
   26.54 -	ln -s /bin/busybox "$1/usr/bin/sort"
   26.55 -	ln -s /bin/busybox "$1/usr/bin/uniq"
   26.56 -	ln -s /bin/busybox "$1/usr/bin/comm"
   26.57 +	# Restore all Busybox applets that have been replaced
   26.58 +	while read i; do
   26.59 +		busybox ln -s /bin/busybox "$1$i"
   26.60 +	done <<EOT
   26.61 +/usr/bin/comm
   26.62 +/usr/bin/sort
   26.63 +/usr/bin/uniq
   26.64 +EOT
   26.65  }
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/coreutils-file-special/description.txt	Wed Jun 15 17:23:11 2016 +0300
    27.3 @@ -0,0 +1,12 @@
    27.4 +Coreutils: Core GNU (file, text, shell) utilities.
    27.5 +
    27.6 +  * link:      call the link function to create a link to a file
    27.7 +  * ln:        make links between files
    27.8 +  * mkdir:     make directories
    27.9 +  * mkfifo:    make FIFOs (named pipes)
   27.10 +  * mknod:     make block or character special files
   27.11 +  * mktemp:    create a temporary file or directory
   27.12 +  * readlink:  print resolved symbolic links or canonical file names
   27.13 +  * realpath:  print the resolved path
   27.14 +  * rmdir:     remove empty directories
   27.15 +  * unlink:    call the unlink function to remove the specified file
    28.1 --- a/coreutils-file-special/receipt	Tue Jun 14 23:10:20 2016 +0300
    28.2 +++ b/coreutils-file-special/receipt	Wed Jun 15 17:23:11 2016 +0300
    28.3 @@ -1,54 +1,59 @@
    28.4  # SliTaz package receipt.
    28.5  
    28.6  PACKAGE="coreutils-file-special"
    28.7 -VERSION="8.12"
    28.8 +VERSION="8.25"
    28.9  CATEGORY="system-tools"
   28.10  SHORT_DESC="GNU utilities that work with special file types."
   28.11  MAINTAINER="rcx@zoominternet.net"
   28.12  LICENSE="GPL3"
   28.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   28.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   28.15 +
   28.16  WANTED="coreutils"
   28.17 -
   28.18  DEPENDS="glibc-base"
   28.19  
   28.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   28.21 -#
   28.22 -# This is a special package for installed system or developer. We only take
   28.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   28.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   28.25 -#
   28.26  genpkg_rules()
   28.27  {
   28.28 -	mkdir -p $fs/bin
   28.29 -	cp -a $install/usr/bin/ln $fs/bin
   28.30 -	cp -a $install/usr/bin/mkdir $fs/bin
   28.31 -	cp -a $install/usr/bin/mknod $fs/bin
   28.32 -	cp -a $install/usr/bin/rmdir $fs/bin
   28.33 +	mandir="$fs/usr/share/man/man1"
   28.34 +	mkdir -p $mandir
   28.35  
   28.36 -	mkdir -p $fs/usr/bin
   28.37 -	cp -a $install/usr/bin/link $fs/usr/bin
   28.38 -	cp -a $install/usr/bin/mkfifo $fs/usr/bin
   28.39 -	cp -a $install/usr/bin/mktemp $fs/usr/bin
   28.40 -	cp -a $install/usr/bin/readlink $fs/usr/bin
   28.41 -	cp -a $install/usr/bin/unlink $fs/usr/bin
   28.42 +	while read i; do
   28.43 +		mkdir -p $fs$(dirname $i)
   28.44 +		cp -a $install$i $fs$i
   28.45 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   28.46 +	done <<EOT
   28.47 +/bin/ln
   28.48 +/bin/mkdir
   28.49 +/bin/mknod
   28.50 +/bin/rmdir
   28.51 +/usr/bin/link
   28.52 +/usr/bin/mkfifo
   28.53 +/usr/bin/mktemp
   28.54 +/usr/bin/readlink
   28.55 +/usr/bin/realpath
   28.56 +/usr/bin/unlink
   28.57 +EOT
   28.58  }
   28.59  
   28.60 -pre_remove()
   28.61 +post_install()
   28.62  {
   28.63 -	# Need to handle the removal of ln
   28.64 -	cp -a -fd "$1/bin/ln" "$1/bin/ln-coreutils"
   28.65 +	# Remove Busybox applets in order to not clash with ("/bin", "/sbin",
   28.66 +	# "/usr/bin" and "/usr/sbin" conflicts with the same filename)
   28.67 +	rm "$1/bin/mktemp"   # /usr/bin/mktemp
   28.68  }
   28.69  
   28.70  post_remove()
   28.71  {
   28.72 -	# Restore ln
   28.73 -	ln-coreutils -s /bin/busybox "$1/bin/ln"
   28.74 -
   28.75 -	ln -s /bin/busybox "$1/bin/mkdir"
   28.76 -	ln -s /bin/busybox "$1/bin/mknod"
   28.77 -	ln -s /bin/busybox "$1/bin/rmdir"
   28.78 -	ln -s /bin/busybox "$1/usr/bin/mkfifo"
   28.79 -	ln -s /bin/busybox "$1/usr/bin/readlink"
   28.80 -	
   28.81 -	rm -f "$1/bin/ln-coreutils"
   28.82 +	# Restore all Busybox applets that have been replaced
   28.83 +	while read i; do
   28.84 +		busybox ln -s /bin/busybox "$1$i"
   28.85 +	done <<EOT
   28.86 +/bin/ln
   28.87 +/bin/mkdir
   28.88 +/bin/mknod
   28.89 +/bin/mktemp
   28.90 +/bin/rmdir
   28.91 +/usr/bin/mkfifo
   28.92 +/usr/bin/realpath
   28.93 +EOT
   28.94  }
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/coreutils-file-summarize/description.txt	Wed Jun 15 17:23:11 2016 +0300
    29.3 @@ -0,0 +1,11 @@
    29.4 +Coreutils: Core GNU (file, text, shell) utilities.
    29.5 +
    29.6 +  * cksum:     checksum and count the bytes in a file
    29.7 +  * md5sum:    compute and check MD5 message digest
    29.8 +  * sha1sum:   compute and check SHA1 message digest
    29.9 +  * sha224sum: compute and check SHA224 message digest
   29.10 +  * sha256sum: compute and check SHA256 message digest
   29.11 +  * sha384sum: compute and check SHA384 message digest
   29.12 +  * sha512sum: compute and check SHA512 message digest
   29.13 +  * sum:       checksum and count the blocks in a file
   29.14 +  * wc:        print newline, word, and byte counts for each file
    30.1 --- a/coreutils-file-summarize/receipt	Tue Jun 14 23:10:20 2016 +0300
    30.2 +++ b/coreutils-file-summarize/receipt	Wed Jun 15 17:23:11 2016 +0300
    30.3 @@ -1,43 +1,51 @@
    30.4  # SliTaz package receipt.
    30.5  
    30.6  PACKAGE="coreutils-file-summarize"
    30.7 -VERSION="8.12"
    30.8 +VERSION="8.25"
    30.9  CATEGORY="system-tools"
   30.10  SHORT_DESC="GNU utilities that summarize files."
   30.11  MAINTAINER="rcx@zoominternet.net"
   30.12  LICENSE="GPL3"
   30.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   30.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   30.15 +
   30.16  WANTED="coreutils"
   30.17 -
   30.18  DEPENDS="glibc-base"
   30.19  
   30.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   30.21 -#
   30.22 -# This is a special package for installed system or developer. We only take
   30.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   30.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   30.25 -#
   30.26  genpkg_rules()
   30.27  {
   30.28 -	mkdir -p $fs/usr/bin
   30.29 -	cp -a $install/usr/bin/wc $fs/usr/bin
   30.30 -	cp -a $install/usr/bin/sum $fs/usr/bin
   30.31 -	cp -a $install/usr/bin/cksum $fs/usr/bin
   30.32 -	cp -a $install/usr/bin/md5sum $fs/usr/bin
   30.33 -	cp -a $install/usr/bin/sha1sum $fs/usr/bin
   30.34 -	cp -a $install/usr/bin/sha224sum $fs/usr/bin
   30.35 -	cp -a $install/usr/bin/sha256sum $fs/usr/bin
   30.36 -	cp -a $install/usr/bin/sha384sum $fs/usr/bin
   30.37 -	cp -a $install/usr/bin/sha512sum $fs/usr/bin
   30.38 +	mandir="$fs/usr/share/man/man1"
   30.39 +	mkdir -p $mandir
   30.40 +
   30.41 +	while read i; do
   30.42 +		mkdir -p $fs$(dirname $i)
   30.43 +		cp -a $install$i $fs$i
   30.44 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   30.45 +	done <<EOT
   30.46 +/usr/bin/cksum
   30.47 +/usr/bin/md5sum
   30.48 +/usr/bin/sha1sum
   30.49 +/usr/bin/sha224sum
   30.50 +/usr/bin/sha256sum
   30.51 +/usr/bin/sha384sum
   30.52 +/usr/bin/sha512sum
   30.53 +/usr/bin/sum
   30.54 +/usr/bin/wc
   30.55 +EOT
   30.56  }
   30.57  
   30.58  post_remove()
   30.59  {
   30.60 -	ln -s /bin/busybox "$1/usr/bin/wc"
   30.61 -	ln -s /bin/busybox "$1/usr/bin/sum"
   30.62 -	ln -s /bin/busybox "$1/usr/bin/cksum"
   30.63 -	ln -s /bin/busybox "$1/usr/bin/md5sum"
   30.64 -	ln -s /bin/busybox "$1/usr/bin/sha1sum"
   30.65 -	ln -s /bin/busybox "$1/usr/bin/sha256sum"
   30.66 -	ln -s /bin/busybox "$1/usr/bin/sha512sum"
   30.67 +	# Restore all Busybox applets that have been replaced
   30.68 +	while read i; do
   30.69 +		busybox ln -s /bin/busybox "$1$i"
   30.70 +	done <<EOT
   30.71 +/usr/bin/cksum
   30.72 +/usr/bin/md5sum
   30.73 +/usr/bin/sha1sum
   30.74 +/usr/bin/sha256sum
   30.75 +/usr/bin/sha512sum
   30.76 +/usr/bin/sum
   30.77 +/usr/bin/wc
   30.78 +EOT
   30.79  }
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/coreutils-line/description.txt	Wed Jun 15 17:23:11 2016 +0300
    31.3 @@ -0,0 +1,5 @@
    31.4 +Coreutils: Core GNU (file, text, shell) utilities.
    31.5 +
    31.6 +  * cut:       remove sections from each line of files
    31.7 +  * join:      join lines of two files on a common field
    31.8 +  * paste:     merge lines of files
    32.1 --- a/coreutils-line/receipt	Tue Jun 14 23:10:20 2016 +0300
    32.2 +++ b/coreutils-line/receipt	Wed Jun 15 17:23:11 2016 +0300
    32.3 @@ -1,31 +1,39 @@
    32.4  # SliTaz package receipt.
    32.5  
    32.6  PACKAGE="coreutils-line"
    32.7 -VERSION="8.12"
    32.8 +VERSION="8.25"
    32.9  CATEGORY="system-tools"
   32.10  SHORT_DESC="GNU utilities that operate on fields within a line."
   32.11  MAINTAINER="rcx@zoominternet.net"
   32.12  LICENSE="GPL3"
   32.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   32.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   32.15 +
   32.16  WANTED="coreutils"
   32.17 -
   32.18 -DEPENDS="glibc-base gmp libcap"
   32.19 +DEPENDS="glibc-base"
   32.20  
   32.21  # Rules to gen a SliTaz package suitable for Tazpkg.
   32.22 -#
   32.23 -# This is a special package for installed system or developer. We only take
   32.24 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   32.25 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   32.26 -#
   32.27  genpkg_rules()
   32.28  {
   32.29 -	mkdir -p $fs/usr/bin
   32.30 -	cp -a $install/usr/bin/cut $fs/usr/bin
   32.31 -	cp -a $install/usr/bin/paste $fs/usr/bin
   32.32 -	cp -a $install/usr/bin/join $fs/usr/bin
   32.33 +	mandir="$fs/usr/share/man/man1"
   32.34 +	mkdir -p $mandir
   32.35 +
   32.36 +	while read i; do
   32.37 +		mkdir -p $fs$(dirname $i)
   32.38 +		cp -a $install$i $fs$i
   32.39 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   32.40 +	done <<EOT
   32.41 +/usr/bin/cut
   32.42 +/usr/bin/join
   32.43 +/usr/bin/paste
   32.44 +EOT
   32.45  }
   32.46  
   32.47  post_remove()
   32.48  {
   32.49 -	ln -s /bin/busybox "$1/usr/bin/cut"
   32.50 +	# Restore all Busybox applets that have been replaced
   32.51 +	while read i; do
   32.52 +		busybox ln -s /bin/busybox "$1$i"
   32.53 +	done <<EOT
   32.54 +/usr/bin/cut
   32.55 +EOT
   32.56  }
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/coreutils-numeric/description.txt	Wed Jun 15 17:23:11 2016 +0300
    33.3 @@ -0,0 +1,4 @@
    33.4 +Coreutils: Core GNU (file, text, shell) utilities.
    33.5 +
    33.6 +  * factor:    factor numbers
    33.7 +  * seq:       print a sequence of numbers
    34.1 --- a/coreutils-numeric/receipt	Tue Jun 14 23:10:20 2016 +0300
    34.2 +++ b/coreutils-numeric/receipt	Wed Jun 15 17:23:11 2016 +0300
    34.3 @@ -1,30 +1,38 @@
    34.4  # SliTaz package receipt.
    34.5  
    34.6  PACKAGE="coreutils-numeric"
    34.7 -VERSION="8.12"
    34.8 +VERSION="8.25"
    34.9  CATEGORY="system-tools"
   34.10  SHORT_DESC="GNU numeric utilities."
   34.11  MAINTAINER="rcx@zoominternet.net"
   34.12  LICENSE="GPL3"
   34.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   34.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   34.15 +
   34.16  WANTED="coreutils"
   34.17 -
   34.18  DEPENDS="glibc-base gmp"
   34.19  
   34.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   34.21 -#
   34.22 -# This is a special package for installed system or developer. We only take
   34.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   34.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   34.25 -#
   34.26  genpkg_rules()
   34.27  {
   34.28 -	mkdir -p $fs/usr/bin
   34.29 -	cp -a $install/usr/bin/factor $fs/usr/bin
   34.30 -	cp -a $install/usr/bin/seq $fs/usr/bin
   34.31 +	mandir="$fs/usr/share/man/man1"
   34.32 +	mkdir -p $mandir
   34.33 +
   34.34 +	while read i; do
   34.35 +		mkdir -p $fs$(dirname $i)
   34.36 +		cp -a $install$i $fs$i
   34.37 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   34.38 +	done <<EOT
   34.39 +/usr/bin/factor
   34.40 +/usr/bin/seq
   34.41 +EOT
   34.42  }
   34.43  
   34.44  post_remove()
   34.45  {
   34.46 -	ln -s /bin/busybox "$1/usr/bin/seq"
   34.47 +	# Restore all Busybox applets that have been replaced
   34.48 +	while read i; do
   34.49 +		busybox ln -s /bin/busybox "$1$i"
   34.50 +	done <<EOT
   34.51 +/usr/bin/seq
   34.52 +EOT
   34.53  }
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/coreutils-operations/description.txt	Wed Jun 15 17:23:11 2016 +0300
    35.3 @@ -0,0 +1,7 @@
    35.4 +Coreutils: Core GNU (file, text, shell) utilities.
    35.5 +
    35.6 +  * cp:        copy files and directories
    35.7 +  * dd:        convert and copy a file
    35.8 +  * install:   copy files and set attributes
    35.9 +  * mv:        move (rename) files
   35.10 +  * shred:     overwrite a file to hide its contents, and optionally delete it
    36.1 --- a/coreutils-operations/receipt	Tue Jun 14 23:10:20 2016 +0300
    36.2 +++ b/coreutils-operations/receipt	Wed Jun 15 17:23:11 2016 +0300
    36.3 @@ -1,43 +1,44 @@
    36.4  # SliTaz package receipt.
    36.5  
    36.6  PACKAGE="coreutils-operations"
    36.7 -VERSION="8.12"
    36.8 +VERSION="8.25"
    36.9  CATEGORY="system-tools"
   36.10  SHORT_DESC="GNU utilities that perform basic operations."
   36.11  MAINTAINER="rcx@zoominternet.net"
   36.12  LICENSE="GPL3"
   36.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   36.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   36.15 +
   36.16  WANTED="coreutils"
   36.17 -
   36.18 -DEPENDS="glibc-base acl"
   36.19 +DEPENDS="glibc-base acl attr"
   36.20  
   36.21  # Rules to gen a SliTaz package suitable for Tazpkg.
   36.22 -#
   36.23 -# This is a special package for installed system or developer. We only take
   36.24 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   36.25 -#
   36.26  genpkg_rules()
   36.27  {
   36.28 -	mkdir -p $fs/bin
   36.29 -	#cp -a $install/usr/bin/cp $fs/bin
   36.30 -	cp -a $install/usr/bin/dd $fs/bin
   36.31 -	cp -a $install/usr/bin/mv $fs/bin
   36.32 -	cp -a $install/usr/bin/ln $fs/bin
   36.33 -	#cp -a $install/usr/bin/rm $fs/bin
   36.34 +	mandir="$fs/usr/share/man/man1"
   36.35 +	mkdir -p $mandir
   36.36  
   36.37 -	mkdir -p $fs/usr/bin
   36.38 -	cp -a $install/usr/bin/install $fs/usr/bin
   36.39 -	cp -a $install/usr/bin/shred $fs/usr/bin
   36.40 +	while read i; do
   36.41 +		mkdir -p $fs$(dirname $i)
   36.42 +		cp -a $install$i $fs$i
   36.43 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   36.44 +	done <<EOT
   36.45 +/bin/cp
   36.46 +/bin/dd
   36.47 +/bin/mv
   36.48 +/usr/bin/install
   36.49 +/usr/bin/shred
   36.50 +EOT
   36.51  }
   36.52  
   36.53  post_remove()
   36.54  {
   36.55 -	# use busybox ln applet directly since /bin/ln
   36.56 -	# in this package is remove already
   36.57 -#	/bin/busybox ln -fs /bin/busybox "$1/bin/cp"
   36.58 -	/bin/busybox ln -fs /bin/busybox "$1/bin/dd"
   36.59 -	/bin/busybox ln -fs /bin/busybox "$1/bin/mv"
   36.60 -	/bin/busybox ln -fs /bin/busybox "$1/bin/ln"
   36.61 -#	/bin/busybox ln -fs /bin/busybox "$1/bin/rm"
   36.62 -	/bin/busybox ln -fs /bin/busybox "$1/usr/bin/install"
   36.63 +	# Restore all Busybox applets that have been replaced
   36.64 +	while read i; do
   36.65 +		busybox ln -s /bin/busybox "$1$i"
   36.66 +	done <<EOT
   36.67 +/bin/cp
   36.68 +/bin/dd
   36.69 +/bin/mv
   36.70 +/usr/bin/install
   36.71 +EOT
   36.72  }
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/coreutils-path/description.txt	Wed Jun 15 17:23:11 2016 +0300
    37.3 @@ -0,0 +1,5 @@
    37.4 +Coreutils: Core GNU (file, text, shell) utilities.
    37.5 +
    37.6 +  * basename:  strip directory and suffix from filenames
    37.7 +  * dirname:   strip last component from file name
    37.8 +  * pathchk:   check whether file names are valid or portable
    38.1 --- a/coreutils-path/receipt	Tue Jun 14 23:10:20 2016 +0300
    38.2 +++ b/coreutils-path/receipt	Wed Jun 15 17:23:11 2016 +0300
    38.3 @@ -1,32 +1,40 @@
    38.4  # SliTaz package receipt.
    38.5  
    38.6  PACKAGE="coreutils-path"
    38.7 -VERSION="8.12"
    38.8 +VERSION="8.25"
    38.9  CATEGORY="system-tools"
   38.10  SHORT_DESC="GNU utilities that perform path manipulation."
   38.11  MAINTAINER="rcx@zoominternet.net"
   38.12  LICENSE="GPL3"
   38.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   38.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   38.15 +
   38.16  WANTED="coreutils"
   38.17 -
   38.18  DEPENDS="glibc-base"
   38.19  
   38.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   38.21 -#
   38.22 -# This is a special package for installed system or developer. We only take
   38.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   38.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   38.25 -#
   38.26  genpkg_rules()
   38.27  {
   38.28 -	mkdir -p $fs/usr/bin
   38.29 -	cp -a $install/usr/bin/basename $fs/usr/bin
   38.30 -	cp -a $install/usr/bin/dirname $fs/usr/bin
   38.31 -	cp -a $install/usr/bin/pathchk $fs/usr/bin
   38.32 +	mandir="$fs/usr/share/man/man1"
   38.33 +	mkdir -p $mandir
   38.34 +
   38.35 +	while read i; do
   38.36 +		mkdir -p $fs$(dirname $i)
   38.37 +		cp -a $install$i $fs$i
   38.38 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   38.39 +	done <<EOT
   38.40 +/usr/bin/basename
   38.41 +/usr/bin/dirname
   38.42 +/usr/bin/pathchk
   38.43 +EOT
   38.44  }
   38.45  
   38.46  post_remove()
   38.47  {
   38.48 -	ln -s /bin/busybox "$1/usr/bin/basename"
   38.49 -	ln -s /bin/busybox "$1/usr/bin/dirname"
   38.50 +	# Restore all Busybox applets that have been replaced
   38.51 +	while read i; do
   38.52 +		busybox ln -s /bin/busybox "$1$i"
   38.53 +	done <<EOT
   38.54 +/usr/bin/basename
   38.55 +/usr/bin/dirname
   38.56 +EOT
   38.57  }
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/coreutils-print/description.txt	Wed Jun 15 17:23:11 2016 +0300
    39.3 @@ -0,0 +1,6 @@
    39.4 +Coreutils: Core GNU (file, text, shell) utilities.
    39.5 +
    39.6 +  * echo:      display a line of text
    39.7 +  * numfmt:    convert numbers from/to human-readable strings
    39.8 +  * printf:    format and print data
    39.9 +  * yes:       output a string repeatedly until killed
    40.1 --- a/coreutils-print/receipt	Tue Jun 14 23:10:20 2016 +0300
    40.2 +++ b/coreutils-print/receipt	Wed Jun 15 17:23:11 2016 +0300
    40.3 @@ -1,35 +1,42 @@
    40.4  # SliTaz package receipt.
    40.5  
    40.6  PACKAGE="coreutils-print"
    40.7 -VERSION="8.12"
    40.8 +VERSION="8.25"
    40.9  CATEGORY="system-tools"
   40.10  SHORT_DESC="GNU utilities that print text."
   40.11  MAINTAINER="rcx@zoominternet.net"
   40.12  LICENSE="GPL3"
   40.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   40.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   40.15 +
   40.16  WANTED="coreutils"
   40.17 -
   40.18  DEPENDS="glibc-base"
   40.19  
   40.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   40.21 -#
   40.22 -# This is a special package for installed system or developer. We only take
   40.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   40.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   40.25 -#
   40.26  genpkg_rules()
   40.27  {
   40.28 -	mkdir -p $fs/bin
   40.29 -	cp -a $install/usr/bin/echo $fs/bin
   40.30 +	mandir="$fs/usr/share/man/man1"
   40.31 +	mkdir -p $mandir
   40.32  
   40.33 -	mkdir -p $fs/usr/bin
   40.34 -	cp -a $install/usr/bin/printf $fs/usr/bin
   40.35 -	cp -a $install/usr/bin/yes $fs/usr/bin
   40.36 +	while read i; do
   40.37 +		mkdir -p $fs$(dirname $i)
   40.38 +		cp -a $install$i $fs$i
   40.39 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   40.40 +	done <<EOT
   40.41 +/bin/echo
   40.42 +/usr/bin/numfmt
   40.43 +/usr/bin/printf
   40.44 +/usr/bin/yes
   40.45 +EOT
   40.46  }
   40.47  
   40.48  post_remove()
   40.49  {
   40.50 -	ln -s /bin/busybox "$1/bin/echo"
   40.51 -	ln -s /bin/busybox "$1/usr/bin/printf"
   40.52 -	ln -s /bin/busybox "$1/usr/bin/yes"
   40.53 +	# Restore all Busybox applets that have been replaced
   40.54 +	while read i; do
   40.55 +		busybox ln -s /bin/busybox "$1$i"
   40.56 +	done <<EOT
   40.57 +/bin/echo
   40.58 +/bin/printf
   40.59 +/bin/yes
   40.60 +EOT
   40.61  }
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/coreutils-redirection/description.txt	Wed Jun 15 17:23:11 2016 +0300
    41.3 @@ -0,0 +1,3 @@
    41.4 +Coreutils: Core GNU (file, text, shell) utilities.
    41.5 +
    41.6 +  * tee:       read from standard input and write to standard output and files
    42.1 --- a/coreutils-redirection/receipt	Tue Jun 14 23:10:20 2016 +0300
    42.2 +++ b/coreutils-redirection/receipt	Wed Jun 15 17:23:11 2016 +0300
    42.3 @@ -1,29 +1,37 @@
    42.4  # SliTaz package receipt.
    42.5  
    42.6  PACKAGE="coreutils-redirection"
    42.7 -VERSION="8.12"
    42.8 +VERSION="8.25"
    42.9  CATEGORY="system-tools"
   42.10  SHORT_DESC="GNU utilities that work with disks."
   42.11  MAINTAINER="rcx@zoominternet.net"
   42.12  LICENSE="GPL3"
   42.13 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   42.14 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   42.15 +
   42.16  WANTED="coreutils"
   42.17 -
   42.18  DEPENDS="glibc-base"
   42.19  
   42.20  # Rules to gen a SliTaz package suitable for Tazpkg.
   42.21 -#
   42.22 -# This is a special package for installed system or developer. We only take
   42.23 -# a few things, as Busybox provides all the basic utilities, but not for compiling.
   42.24 -# But DO NOT erase a Busybox applet, remove it before with pre_install rules.
   42.25 -#
   42.26  genpkg_rules()
   42.27  {
   42.28 -	mkdir -p $fs/usr/bin
   42.29 -	cp -a $install/usr/bin/tee $fs/usr/bin
   42.30 +	mandir="$fs/usr/share/man/man1"
   42.31 +	mkdir -p $mandir
   42.32 +
   42.33 +	while read i; do
   42.34 +		mkdir -p $fs$(dirname $i)
   42.35 +		cp -a $install$i $fs$i
   42.36 +		find $install -name "$(basename $i).*" -exec cp -a \{\} $mandir \;
   42.37 +	done <<EOT
   42.38 +/usr/bin/tee
   42.39 +EOT
   42.40  }
   42.41  
   42.42  post_remove()
   42.43  {
   42.44 -	ln -s /bin/busybox "$1/usr/bin/tee"
   42.45 +	# Restore all Busybox applets that have been replaced
   42.46 +	while read i; do
   42.47 +		busybox ln -s /bin/busybox "$1$i"
   42.48 +	done <<EOT
   42.49 +/usr/bin/tee
   42.50 +EOT
   42.51  }
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/coreutils/description.txt	Wed Jun 15 17:23:11 2016 +0300
    43.3 @@ -0,0 +1,17 @@
    43.4 +Coreutils: Core GNU (file, text, shell) utilities.
    43.5 +
    43.6 +  * base64:    base64 encode/decode data and print to standard output
    43.7 +  * cp:        copy files and directories
    43.8 +  * csplit:    split a file into sections determined by context lines
    43.9 +  * factor:    factor numbers
   43.10 +  * fmt:       simple optimal text formatter
   43.11 +  * groups:    print the groups a user is in
   43.12 +  * join:      join lines of two files on a common field
   43.13 +  * od:        dump files in octal and other formats
   43.14 +  * paste:     merge lines of files
   43.15 +  * ptx:       produce a permuted index of file contents
   43.16 +  * shred:     overwrite a file to hide its contents, and optionally delete it
   43.17 +  * shuf:      generate random permutations
   43.18 +  * split:     split a file into pieces
   43.19 +  * users:     print the user names of users currently logged in to the current
   43.20 +               host
    44.1 --- a/coreutils/receipt	Tue Jun 14 23:10:20 2016 +0300
    44.2 +++ b/coreutils/receipt	Wed Jun 15 17:23:11 2016 +0300
    44.3 @@ -1,90 +1,84 @@
    44.4  # SliTaz package receipt.
    44.5  
    44.6  PACKAGE="coreutils"
    44.7 -VERSION="8.12"
    44.8 +VERSION="8.25"
    44.9  CATEGORY="system-tools"
   44.10  SHORT_DESC="Utilities for using and setting the basic system."
   44.11  MAINTAINER="pankso@slitaz.org"
   44.12  LICENSE="GPL3"
   44.13 +WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html"
   44.14  TARBALL="$PACKAGE-$VERSION.tar.xz"
   44.15 -WEB_SITE="http://www.gnu.org/software/coreutils/"
   44.16 -WGET_URL="ftp://ftp.gnu.org/gnu/$PACKAGE/$TARBALL"
   44.17 +WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL"
   44.18  
   44.19 -DEPENDS="glibc-base gmp libcap"
   44.20 -BUILD_DEPENDS="slitaz-toolchain libcap-dev gmp-dev m4 autoconf automake"
   44.21 +SIBLINGS="coreutils-multicall"
   44.22 +SPLIT="coreutils-character coreutils-command coreutils-conditions coreutils-\
   44.23 +context-system coreutils-context-user coreutils-context-working coreutils-\
   44.24 +directory coreutils-disk coreutils-file-attributes coreutils-file-format \
   44.25 +coreutils-file-output-full coreutils-file-output-part coreutils-file-sort \
   44.26 +coreutils-file-special coreutils-file-summarize coreutils-line coreutils-\
   44.27 +numeric coreutils-operations coreutils-path coreutils-print coreutils-\
   44.28 +redirection"
   44.29 +DEPENDS="glibc-base acl attr gmp"
   44.30 +BUILD_DEPENDS="automake xz libcap-dev gmp-dev"
   44.31  
   44.32  # Rules to configure and make the package.
   44.33  compile_rules()
   44.34  {
   44.35 -	# NOTE: There does not seem to be a problem with sigcontext.h in Linux 2.6.29.3
   44.36 +	# LFS: Coreutils Internationalization Fixes Patch
   44.37 +	patch -Np1 -i $stuff/coreutils-8.25-i18n-2.patch
   44.38 +	# SliTaz: show extended info touching CPU via uname
   44.39 +	patch  -p1 -i $stuff/uname.u
   44.40  
   44.41 -	# Hack to fix ls: expected specifier-qualifier-list before '__u64'
   44.42 -	# Hack to change uname: so can see the cpu type your running on with uname
   44.43 -	while read patch_file; do
   44.44 -		if [ -f done.$patch_file ]; then
   44.45 -			echo "Skipping $patch_file"
   44.46 -			continue
   44.47 -		fi
   44.48 -		echo "Apply $patch_file"
   44.49 -		patch -p1 < $stuff/$patch_file || return 1
   44.50 -		touch done.$patch_file
   44.51 -	done <<EOT
   44.52 -ls.u
   44.53 -uname.u
   44.54 -EOT
   44.55 +	autoreconf -fi
   44.56  
   44.57 -	sed -i 's/1.10a/1.10.2/' configure.ac || return 1
   44.58 -	sed -i 's/dist-xz/dist-lzma/' configure.ac || return 1
   44.59 -
   44.60 -	./configure $CONFIGURE_ARGS &&
   44.61 +	FORCE_UNSAFE_CONFIGURE=1 ./configure $CONFIGURE_ARGS &&
   44.62  	make && make install
   44.63  
   44.64 -	# Restore original sigcontext.h
   44.65 -	# mv -f /usr/include/asm/sigcontext.h.bak /usr/include/asm/sigcontext.h
   44.66 +	# LFS: Move programs to the locations specified by the FHS
   44.67 +	mkdir -p \
   44.68 +		$install/bin \
   44.69 +		$install/usr/sbin \
   44.70 +		$install/usr/share/man/man8
   44.71 +	for i in cat chgrp chmod chown cp date dd df echo false ln ls mkdir \
   44.72 +		mknod mv pwd rm rmdir stty sync true uname; do
   44.73 +		mv $install/usr/bin/$i $install/bin
   44.74 +	done
   44.75 +	mv  $install/usr/bin/chroot $install/usr/sbin
   44.76 +	mv  $install/usr/share/man/man1/chroot.1 \
   44.77 +		$install/usr/share/man/man8/chroot.8
   44.78 +	sed -i 's|"1"|"8"|' $install/usr/share/man/man8/chroot.8
   44.79 +
   44.80 +	find $install/usr/share/man -type f -exec gzip -9 \{\} \;
   44.81  }
   44.82  
   44.83  # Rules to gen a SliTaz package suitable for Tazpkg.
   44.84 -#
   44.85 -# This is a special package for installed system or developer. We only take
   44.86 -# a fiew things, Busybox provide all the basic utilitie, but not for compiling.
   44.87 -# But DO NOT ecrase a Busybox applet, remove it before with pre_install rules.
   44.88 -#
   44.89  genpkg_rules()
   44.90  {
   44.91 +	# A set of binaries looks intriguing, isn't it?
   44.92 +	# For what is this package with exactly these binaries?
   44.93 +
   44.94  	mkdir -p $fs/usr/bin $fs/bin
   44.95 -	# Utils...
   44.96 -	cp -a $install/usr/bin/base64 $fs/usr/bin
   44.97 -	cp -a $install/usr/bin/csplit $fs/usr/bin
   44.98 -	cp -a $install/usr/bin/factor $fs/usr/bin
   44.99 -	cp -a $install/usr/bin/fmt $fs/usr/bin
  44.100 -	cp -a $install/usr/bin/join $fs/usr/bin
  44.101 -	cp -a $install/usr/bin/od $fs/usr/bin
  44.102 -	cp -a $install/usr/bin/paste $fs/usr/bin
  44.103 -	cp -a $install/usr/bin/ptx $fs/usr/bin
  44.104 -	cp -a $install/usr/bin/shred $fs/usr/bin
  44.105 -	cp -a $install/usr/bin/shuf $fs/usr/bin
  44.106 -	cp -a $install/usr/bin/split $fs/usr/bin
  44.107 -	cp -a $install/usr/bin/users $fs/usr/bin
  44.108 -	cp -a $install/usr/bin/groups $fs/usr/bin
  44.109 -	cp -a $install/usr/bin/cp $fs/usr/bin
  44.110 +
  44.111 +	cd $install/usr/bin
  44.112 +	cp -a base64 csplit factor fmt join od paste ptx shred shuf split users \
  44.113 +		groups $fs/usr/bin
  44.114 +
  44.115 +	cp -a $install/bin/cp $fs/bin
  44.116  }
  44.117  
  44.118  post_install()
  44.119  {
  44.120 -	rm "$1/bin/cp" &&
  44.121 -	mv "$1/usr/bin/cp" "$1/bin"
  44.122 +	# Remove Busybox applet in order to not clash with
  44.123 +	# /usr/bin/base64 from this package.
  44.124 +	rm "$1/bin/base64"
  44.125  }
  44.126  
  44.127  post_remove()
  44.128  {
  44.129 -	ln -s ../../bin/busybox "$1/usr/bin/od"
  44.130 -	ln -s ../../bin/busybox "$1/usr/bin/split"
  44.131 -	rm -f "$1/bin/cp"
  44.132 -	ln -s busybox "$1/bin/cp"
  44.133 +	ln -s      busybox "$1/bin/base64"
  44.134 +	ln -s      busybox "$1/bin/cp"
  44.135 +	ln -s /bin/busybox "$1/usr/bin/groups"
  44.136 +	ln -s /bin/busybox "$1/usr/bin/od"
  44.137 +	ln -s /bin/busybox "$1/usr/bin/split"
  44.138 +	ln -s /bin/busybox "$1/usr/bin/users"
  44.139  }
  44.140 -
  44.141 -clean_wok()
  44.142 -{
  44.143 -	rm -rf $WOK/$PACKAGE-*/taz
  44.144 -	rm -rf $WOK/$PACKAGE-*/process.log
  44.145 -}
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/coreutils/stuff/coreutils-8.25-i18n-2.patch	Wed Jun 15 17:23:11 2016 +0300
    45.3 @@ -0,0 +1,4790 @@
    45.4 +Submitted by:            DJ Lucas (dj_AT_linuxfromscratch_DOT_org)
    45.5 +Date:                    2016-02-09
    45.6 +Initial Package Version: 8.25
    45.7 +Upstream Status:         Rejected
    45.8 +Origin:                  Based on Suse's i18n patches at https://build.opensuse.org/package/view_file/Base:System/coreutils/coreutils-i18n.patch
    45.9 +Description:             Fixes several i18n issues with various Coreutils programs
   45.10 +
   45.11 +diff -Naurp coreutils-8.25-orig/lib/linebuffer.h coreutils-8.25/lib/linebuffer.h
   45.12 +--- coreutils-8.25-orig/lib/linebuffer.h	2016-01-01 07:45:55.000000000 -0600
   45.13 ++++ coreutils-8.25/lib/linebuffer.h	2016-02-08 19:07:10.298944609 -0600
   45.14 +@@ -21,6 +21,11 @@
   45.15 + 
   45.16 + # include <stdio.h>
   45.17 + 
   45.18 ++/* Get mbstate_t.  */
   45.19 ++# if HAVE_WCHAR_H
   45.20 ++#  include <wchar.h>
   45.21 ++# endif
   45.22 ++
   45.23 + /* A 'struct linebuffer' holds a line of text. */
   45.24 + 
   45.25 + struct linebuffer
   45.26 +@@ -28,6 +33,9 @@ struct linebuffer
   45.27 +   size_t size;                  /* Allocated. */
   45.28 +   size_t length;                /* Used. */
   45.29 +   char *buffer;
   45.30 ++# if HAVE_WCHAR_H
   45.31 ++  mbstate_t state;
   45.32 ++# endif
   45.33 + };
   45.34 + 
   45.35 + /* Initialize linebuffer LINEBUFFER for use. */
   45.36 +diff -Naurp coreutils-8.25-orig/src/cut.c coreutils-8.25/src/cut.c
   45.37 +--- coreutils-8.25-orig/src/cut.c	2016-01-13 05:08:59.000000000 -0600
   45.38 ++++ coreutils-8.25/src/cut.c	2016-02-08 19:07:10.300944616 -0600
   45.39 +@@ -28,6 +28,11 @@
   45.40 + #include <assert.h>
   45.41 + #include <getopt.h>
   45.42 + #include <sys/types.h>
   45.43 ++
   45.44 ++/* Get mbstate_t, mbrtowc().  */
   45.45 ++#if HAVE_WCHAR_H
   45.46 ++# include <wchar.h>
   45.47 ++#endif
   45.48 + #include "system.h"
   45.49 + 
   45.50 + #include "error.h"
   45.51 +@@ -38,6 +43,18 @@
   45.52 + 
   45.53 + #include "set-fields.h"
   45.54 + 
   45.55 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
   45.56 ++   installation; work around this configuration error.        */
   45.57 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
   45.58 ++# undef MB_LEN_MAX
   45.59 ++# define MB_LEN_MAX 16
   45.60 ++#endif
   45.61 ++
   45.62 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
   45.63 ++#if HAVE_MBRTOWC && defined mbstate_t
   45.64 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
   45.65 ++#endif
   45.66 ++
   45.67 + /* The official name of this program (e.g., no 'g' prefix).  */
   45.68 + #define PROGRAM_NAME "cut"
   45.69 + 
   45.70 +@@ -54,6 +71,52 @@
   45.71 +     }									\
   45.72 +   while (0)
   45.73 + 
   45.74 ++/* Refill the buffer BUF to get a multibyte character. */
   45.75 ++#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM)                        \
   45.76 ++  do                                                                        \
   45.77 ++    {                                                                        \
   45.78 ++      if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM))        \
   45.79 ++        {                                                                \
   45.80 ++          memmove (BUF, BUFPOS, BUFLEN);                                \
   45.81 ++          BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \
   45.82 ++          BUFPOS = BUF;                                                        \
   45.83 ++        }                                                                \
   45.84 ++    }                                                                        \
   45.85 ++  while (0)
   45.86 ++
   45.87 ++/* Get wide character on BUFPOS. BUFPOS is not included after that.
   45.88 ++   If byte sequence is not valid as a character, CONVFAIL is true. Otherwise false. */
   45.89 ++#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \
   45.90 ++  do                                                                        \
   45.91 ++    {                                                                        \
   45.92 ++      mbstate_t state_bak;                                                \
   45.93 ++                                                                        \
   45.94 ++      if (BUFLEN < 1)                                                        \
   45.95 ++        {                                                                \
   45.96 ++          WC = WEOF;                                                        \
   45.97 ++          break;                                                        \
   45.98 ++        }                                                                \
   45.99 ++                                                                        \
  45.100 ++      /* Get a wide character. */                                        \
  45.101 ++      CONVFAIL = false;                                                        \
  45.102 ++      state_bak = STATE;                                                \
  45.103 ++      MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE);        \
  45.104 ++                                                                        \
  45.105 ++      switch (MBLENGTH)                                                        \
  45.106 ++        {                                                                \
  45.107 ++        case (size_t)-1:                                                \
  45.108 ++        case (size_t)-2:                                                \
  45.109 ++          CONVFAIL = true;                                                        \
  45.110 ++          STATE = state_bak;                                                \
  45.111 ++          /* Fall througn. */                                                \
  45.112 ++                                                                        \
  45.113 ++        case 0:                                                                \
  45.114 ++          MBLENGTH = 1;                                                        \
  45.115 ++          break;                                                        \
  45.116 ++        }                                                                \
  45.117 ++    }                                                                        \
  45.118 ++  while (0)
  45.119 ++
  45.120 + 
  45.121 + /* Pointer inside RP.  When checking if a byte or field is selected
  45.122 +    by a finite range, we check if it is between CURRENT_RP.LO
  45.123 +@@ -61,6 +124,9 @@
  45.124 +    CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */
  45.125 + static struct field_range_pair *current_rp;
  45.126 + 
  45.127 ++/* Length of the delimiter given as argument to -d.  */
  45.128 ++size_t delimlen;
  45.129 ++
  45.130 + /* This buffer is used to support the semantics of the -s option
  45.131 +    (or lack of same) when the specified field list includes (does
  45.132 +    not include) the first field.  In both of those cases, the entire
  45.133 +@@ -77,15 +143,25 @@ enum operating_mode
  45.134 +   {
  45.135 +     undefined_mode,
  45.136 + 
  45.137 +-    /* Output characters that are in the given bytes. */
  45.138 ++    /* Output bytes that are at the given positions. */
  45.139 +     byte_mode,
  45.140 + 
  45.141 ++    /* Output characters that are at the given positions. */
  45.142 ++    character_mode,
  45.143 ++
  45.144 +     /* Output the given delimiter-separated fields. */
  45.145 +     field_mode
  45.146 +   };
  45.147 + 
  45.148 + static enum operating_mode operating_mode;
  45.149 + 
  45.150 ++/* If nonzero, when in byte mode, don't split multibyte characters.  */
  45.151 ++static int byte_mode_character_aware;
  45.152 ++
  45.153 ++/* If nonzero, the function for single byte locale is work
  45.154 ++   if this program runs on multibyte locale. */
  45.155 ++static int force_singlebyte_mode;
  45.156 ++
  45.157 + /* If true do not output lines containing no delimiter characters.
  45.158 +    Otherwise, all such lines are printed.  This option is valid only
  45.159 +    with field mode.  */
  45.160 +@@ -97,6 +173,9 @@ static bool complement;
  45.161 + 
  45.162 + /* The delimiter character for field mode. */
  45.163 + static unsigned char delim;
  45.164 ++#if HAVE_WCHAR_H
  45.165 ++static wchar_t wcdelim;
  45.166 ++#endif
  45.167 + 
  45.168 + /* The delimiter for each line/record. */
  45.169 + static unsigned char line_delim = '\n';
  45.170 +@@ -164,7 +243,7 @@ Print selected parts of lines from each
  45.171 +   -f, --fields=LIST       select only these fields;  also print any line\n\
  45.172 +                             that contains no delimiter character, unless\n\
  45.173 +                             the -s option is specified\n\
  45.174 +-  -n                      (ignored)\n\
  45.175 ++  -n                      with -b: don't split multibyte characters\n\
  45.176 + "), stdout);
  45.177 +       fputs (_("\
  45.178 +       --complement        complement the set of selected bytes, characters\n\
  45.179 +@@ -280,6 +359,82 @@ cut_bytes (FILE *stream)
  45.180 +     }
  45.181 + }
  45.182 + 
  45.183 ++#if HAVE_MBRTOWC
  45.184 ++/* This function is in use for the following case.
  45.185 ++
  45.186 ++   1. Read from the stream STREAM, printing to standard output any selected
  45.187 ++   characters.
  45.188 ++
  45.189 ++   2. Read from stream STREAM, printing to standard output any selected bytes,
  45.190 ++   without splitting multibyte characters.  */
  45.191 ++
  45.192 ++static void
  45.193 ++cut_characters_or_cut_bytes_no_split (FILE *stream)
  45.194 ++{
  45.195 ++  size_t idx;                /* number of bytes or characters in the line so far. */
  45.196 ++  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
  45.197 ++  char *bufpos;                /* Next read position of BUF. */
  45.198 ++  size_t buflen;        /* The length of the byte sequence in buf. */
  45.199 ++  wint_t wc;                /* A gotten wide character. */
  45.200 ++  size_t mblength;        /* The byte size of a multibyte character which shows
  45.201 ++                           as same character as WC. */
  45.202 ++  mbstate_t state;        /* State of the stream. */
  45.203 ++  bool convfail = false;  /* true, when conversion failed. Otherwise false. */
  45.204 ++  /* Whether to begin printing delimiters between ranges for the current line.
  45.205 ++     Set after we've begun printing data corresponding to the first range.  */
  45.206 ++  bool print_delimiter = false;
  45.207 ++
  45.208 ++  idx = 0;
  45.209 ++  buflen = 0;
  45.210 ++  bufpos = buf;
  45.211 ++  memset (&state, '\0', sizeof(mbstate_t));
  45.212 ++
  45.213 ++  current_rp = frp;
  45.214 ++
  45.215 ++  while (1)
  45.216 ++    {
  45.217 ++      REFILL_BUFFER (buf, bufpos, buflen, stream);
  45.218 ++
  45.219 ++      GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail);
  45.220 ++      (void) convfail;  /* ignore unused */
  45.221 ++
  45.222 ++      if (wc == WEOF)
  45.223 ++        {
  45.224 ++          if (idx > 0)
  45.225 ++            putchar (line_delim);
  45.226 ++          break;
  45.227 ++        }
  45.228 ++      else if (wc == line_delim)
  45.229 ++        {
  45.230 ++          putchar (line_delim);
  45.231 ++          idx = 0;
  45.232 ++          print_delimiter = false;
  45.233 ++          current_rp = frp;
  45.234 ++        }
  45.235 ++      else
  45.236 ++        {
  45.237 ++          next_item (&idx);
  45.238 ++          if (print_kth (idx))
  45.239 ++            {
  45.240 ++              if (output_delimiter_specified)
  45.241 ++                {
  45.242 ++                  if (print_delimiter && is_range_start_index (idx))
  45.243 ++                    {
  45.244 ++                      fwrite (output_delimiter_string, sizeof (char),
  45.245 ++                              output_delimiter_length, stdout);
  45.246 ++                    }
  45.247 ++                  print_delimiter = true;
  45.248 ++                }
  45.249 ++              fwrite (bufpos, mblength, sizeof(char), stdout);
  45.250 ++            }
  45.251 ++        }
  45.252 ++
  45.253 ++      buflen -= mblength;
  45.254 ++      bufpos += mblength;
  45.255 ++    }
  45.256 ++}
  45.257 ++#endif
  45.258 ++
  45.259 + /* Read from stream STREAM, printing to standard output any selected fields.  */
  45.260 + 
  45.261 + static void
  45.262 +@@ -425,13 +580,211 @@ cut_fields (FILE *stream)
  45.263 +     }
  45.264 + }
  45.265 + 
  45.266 ++#if HAVE_MBRTOWC
  45.267 ++static void
  45.268 ++cut_fields_mb (FILE *stream)
  45.269 ++{
  45.270 ++  int c;
  45.271 ++  size_t field_idx;
  45.272 ++  int found_any_selected_field;
  45.273 ++  int buffer_first_field;
  45.274 ++  int empty_input;
  45.275 ++  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
  45.276 ++  char *bufpos;                /* Next read position of BUF. */
  45.277 ++  size_t buflen;        /* The length of the byte sequence in buf. */
  45.278 ++  wint_t wc = 0;        /* A gotten wide character. */
  45.279 ++  size_t mblength;        /* The byte size of a multibyte character which shows
  45.280 ++                           as same character as WC. */
  45.281 ++  mbstate_t state;        /* State of the stream. */
  45.282 ++  bool convfail = false;  /* true, when conversion failed. Otherwise false. */
  45.283 ++
  45.284 ++  current_rp = frp;
  45.285 ++
  45.286 ++  found_any_selected_field = 0;
  45.287 ++  field_idx = 1;
  45.288 ++  bufpos = buf;
  45.289 ++  buflen = 0;
  45.290 ++  memset (&state, '\0', sizeof(mbstate_t));
  45.291 ++
  45.292 ++  c = getc (stream);
  45.293 ++  empty_input = (c == EOF);
  45.294 ++  if (c != EOF)
  45.295 ++  {
  45.296 ++    ungetc (c, stream);
  45.297 ++    wc = 0;
  45.298 ++  }
  45.299 ++  else
  45.300 ++    wc = WEOF;
  45.301 ++
  45.302 ++  /* To support the semantics of the -s flag, we may have to buffer
  45.303 ++     all of the first field to determine whether it is `delimited.'
  45.304 ++     But that is unnecessary if all non-delimited lines must be printed
  45.305 ++     and the first field has been selected, or if non-delimited lines
  45.306 ++     must be suppressed and the first field has *not* been selected.
  45.307 ++     That is because a non-delimited line has exactly one field.  */
  45.308 ++  buffer_first_field = (suppress_non_delimited ^ !print_kth (1));
  45.309 ++
  45.310 ++  while (1)
  45.311 ++    {
  45.312 ++      if (field_idx == 1 && buffer_first_field)
  45.313 ++        {
  45.314 ++          int len = 0;
  45.315 ++
  45.316 ++          while (1)
  45.317 ++            {
  45.318 ++              REFILL_BUFFER (buf, bufpos, buflen, stream);
  45.319 ++
  45.320 ++              GET_NEXT_WC_FROM_BUFFER
  45.321 ++                (wc, bufpos, buflen, mblength, state, convfail);
  45.322 ++
  45.323 ++              if (wc == WEOF)
  45.324 ++                break;
  45.325 ++
  45.326 ++              field_1_buffer = xrealloc (field_1_buffer, len + mblength);
  45.327 ++              memcpy (field_1_buffer + len, bufpos, mblength);
  45.328 ++              len += mblength;
  45.329 ++              buflen -= mblength;
  45.330 ++              bufpos += mblength;
  45.331 ++
  45.332 ++              if (!convfail && (wc == line_delim || wc == wcdelim))
  45.333 ++                break;
  45.334 ++            }
  45.335 ++
  45.336 ++          if (len <= 0 && wc == WEOF)
  45.337 ++            break;
  45.338 ++
  45.339 ++          /* If the first field extends to the end of line (it is not
  45.340 ++             delimited) and we are printing all non-delimited lines,
  45.341 ++             print this one.  */
  45.342 ++          if (convfail || (!convfail && wc != wcdelim))
  45.343 ++            {
  45.344 ++              if (suppress_non_delimited)
  45.345 ++                {
  45.346 ++                  /* Empty.        */
  45.347 ++                }
  45.348 ++              else
  45.349 ++                {
  45.350 ++                  fwrite (field_1_buffer, sizeof (char), len, stdout);
  45.351 ++                  /* Make sure the output line is newline terminated.  */
  45.352 ++                  if (convfail || (!convfail && wc != line_delim))
  45.353 ++                    putchar (line_delim);
  45.354 ++                }
  45.355 ++              continue;
  45.356 ++            }
  45.357 ++
  45.358 ++          if (print_kth (1))
  45.359 ++            {
  45.360 ++              /* Print the field, but not the trailing delimiter.  */
  45.361 ++              fwrite (field_1_buffer, sizeof (char), len - 1, stdout);
  45.362 ++              found_any_selected_field = 1;
  45.363 ++            }
  45.364 ++          next_item (&field_idx);
  45.365 ++        }
  45.366 ++
  45.367 ++      if (wc != WEOF)
  45.368 ++        {
  45.369 ++          if (print_kth (field_idx))
  45.370 ++            {
  45.371 ++              if (found_any_selected_field)
  45.372 ++                {
  45.373 ++                  fwrite (output_delimiter_string, sizeof (char),
  45.374 ++                          output_delimiter_length, stdout);
  45.375 ++                }
  45.376 ++              found_any_selected_field = 1;
  45.377 ++            }
  45.378 ++
  45.379 ++          while (1)
  45.380 ++            {
  45.381 ++              REFILL_BUFFER (buf, bufpos, buflen, stream);
  45.382 ++
  45.383 ++              GET_NEXT_WC_FROM_BUFFER
  45.384 ++                (wc, bufpos, buflen, mblength, state, convfail);
  45.385 ++
  45.386 ++              if (wc == WEOF)
  45.387 ++                break;
  45.388 ++              else if (!convfail && (wc == wcdelim || wc == line_delim))
  45.389 ++                {
  45.390 ++                  buflen -= mblength;
  45.391 ++                  bufpos += mblength;
  45.392 ++                  break;
  45.393 ++                }
  45.394 ++
  45.395 ++              if (print_kth (field_idx))
  45.396 ++                fwrite (bufpos, mblength, sizeof(char), stdout);
  45.397 ++
  45.398 ++              buflen -= mblength;
  45.399 ++              bufpos += mblength;
  45.400 ++            }
  45.401 ++        }
  45.402 ++
  45.403 ++      if ((!convfail || wc == line_delim) && buflen < 1)
  45.404 ++        wc = WEOF;
  45.405 ++
  45.406 ++      if (!convfail && wc == wcdelim)
  45.407 ++        next_item (&field_idx);
  45.408 ++      else if (wc == WEOF || (!convfail && wc == line_delim))
  45.409 ++        {
  45.410 ++          if (found_any_selected_field
  45.411 ++              || (!empty_input && !(suppress_non_delimited && field_idx == 1)))
  45.412 ++            putchar (line_delim);
  45.413 ++          if (wc == WEOF)
  45.414 ++            break;
  45.415 ++          field_idx = 1;
  45.416 ++          current_rp = frp;
  45.417 ++          found_any_selected_field = 0;
  45.418 ++        }
  45.419 ++    }
  45.420 ++}
  45.421 ++#endif
  45.422 ++
  45.423 + static void
  45.424 + cut_stream (FILE *stream)
  45.425 + {
  45.426 +-  if (operating_mode == byte_mode)
  45.427 +-    cut_bytes (stream);
  45.428 ++#if HAVE_MBRTOWC
  45.429 ++  if (MB_CUR_MAX > 1 && !force_singlebyte_mode)
  45.430 ++    {
  45.431 ++      switch (operating_mode)
  45.432 ++        {
  45.433 ++        case byte_mode:
  45.434 ++          if (byte_mode_character_aware)
  45.435 ++            cut_characters_or_cut_bytes_no_split (stream);
  45.436 ++          else
  45.437 ++            cut_bytes (stream);
  45.438 ++          break;
  45.439 ++
  45.440 ++        case character_mode:
  45.441 ++          cut_characters_or_cut_bytes_no_split (stream);
  45.442 ++          break;
  45.443 ++
  45.444 ++        case field_mode:
  45.445 ++          if (delimlen == 1)
  45.446 ++            {
  45.447 ++              /* Check if we have utf8 multibyte locale, so we can use this
  45.448 ++                 optimization because of uniqueness of characters, which is
  45.449 ++                 not true for e.g. SJIS */
  45.450 ++              char * loc = setlocale(LC_CTYPE, NULL);
  45.451 ++              if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") ||
  45.452 ++                  strstr (loc, "UTF8") || strstr (loc, "utf8")))
  45.453 ++                {
  45.454 ++                  cut_fields (stream);
  45.455 ++                  break;
  45.456 ++                }
  45.457 ++            }
  45.458 ++          cut_fields_mb (stream);
  45.459 ++          break;
  45.460 ++
  45.461 ++        default:
  45.462 ++          abort ();
  45.463 ++        }
  45.464 ++    }
  45.465 +   else
  45.466 +-    cut_fields (stream);
  45.467 ++#endif
  45.468 ++    {
  45.469 ++      if (operating_mode == field_mode)
  45.470 ++        cut_fields (stream);
  45.471 ++      else
  45.472 ++        cut_bytes (stream);
  45.473 ++    }
  45.474 + }
  45.475 + 
  45.476 + /* Process file FILE to standard output.
  45.477 +@@ -483,6 +836,7 @@ main (int argc, char **argv)
  45.478 +   bool ok;
  45.479 +   bool delim_specified = false;
  45.480 +   char *spec_list_string IF_LINT ( = NULL);
  45.481 ++  char mbdelim[MB_LEN_MAX + 1];
  45.482 + 
  45.483 +   initialize_main (&argc, &argv);
  45.484 +   set_program_name (argv[0]);
  45.485 +@@ -505,7 +859,6 @@ main (int argc, char **argv)
  45.486 +       switch (optc)
  45.487 +         {
  45.488 +         case 'b':
  45.489 +-        case 'c':
  45.490 +           /* Build the byte list. */
  45.491 +           if (operating_mode != undefined_mode)
  45.492 +             FATAL_ERROR (_("only one type of list may be specified"));
  45.493 +@@ -513,6 +866,14 @@ main (int argc, char **argv)
  45.494 +           spec_list_string = optarg;
  45.495 +           break;
  45.496 + 
  45.497 ++        case 'c':
  45.498 ++          /* Build the character list. */
  45.499 ++          if (operating_mode != undefined_mode)
  45.500 ++            FATAL_ERROR (_("only one type of list may be specified"));
  45.501 ++          operating_mode = character_mode;
  45.502 ++          spec_list_string = optarg;
  45.503 ++          break;
  45.504 ++
  45.505 +         case 'f':
  45.506 +           /* Build the field list. */
  45.507 +           if (operating_mode != undefined_mode)
  45.508 +@@ -524,10 +885,38 @@ main (int argc, char **argv)
  45.509 +         case 'd':
  45.510 +           /* New delimiter. */
  45.511 +           /* Interpret -d '' to mean 'use the NUL byte as the delimiter.'  */
  45.512 +-          if (optarg[0] != '\0' && optarg[1] != '\0')
  45.513 +-            FATAL_ERROR (_("the delimiter must be a single character"));
  45.514 +-          delim = optarg[0];
  45.515 +-          delim_specified = true;
  45.516 ++            {
  45.517 ++#if HAVE_MBRTOWC
  45.518 ++              if(MB_CUR_MAX > 1)
  45.519 ++                {
  45.520 ++                  mbstate_t state;
  45.521 ++
  45.522 ++                  memset (&state, '\0', sizeof(mbstate_t));
  45.523 ++                  delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state);
  45.524 ++
  45.525 ++                  if (delimlen == (size_t)-1 || delimlen == (size_t)-2)
  45.526 ++                    ++force_singlebyte_mode;
  45.527 ++                  else
  45.528 ++                    {
  45.529 ++                      delimlen = (delimlen < 1) ? 1 : delimlen;
  45.530 ++                      if (wcdelim != L'\0' && *(optarg + delimlen) != '\0')
  45.531 ++                        FATAL_ERROR (_("the delimiter must be a single character"));
  45.532 ++                      memcpy (mbdelim, optarg, delimlen);
  45.533 ++                      mbdelim[delimlen] = '\0';
  45.534 ++                      if (delimlen == 1)
  45.535 ++                        delim = *optarg;
  45.536 ++                    }
  45.537 ++                }
  45.538 ++
  45.539 ++              if (MB_CUR_MAX <= 1 || force_singlebyte_mode)
  45.540 ++#endif
  45.541 ++                {
  45.542 ++                  if (optarg[0] != '\0' && optarg[1] != '\0')
  45.543 ++                    FATAL_ERROR (_("the delimiter must be a single character"));
  45.544 ++                  delim = (unsigned char) optarg[0];
  45.545 ++                }
  45.546 ++            delim_specified = true;
  45.547 ++          }
  45.548 +           break;
  45.549 + 
  45.550 +         case OUTPUT_DELIMITER_OPTION:
  45.551 +@@ -540,6 +929,7 @@ main (int argc, char **argv)
  45.552 +           break;
  45.553 + 
  45.554 +         case 'n':
  45.555 ++          byte_mode_character_aware = 1;
  45.556 +           break;
  45.557 + 
  45.558 +         case 's':
  45.559 +@@ -579,15 +969,34 @@ main (int argc, char **argv)
  45.560 +               | (complement ? SETFLD_COMPLEMENT : 0) );
  45.561 + 
  45.562 +   if (!delim_specified)
  45.563 +-    delim = '\t';
  45.564 ++    {
  45.565 ++      delim = '\t';
  45.566 ++#ifdef HAVE_MBRTOWC
  45.567 ++      wcdelim = L'\t';
  45.568 ++      mbdelim[0] = '\t';
  45.569 ++      mbdelim[1] = '\0';
  45.570 ++      delimlen = 1;
  45.571 ++#endif
  45.572 ++    }
  45.573 + 
  45.574 +   if (output_delimiter_string == NULL)
  45.575 +     {
  45.576 +-      static char dummy[2];
  45.577 +-      dummy[0] = delim;
  45.578 +-      dummy[1] = '\0';
  45.579 +-      output_delimiter_string = dummy;
  45.580 +-      output_delimiter_length = 1;
  45.581 ++#ifdef HAVE_MBRTOWC
  45.582 ++      if (MB_CUR_MAX > 1 && !force_singlebyte_mode)
  45.583 ++        {
  45.584 ++          output_delimiter_string = xstrdup(mbdelim);
  45.585 ++          output_delimiter_length = delimlen;
  45.586 ++        }
  45.587 ++
  45.588 ++      if (MB_CUR_MAX <= 1 || force_singlebyte_mode)
  45.589 ++#endif
  45.590 ++        {
  45.591 ++          static char dummy[2];
  45.592 ++          dummy[0] = delim;
  45.593 ++          dummy[1] = '\0';
  45.594 ++          output_delimiter_string = dummy;
  45.595 ++          output_delimiter_length = 1;
  45.596 ++        }
  45.597 +     }
  45.598 + 
  45.599 +   if (optind == argc)
  45.600 +diff -Naurp coreutils-8.25-orig/src/expand.c coreutils-8.25/src/expand.c
  45.601 +--- coreutils-8.25-orig/src/expand.c	2016-01-01 07:48:50.000000000 -0600
  45.602 ++++ coreutils-8.25/src/expand.c	2016-02-08 19:07:10.301944619 -0600
  45.603 +@@ -37,12 +37,34 @@
  45.604 + #include <stdio.h>
  45.605 + #include <getopt.h>
  45.606 + #include <sys/types.h>
  45.607 ++
  45.608 ++/* Get mbstate_t, mbrtowc(), wcwidth(). */
  45.609 ++#if HAVE_WCHAR_H
  45.610 ++# include <wchar.h>
  45.611 ++#endif
  45.612 ++
  45.613 ++/* Get iswblank(). */
  45.614 ++#if HAVE_WCTYPE_H
  45.615 ++# include <wctype.h>
  45.616 ++#endif
  45.617 ++
  45.618 + #include "system.h"
  45.619 + #include "error.h"
  45.620 + #include "fadvise.h"
  45.621 + #include "quote.h"
  45.622 + #include "xstrndup.h"
  45.623 + 
  45.624 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
  45.625 ++   installation; work around this configuration error.  */
  45.626 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
  45.627 ++# define MB_LEN_MAX 16
  45.628 ++#endif
  45.629 ++
  45.630 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
  45.631 ++#if HAVE_MBRTOWC && defined mbstate_t
  45.632 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
  45.633 ++#endif
  45.634 ++
  45.635 + /* The official name of this program (e.g., no 'g' prefix).  */
  45.636 + #define PROGRAM_NAME "expand"
  45.637 + 
  45.638 +@@ -357,6 +379,142 @@ expand (void)
  45.639 +     }
  45.640 + }
  45.641 + 
  45.642 ++#if HAVE_MBRTOWC
  45.643 ++static void
  45.644 ++expand_multibyte (void)
  45.645 ++{
  45.646 ++  FILE *fp;			/* Input strem. */
  45.647 ++  mbstate_t i_state;		/* Current shift state of the input stream. */
  45.648 ++  mbstate_t i_state_bak;	/* Back up the I_STATE. */
  45.649 ++  mbstate_t o_state;		/* Current shift state of the output stream. */
  45.650 ++  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
  45.651 ++  char *bufpos = buf;			/* Next read position of BUF. */
  45.652 ++  size_t buflen = 0;		/* The length of the byte sequence in buf. */
  45.653 ++  wchar_t wc;			/* A gotten wide character. */
  45.654 ++  size_t mblength;		/* The byte size of a multibyte character
  45.655 ++				   which shows as same character as WC. */
  45.656 ++  int tab_index = 0;		/* Index in `tab_list' of next tabstop. */
  45.657 ++  int column = 0;		/* Column on screen of the next char. */
  45.658 ++  int next_tab_column;		/* Column the next tab stop is on. */
  45.659 ++  int convert = 1;		/* If nonzero, perform translations. */
  45.660 ++
  45.661 ++  fp = next_file ((FILE *) NULL);
  45.662 ++  if (fp == NULL)
  45.663 ++    return;
  45.664 ++
  45.665 ++  memset (&o_state, '\0', sizeof(mbstate_t));
  45.666 ++  memset (&i_state, '\0', sizeof(mbstate_t));
  45.667 ++
  45.668 ++  for (;;)
  45.669 ++    {
  45.670 ++      /* Refill the buffer BUF. */
  45.671 ++      if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp))
  45.672 ++	{
  45.673 ++	  memmove (buf, bufpos, buflen);
  45.674 ++	  buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp);
  45.675 ++	  bufpos = buf;
  45.676 ++	}
  45.677 ++
  45.678 ++      /* No character is left in BUF. */
  45.679 ++      if (buflen < 1)
  45.680 ++	{
  45.681 ++	  fp = next_file (fp);
  45.682 ++
  45.683 ++	  if (fp == NULL)
  45.684 ++	    break;		/* No more files. */
  45.685 ++	  else
  45.686 ++	    {
  45.687 ++	      memset (&i_state, '\0', sizeof(mbstate_t));
  45.688 ++	      continue;
  45.689 ++	    }
  45.690 ++	}
  45.691 ++
  45.692 ++      /* Get a wide character. */
  45.693 ++      i_state_bak = i_state;
  45.694 ++      mblength = mbrtowc (&wc, bufpos, buflen, &i_state);
  45.695 ++
  45.696 ++      switch (mblength)
  45.697 ++	{
  45.698 ++	case (size_t)-1:	/* illegal byte sequence. */
  45.699 ++	case (size_t)-2:
  45.700 ++	  mblength = 1;
  45.701 ++	  i_state = i_state_bak;
  45.702 ++	  if (convert)
  45.703 ++	    {
  45.704 ++	      ++column;
  45.705 ++	      if (convert_entire_line == 0 && !isblank(*bufpos))
  45.706 ++		convert = 0;
  45.707 ++	    }
  45.708 ++	  putchar (*bufpos);
  45.709 ++	  break;
  45.710 ++
  45.711 ++	case 0:		/* null. */
  45.712 ++	  mblength = 1;
  45.713 ++	  if (convert && convert_entire_line == 0)
  45.714 ++	    convert = 0;
  45.715 ++	  putchar ('\0');
  45.716 ++	  break;
  45.717 ++
  45.718 ++	default:
  45.719 ++	  if (wc == L'\n')   /* LF. */
  45.720 ++	    {
  45.721 ++	      tab_index = 0;
  45.722 ++	      column = 0;
  45.723 ++	      convert = 1;
  45.724 ++	      putchar ('\n');
  45.725 ++	    }
  45.726 ++	  else if (wc == L'\t' && convert)	/* Tab. */
  45.727 ++	    {
  45.728 ++	      if (tab_size == 0)
  45.729 ++		{
  45.730 ++		  /* Do not let tab_index == first_free_tab;
  45.731 ++		     stop when it is 1 less. */
  45.732 ++		  while (tab_index < first_free_tab - 1
  45.733 ++		      && column >= tab_list[tab_index])
  45.734 ++		    tab_index++;
  45.735 ++		  next_tab_column = tab_list[tab_index];
  45.736 ++		  if (tab_index < first_free_tab - 1)
  45.737 ++		    tab_index++;
  45.738 ++		  if (column >= next_tab_column)
  45.739 ++		    next_tab_column = column + 1;
  45.740 ++		}
  45.741 ++	      else
  45.742 ++		next_tab_column = column + tab_size - column % tab_size;
  45.743 ++
  45.744 ++	      while (column < next_tab_column)
  45.745 ++		{
  45.746 ++		  putchar (' ');
  45.747 ++		  ++column;
  45.748 ++		}
  45.749 ++	    }
  45.750 ++	  else  /* Others. */
  45.751 ++	    {
  45.752 ++	      if (convert)
  45.753 ++		{
  45.754 ++		  if (wc == L'\b')
  45.755 ++		    {
  45.756 ++		      if (column > 0)
  45.757 ++			--column;
  45.758 ++		    }
  45.759 ++		  else
  45.760 ++		    {
  45.761 ++		      int width;		/* The width of WC. */
  45.762 ++
  45.763 ++		      width = wcwidth (wc);
  45.764 ++		      column += (width > 0) ? width : 0;
  45.765 ++		      if (convert_entire_line == 0 && !iswblank(wc))
  45.766 ++			convert = 0;
  45.767 ++		    }
  45.768 ++		}
  45.769 ++	      fwrite (bufpos, sizeof(char), mblength, stdout);
  45.770 ++	    }
  45.771 ++	}
  45.772 ++      buflen -= mblength;
  45.773 ++      bufpos += mblength;
  45.774 ++    }
  45.775 ++}
  45.776 ++#endif
  45.777 ++
  45.778 + int
  45.779 + main (int argc, char **argv)
  45.780 + {
  45.781 +@@ -421,7 +579,12 @@ main (int argc, char **argv)
  45.782 + 
  45.783 +   file_list = (optind < argc ? &argv[optind] : stdin_argv);
  45.784 + 
  45.785 +-  expand ();
  45.786 ++#if HAVE_MBRTOWC
  45.787 ++  if (MB_CUR_MAX > 1)
  45.788 ++    expand_multibyte ();
  45.789 ++  else
  45.790 ++#endif
  45.791 ++    expand ();
  45.792 + 
  45.793 +   if (have_read_stdin && fclose (stdin) != 0)
  45.794 +     error (EXIT_FAILURE, errno, "-");
  45.795 +diff -Naurp coreutils-8.25-orig/src/fold.c coreutils-8.25/src/fold.c
  45.796 +--- coreutils-8.25-orig/src/fold.c	2016-01-01 07:48:50.000000000 -0600
  45.797 ++++ coreutils-8.25/src/fold.c	2016-02-08 19:07:10.302944622 -0600
  45.798 +@@ -22,11 +22,33 @@
  45.799 + #include <getopt.h>
  45.800 + #include <sys/types.h>
  45.801 + 
  45.802 ++/* Get mbstate_t, mbrtowc(), wcwidth().  */
  45.803 ++#if HAVE_WCHAR_H
  45.804 ++# include <wchar.h>
  45.805 ++#endif
  45.806 ++
  45.807 ++/* Get iswprint(), iswblank(), wcwidth().  */
  45.808 ++#if HAVE_WCTYPE_H
  45.809 ++# include <wctype.h>
  45.810 ++#endif
  45.811 ++
  45.812 + #include "system.h"
  45.813 + #include "error.h"
  45.814 + #include "fadvise.h"
  45.815 + #include "xdectoint.h"
  45.816 + 
  45.817 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
  45.818 ++      installation; work around this configuration error.  */
  45.819 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
  45.820 ++# undef MB_LEN_MAX
  45.821 ++# define MB_LEN_MAX 16
  45.822 ++#endif
  45.823 ++
  45.824 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
  45.825 ++#if HAVE_MBRTOWC && defined mbstate_t
  45.826 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
  45.827 ++#endif
  45.828 ++
  45.829 + #define TAB_WIDTH 8
  45.830 + 
  45.831 + /* The official name of this program (e.g., no 'g' prefix).  */
  45.832 +@@ -34,20 +56,41 @@
  45.833 + 
  45.834 + #define AUTHORS proper_name ("David MacKenzie")
  45.835 + 
  45.836 ++#define FATAL_ERROR(Message)                                            \
  45.837 ++  do                                                                    \
  45.838 ++    {                                                                   \
  45.839 ++      error (0, 0, (Message));                                          \
  45.840 ++      usage (2);                                                        \
  45.841 ++    }                                                                   \
  45.842 ++  while (0)
  45.843 ++
  45.844 ++enum operating_mode
  45.845 ++{
  45.846 ++  /* Fold texts by columns that are at the given positions. */
  45.847 ++  column_mode,
  45.848 ++
  45.849 ++  /* Fold texts by bytes that are at the given positions. */
  45.850 ++  byte_mode,
  45.851 ++
  45.852 ++  /* Fold texts by characters that are at the given positions. */
  45.853 ++  character_mode,
  45.854 ++};
  45.855 ++
  45.856 ++/* The argument shows current mode. (Default: column_mode) */
  45.857 ++static enum operating_mode operating_mode;
  45.858 ++
  45.859 + /* If nonzero, try to break on whitespace. */
  45.860 + static bool break_spaces;
  45.861 + 
  45.862 +-/* If nonzero, count bytes, not column positions. */
  45.863 +-static bool count_bytes;
  45.864 +-
  45.865 + /* If nonzero, at least one of the files we read was standard input. */
  45.866 + static bool have_read_stdin;
  45.867 + 
  45.868 +-static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::";
  45.869 ++static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::";
  45.870 + 
  45.871 + static struct option const longopts[] =
  45.872 + {
  45.873 +   {"bytes", no_argument, NULL, 'b'},
  45.874 ++  {"characters", no_argument, NULL, 'c'},
  45.875 +   {"spaces", no_argument, NULL, 's'},
  45.876 +   {"width", required_argument, NULL, 'w'},
  45.877 +   {GETOPT_HELP_OPTION_DECL},
  45.878 +@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing t
  45.879 + 
  45.880 +       fputs (_("\
  45.881 +   -b, --bytes         count bytes rather than columns\n\
  45.882 ++  -c, --characters    count characters rather than columns\n\
  45.883 +   -s, --spaces        break at spaces\n\
  45.884 +   -w, --width=WIDTH   use WIDTH columns instead of 80\n\
  45.885 + "), stdout);
  45.886 +@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing t
  45.887 + static size_t
  45.888 + adjust_column (size_t column, char c)
  45.889 + {
  45.890 +-  if (!count_bytes)
  45.891 ++  if (operating_mode != byte_mode)
  45.892 +     {
  45.893 +       if (c == '\b')
  45.894 +         {
  45.895 +@@ -115,30 +159,14 @@ adjust_column (size_t column, char c)
  45.896 +    to stdout, with maximum line length WIDTH.
  45.897 +    Return true if successful.  */
  45.898 + 
  45.899 +-static bool
  45.900 +-fold_file (char const *filename, size_t width)
  45.901 ++static void
  45.902 ++fold_text (FILE *istream, size_t width, int *saved_errno)
  45.903 + {
  45.904 +-  FILE *istream;
  45.905 +   int c;
  45.906 +   size_t column = 0;		/* Screen column where next char will go. */
  45.907 +   size_t offset_out = 0;	/* Index in 'line_out' for next char. */
  45.908 +   static char *line_out = NULL;
  45.909 +   static size_t allocated_out = 0;
  45.910 +-  int saved_errno;
  45.911 +-
  45.912 +-  if (STREQ (filename, "-"))
  45.913 +-    {
  45.914 +-      istream = stdin;
  45.915 +-      have_read_stdin = true;
  45.916 +-    }
  45.917 +-  else
  45.918 +-    istream = fopen (filename, "r");
  45.919 +-
  45.920 +-  if (istream == NULL)
  45.921 +-    {
  45.922 +-      error (0, errno, "%s", quotef (filename));
  45.923 +-      return false;
  45.924 +-    }
  45.925 + 
  45.926 +   fadvise (istream, FADVISE_SEQUENTIAL);
  45.927 + 
  45.928 +@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t
  45.929 +               bool found_blank = false;
  45.930 +               size_t logical_end = offset_out;
  45.931 + 
  45.932 ++              /* If LINE_OUT has no wide character,
  45.933 ++                 put a new wide character in LINE_OUT
  45.934 ++                 if column is bigger than width. */
  45.935 ++              if (offset_out == 0)
  45.936 ++                {
  45.937 ++                  line_out[offset_out++] = c;
  45.938 ++                  continue;
  45.939 ++                }
  45.940 ++
  45.941 +               /* Look for the last blank. */
  45.942 +               while (logical_end)
  45.943 +                 {
  45.944 +@@ -214,11 +251,221 @@ fold_file (char const *filename, size_t
  45.945 +       line_out[offset_out++] = c;
  45.946 +     }
  45.947 + 
  45.948 +-  saved_errno = errno;
  45.949 ++  *saved_errno = errno;
  45.950 ++
  45.951 ++  if (offset_out)
  45.952 ++    fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
  45.953 ++
  45.954 ++}
  45.955 ++
  45.956 ++#if HAVE_MBRTOWC
  45.957 ++static void
  45.958 ++fold_multibyte_text (FILE *istream, size_t width, int *saved_errno)
  45.959 ++{
  45.960 ++  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
  45.961 ++  size_t buflen = 0;        /* The length of the byte sequence in buf. */
  45.962 ++  char *bufpos = buf;         /* Next read position of BUF. */
  45.963 ++  wint_t wc;                /* A gotten wide character. */
  45.964 ++  size_t mblength;        /* The byte size of a multibyte character which shows
  45.965 ++                           as same character as WC. */
  45.966 ++  mbstate_t state, state_bak;        /* State of the stream. */
  45.967 ++  int convfail = 0;                /* 1, when conversion is failed. Otherwise 0. */
  45.968 ++
  45.969 ++  static char *line_out = NULL;
  45.970 ++  size_t offset_out = 0;        /* Index in `line_out' for next char. */
  45.971 ++  static size_t allocated_out = 0;
  45.972 ++
  45.973 ++  int increment;
  45.974 ++  size_t column = 0;
  45.975 ++
  45.976 ++  size_t last_blank_pos;
  45.977 ++  size_t last_blank_column;
  45.978 ++  int is_blank_seen;
  45.979 ++  int last_blank_increment = 0;
  45.980 ++  int is_bs_following_last_blank;
  45.981 ++  size_t bs_following_last_blank_num;
  45.982 ++  int is_cr_after_last_blank;
  45.983 ++
  45.984 ++#define CLEAR_FLAGS                                \
  45.985 ++   do                                                \
  45.986 ++     {                                                \
  45.987 ++        last_blank_pos = 0;                        \
  45.988 ++        last_blank_column = 0;                        \
  45.989 ++        is_blank_seen = 0;                        \
  45.990 ++        is_bs_following_last_blank = 0;                \
  45.991 ++        bs_following_last_blank_num = 0;        \
  45.992 ++        is_cr_after_last_blank = 0;                \
  45.993 ++     }                                                \
  45.994 ++   while (0)
  45.995 ++
  45.996 ++#define START_NEW_LINE                        \
  45.997 ++   do                                        \
  45.998 ++     {                                        \
  45.999 ++      putchar ('\n');                        \
 45.1000 ++      column = 0;                        \
 45.1001 ++      offset_out = 0;                        \
 45.1002 ++      CLEAR_FLAGS;                        \
 45.1003 ++    }                                        \
 45.1004 ++   while (0)
 45.1005 ++
 45.1006 ++  CLEAR_FLAGS;
 45.1007 ++  memset (&state, '\0', sizeof(mbstate_t));
 45.1008 ++
 45.1009 ++  for (;; bufpos += mblength, buflen -= mblength)
 45.1010 ++    {
 45.1011 ++      if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream))
 45.1012 ++        {
 45.1013 ++          memmove (buf, bufpos, buflen);
 45.1014 ++          buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream);
 45.1015 ++          bufpos = buf;
 45.1016 ++        }
 45.1017 ++
 45.1018 ++      if (buflen < 1)
 45.1019 ++        break;
 45.1020 ++
 45.1021 ++      /* Get a wide character. */
 45.1022 ++      state_bak = state;
 45.1023 ++      mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state);
 45.1024 ++
 45.1025 ++      switch (mblength)
 45.1026 ++        {
 45.1027 ++        case (size_t)-1:
 45.1028 ++        case (size_t)-2:
 45.1029 ++          convfail++;
 45.1030 ++          state = state_bak;
 45.1031 ++          /* Fall through. */
 45.1032 ++
 45.1033 ++        case 0:
 45.1034 ++          mblength = 1;
 45.1035 ++          break;
 45.1036 ++        }
 45.1037 ++
 45.1038 ++rescan:
 45.1039 ++      if (operating_mode == byte_mode)                        /* byte mode */
 45.1040 ++        increment = mblength;
 45.1041 ++      else if (operating_mode == character_mode)        /* character mode */
 45.1042 ++        increment = 1;
 45.1043 ++      else                                                /* column mode */
 45.1044 ++        {
 45.1045 ++          if (convfail)
 45.1046 ++            increment = 1;
 45.1047 ++          else
 45.1048 ++            {
 45.1049 ++              switch (wc)
 45.1050 ++                {
 45.1051 ++                case L'\n':
 45.1052 ++                  fwrite (line_out, sizeof(char), offset_out, stdout);
 45.1053 ++                  START_NEW_LINE;
 45.1054 ++                  continue;
 45.1055 ++
 45.1056 ++                case L'\b':
 45.1057 ++                  increment = (column > 0) ? -1 : 0;
 45.1058 ++                  break;
 45.1059 ++
 45.1060 ++                case L'\r':
 45.1061 ++                  increment = -1 * column;
 45.1062 ++                  break;
 45.1063 ++
 45.1064 ++                case L'\t':
 45.1065 ++                  increment = 8 - column % 8;
 45.1066 ++                  break;
 45.1067 ++
 45.1068 ++                default:
 45.1069 ++                  increment = wcwidth (wc);
 45.1070 ++                  increment = (increment < 0) ? 0 : increment;
 45.1071 ++                }
 45.1072 ++            }
 45.1073 ++        }
 45.1074 ++
 45.1075 ++      if (column + increment > width && break_spaces && last_blank_pos)
 45.1076 ++        {
 45.1077 ++          fwrite (line_out, sizeof(char), last_blank_pos, stdout);
 45.1078 ++          putchar ('\n');
 45.1079 ++
 45.1080 ++          offset_out = offset_out - last_blank_pos;
 45.1081 ++          column = column - last_blank_column + ((is_cr_after_last_blank)
 45.1082 ++              ? last_blank_increment : bs_following_last_blank_num);
 45.1083 ++          memmove (line_out, line_out + last_blank_pos, offset_out);
 45.1084 ++          CLEAR_FLAGS;
 45.1085 ++          goto rescan;
 45.1086 ++        }
 45.1087 ++
 45.1088 ++      if (column + increment > width && column != 0)
 45.1089 ++        {
 45.1090 ++          fwrite (line_out, sizeof(char), offset_out, stdout);
 45.1091 ++          START_NEW_LINE;
 45.1092 ++          goto rescan;
 45.1093 ++        }
 45.1094 ++
 45.1095 ++      if (allocated_out < offset_out + mblength)
 45.1096 ++        {
 45.1097 ++          line_out = X2REALLOC (line_out, &allocated_out);
 45.1098 ++        }
 45.1099 ++
 45.1100 ++      memcpy (line_out + offset_out, bufpos, mblength);
 45.1101 ++      offset_out += mblength;
 45.1102 ++      column += increment;
 45.1103 ++
 45.1104 ++      if (is_blank_seen && !convfail && wc == L'\r')
 45.1105 ++        is_cr_after_last_blank = 1;
 45.1106 ++
 45.1107 ++      if (is_bs_following_last_blank && !convfail && wc == L'\b')
 45.1108 ++        ++bs_following_last_blank_num;
 45.1109 ++      else
 45.1110 ++        is_bs_following_last_blank = 0;
 45.1111 ++
 45.1112 ++      if (break_spaces && !convfail && iswblank (wc))
 45.1113 ++        {
 45.1114 ++          last_blank_pos = offset_out;
 45.1115 ++          last_blank_column = column;
 45.1116 ++          is_blank_seen = 1;
 45.1117 ++          last_blank_increment = increment;
 45.1118 ++          is_bs_following_last_blank = 1;
 45.1119 ++          bs_following_last_blank_num = 0;
 45.1120 ++          is_cr_after_last_blank = 0;
 45.1121 ++        }
 45.1122 ++    }
 45.1123 ++
 45.1124 ++  *saved_errno = errno;
 45.1125 + 
 45.1126 +   if (offset_out)
 45.1127 +     fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
 45.1128 + 
 45.1129 ++}
 45.1130 ++#endif
 45.1131 ++
 45.1132 ++/* Fold file FILENAME, or standard input if FILENAME is "-",
 45.1133 ++   to stdout, with maximum line length WIDTH.
 45.1134 ++   Return 0 if successful, 1 if an error occurs. */
 45.1135 ++
 45.1136 ++static bool
 45.1137 ++fold_file (char const *filename, size_t width)
 45.1138 ++{
 45.1139 ++  FILE *istream;
 45.1140 ++  int saved_errno;
 45.1141 ++
 45.1142 ++  if (STREQ (filename, "-"))
 45.1143 ++    {
 45.1144 ++      istream = stdin;
 45.1145 ++      have_read_stdin = 1;
 45.1146 ++    }
 45.1147 ++  else
 45.1148 ++    istream = fopen (filename, "r");
 45.1149 ++
 45.1150 ++  if (istream == NULL)
 45.1151 ++    {
 45.1152 ++      error (0, errno, "%s", quotef (filename));
 45.1153 ++      return 1;
 45.1154 ++    }
 45.1155 ++
 45.1156 ++  /* Define how ISTREAM is being folded. */
 45.1157 ++#if HAVE_MBRTOWC
 45.1158 ++  if (MB_CUR_MAX > 1)
 45.1159 ++    fold_multibyte_text (istream, width, &saved_errno);
 45.1160 ++  else
 45.1161 ++#endif
 45.1162 ++    fold_text (istream, width, &saved_errno);
 45.1163 ++
 45.1164 +   if (ferror (istream))
 45.1165 +     {
 45.1166 +       error (0, saved_errno, "%s", quotef (filename));
 45.1167 +@@ -251,7 +498,8 @@ main (int argc, char **argv)
 45.1168 + 
 45.1169 +   atexit (close_stdout);
 45.1170 + 
 45.1171 +-  break_spaces = count_bytes = have_read_stdin = false;
 45.1172 ++  operating_mode = column_mode;
 45.1173 ++  break_spaces = have_read_stdin = false;
 45.1174 + 
 45.1175 +   while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
 45.1176 +     {
 45.1177 +@@ -260,7 +508,15 @@ main (int argc, char **argv)
 45.1178 +       switch (optc)
 45.1179 +         {
 45.1180 +         case 'b':		/* Count bytes rather than columns. */
 45.1181 +-          count_bytes = true;
 45.1182 ++          if (operating_mode != column_mode)
 45.1183 ++            FATAL_ERROR (_("only one way of folding may be specified"));
 45.1184 ++          operating_mode = byte_mode;
 45.1185 ++          break;
 45.1186 ++
 45.1187 ++        case 'c':
 45.1188 ++          if (operating_mode != column_mode)
 45.1189 ++            FATAL_ERROR (_("only one way of folding may be specified"));
 45.1190 ++          operating_mode = character_mode;
 45.1191 +           break;
 45.1192 + 
 45.1193 +         case 's':		/* Break at word boundaries. */
 45.1194 +diff -Naurp coreutils-8.25-orig/src/join.c coreutils-8.25/src/join.c
 45.1195 +--- coreutils-8.25-orig/src/join.c	2016-01-13 05:08:59.000000000 -0600
 45.1196 ++++ coreutils-8.25/src/join.c	2016-02-08 19:07:10.303944625 -0600
 45.1197 +@@ -22,18 +22,32 @@
 45.1198 + #include <sys/types.h>
 45.1199 + #include <getopt.h>
 45.1200 + 
 45.1201 ++/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth().  */
 45.1202 ++#if HAVE_WCHAR_H
 45.1203 ++# include <wchar.h>
 45.1204 ++#endif
 45.1205 ++
 45.1206 ++/* Get iswblank(), towupper.  */
 45.1207 ++#if HAVE_WCTYPE_H
 45.1208 ++# include <wctype.h>
 45.1209 ++#endif
 45.1210 ++
 45.1211 + #include "system.h"
 45.1212 + #include "error.h"
 45.1213 + #include "fadvise.h"
 45.1214 + #include "hard-locale.h"
 45.1215 + #include "linebuffer.h"
 45.1216 +-#include "memcasecmp.h"
 45.1217 + #include "quote.h"
 45.1218 + #include "stdio--.h"
 45.1219 + #include "xmemcoll.h"
 45.1220 + #include "xstrtol.h"
 45.1221 + #include "argmatch.h"
 45.1222 + 
 45.1223 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
 45.1224 ++#if HAVE_MBRTOWC && defined mbstate_t
 45.1225 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
 45.1226 ++#endif
 45.1227 ++
 45.1228 + /* The official name of this program (e.g., no 'g' prefix).  */
 45.1229 + #define PROGRAM_NAME "join"
 45.1230 + 
 45.1231 +@@ -135,10 +149,12 @@ static struct outlist outlist_head;
 45.1232 + /* Last element in 'outlist', where a new element can be added.  */
 45.1233 + static struct outlist *outlist_end = &outlist_head;
 45.1234 + 
 45.1235 +-/* Tab character separating fields.  If negative, fields are separated
 45.1236 +-   by any nonempty string of blanks, otherwise by exactly one
 45.1237 +-   tab character whose value (when cast to unsigned char) equals TAB.  */
 45.1238 +-static int tab = -1;
 45.1239 ++/* Tab character separating fields.  If NULL, fields are separated
 45.1240 ++   by any nonempty string of blanks.  */
 45.1241 ++static char *tab = NULL;
 45.1242 ++
 45.1243 ++/* The number of bytes used for tab. */
 45.1244 ++static size_t tablen = 0;
 45.1245 + 
 45.1246 + /* If nonzero, check that the input is correctly ordered. */
 45.1247 + static enum
 45.1248 +@@ -275,13 +291,14 @@ xfields (struct line *line)
 45.1249 +   if (ptr == lim)
 45.1250 +     return;
 45.1251 + 
 45.1252 +-  if (0 <= tab && tab != '\n')
 45.1253 ++  if (tab != NULL)
 45.1254 +     {
 45.1255 ++      unsigned char t = tab[0];
 45.1256 +       char *sep;
 45.1257 +-      for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1)
 45.1258 ++      for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1)
 45.1259 +         extract_field (line, ptr, sep - ptr);
 45.1260 +     }
 45.1261 +-  else if (tab < 0)
 45.1262 ++   else
 45.1263 +     {
 45.1264 +       /* Skip leading blanks before the first field.  */
 45.1265 +       while (field_sep (*ptr))
 45.1266 +@@ -305,6 +322,147 @@ xfields (struct line *line)
 45.1267 +   extract_field (line, ptr, lim - ptr);
 45.1268 + }
 45.1269 + 
 45.1270 ++#if HAVE_MBRTOWC
 45.1271 ++static void
 45.1272 ++xfields_multibyte (struct line *line)
 45.1273 ++{
 45.1274 ++  char *ptr = line->buf.buffer;
 45.1275 ++  char const *lim = ptr + line->buf.length - 1;
 45.1276 ++  wchar_t wc = 0;
 45.1277 ++  size_t mblength = 1;
 45.1278 ++  mbstate_t state, state_bak;
 45.1279 ++
 45.1280 ++  memset (&state, 0, sizeof (mbstate_t));
 45.1281 ++
 45.1282 ++  if (ptr >= lim)
 45.1283 ++    return;
 45.1284 ++
 45.1285 ++  if (tab != NULL)
 45.1286 ++    {
 45.1287 ++      char *sep = ptr;
 45.1288 ++      for (; ptr < lim; ptr = sep + mblength)
 45.1289 ++	{
 45.1290 ++	  sep = ptr;
 45.1291 ++	  while (sep < lim)
 45.1292 ++	    {
 45.1293 ++	      state_bak = state;
 45.1294 ++	      mblength = mbrtowc (&wc, sep, lim - sep + 1, &state);
 45.1295 ++
 45.1296 ++	      if (mblength == (size_t)-1 || mblength == (size_t)-2)
 45.1297 ++		{
 45.1298 ++		  mblength = 1;
 45.1299 ++		  state = state_bak;
 45.1300 ++		}
 45.1301 ++	      mblength = (mblength < 1) ? 1 : mblength;
 45.1302 ++
 45.1303 ++	      if (mblength == tablen && !memcmp (sep, tab, mblength))
 45.1304 ++		break;
 45.1305 ++	      else
 45.1306 ++		{
 45.1307 ++		  sep += mblength;
 45.1308 ++		  continue;
 45.1309 ++		}
 45.1310 ++	    }
 45.1311 ++
 45.1312 ++	  if (sep >= lim)
 45.1313 ++	    break;
 45.1314 ++
 45.1315 ++	  extract_field (line, ptr, sep - ptr);
 45.1316 ++	}
 45.1317 ++    }
 45.1318 ++  else
 45.1319 ++    {
 45.1320 ++      /* Skip leading blanks before the first field.  */
 45.1321 ++      while(ptr < lim)
 45.1322 ++      {
 45.1323 ++        state_bak = state;
 45.1324 ++        mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state);
 45.1325 ++
 45.1326 ++        if (mblength == (size_t)-1 || mblength == (size_t)-2)
 45.1327 ++          {
 45.1328 ++            mblength = 1;
 45.1329 ++            state = state_bak;
 45.1330 ++            break;
 45.1331 ++          }
 45.1332 ++        mblength = (mblength < 1) ? 1 : mblength;
 45.1333 ++
 45.1334 ++        if (!iswblank(wc) && wc != '\n')
 45.1335 ++          break;
 45.1336 ++        ptr += mblength;
 45.1337 ++      }
 45.1338 ++
 45.1339 ++      do
 45.1340 ++	{
 45.1341 ++	  char *sep;
 45.1342 ++	  state_bak = state;
 45.1343 ++	  mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state);
 45.1344 ++	  if (mblength == (size_t)-1 || mblength == (size_t)-2)
 45.1345 ++	    {
 45.1346 ++	      mblength = 1;
 45.1347 ++	      state = state_bak;
 45.1348 ++	      break;
 45.1349 ++	    }
 45.1350 ++	  mblength = (mblength < 1) ? 1 : mblength;
 45.1351 ++
 45.1352 ++	  sep = ptr + mblength;
 45.1353 ++	  while (sep < lim)
 45.1354 ++	    {
 45.1355 ++	      state_bak = state;
 45.1356 ++	      mblength = mbrtowc (&wc, sep, lim - sep + 1, &state);
 45.1357 ++	      if (mblength == (size_t)-1 || mblength == (size_t)-2)
 45.1358 ++		{
 45.1359 ++		  mblength = 1;
 45.1360 ++		  state = state_bak;
 45.1361 ++		  break;
 45.1362 ++		}
 45.1363 ++	      mblength = (mblength < 1) ? 1 : mblength;
 45.1364 ++
 45.1365 ++	      if (iswblank (wc) || wc == '\n')
 45.1366 ++		break;
 45.1367 ++
 45.1368 ++	      sep += mblength;
 45.1369 ++	    }
 45.1370 ++
 45.1371 ++	  extract_field (line, ptr, sep - ptr);
 45.1372 ++	  if (sep >= lim)
 45.1373 ++	    return;
 45.1374 ++
 45.1375 ++	  state_bak = state;
 45.1376 ++	  mblength = mbrtowc (&wc, sep, lim - sep + 1, &state);
 45.1377 ++	  if (mblength == (size_t)-1 || mblength == (size_t)-2)
 45.1378 ++	    {
 45.1379 ++	      mblength = 1;
 45.1380 ++	      state = state_bak;
 45.1381 ++	      break;
 45.1382 ++	    }
 45.1383 ++	  mblength = (mblength < 1) ? 1 : mblength;
 45.1384 ++
 45.1385 ++	  ptr = sep + mblength;
 45.1386 ++	  while (ptr < lim)
 45.1387 ++	    {
 45.1388 ++	      state_bak = state;
 45.1389 ++	      mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state);
 45.1390 ++	      if (mblength == (size_t)-1 || mblength == (size_t)-2)
 45.1391 ++		{
 45.1392 ++		  mblength = 1;
 45.1393 ++		  state = state_bak;
 45.1394 ++		  break;
 45.1395 ++		}
 45.1396 ++	      mblength = (mblength < 1) ? 1 : mblength;
 45.1397 ++
 45.1398 ++	      if (!iswblank (wc) && wc != '\n')
 45.1399 ++		break;
 45.1400 ++
 45.1401 ++	      ptr += mblength;
 45.1402 ++	    }
 45.1403 ++	}
 45.1404 ++      while (ptr < lim);
 45.1405 ++    }
 45.1406 ++
 45.1407 ++  extract_field (line, ptr, lim - ptr);
 45.1408 ++}
 45.1409 ++#endif
 45.1410 ++
 45.1411 + static void
 45.1412 + freeline (struct line *line)
 45.1413 + {
 45.1414 +@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct
 45.1415 +         size_t jf_1, size_t jf_2)
 45.1416 + {
 45.1417 +   /* Start of field to compare in each file.  */
 45.1418 +-  char *beg1;
 45.1419 +-  char *beg2;
 45.1420 +-
 45.1421 +-  size_t len1;
 45.1422 +-  size_t len2;		/* Length of fields to compare.  */
 45.1423 ++  char *beg[2];
 45.1424 ++  char *copy[2];
 45.1425 ++  size_t len[2]; 	/* Length of fields to compare.  */
 45.1426 +   int diff;
 45.1427 ++  int i, j;
 45.1428 ++  int mallocd = 0;
 45.1429 + 
 45.1430 +   if (jf_1 < line1->nfields)
 45.1431 +     {
 45.1432 +-      beg1 = line1->fields[jf_1].beg;
 45.1433 +-      len1 = line1->fields[jf_1].len;
 45.1434 ++      beg[0] = line1->fields[jf_1].beg;
 45.1435 ++      len[0] = line1->fields[jf_1].len;
 45.1436 +     }
 45.1437 +   else
 45.1438 +     {
 45.1439 +-      beg1 = NULL;
 45.1440 +-      len1 = 0;
 45.1441 ++      beg[0] = NULL;
 45.1442 ++      len[0] = 0;
 45.1443 +     }
 45.1444 + 
 45.1445 +   if (jf_2 < line2->nfields)
 45.1446 +     {
 45.1447 +-      beg2 = line2->fields[jf_2].beg;
 45.1448 +-      len2 = line2->fields[jf_2].len;
 45.1449 ++      beg[1] = line2->fields[jf_2].beg;
 45.1450 ++      len[1] = line2->fields[jf_2].len;
 45.1451 +     }
 45.1452 +   else
 45.1453 +     {
 45.1454 +-      beg2 = NULL;
 45.1455 +-      len2 = 0;
 45.1456 ++      beg[1] = NULL;
 45.1457 ++      len[1] = 0;
 45.1458 +     }
 45.1459 + 
 45.1460 +-  if (len1 == 0)
 45.1461 +-    return len2 == 0 ? 0 : -1;
 45.1462 +-  if (len2 == 0)
 45.1463 ++  if (len[0] == 0)
 45.1464 ++    return len[1] == 0 ? 0 : -1;
 45.1465 ++  if (len[1] == 0)
 45.1466 +     return 1;
 45.1467 + 
 45.1468 +   if (ignore_case)
 45.1469 +     {
 45.1470 +-      /* FIXME: ignore_case does not work with NLS (in particular,
 45.1471 +-         with multibyte chars).  */
 45.1472 +-      diff = memcasecmp (beg1, beg2, MIN (len1, len2));
 45.1473 ++#ifdef HAVE_MBRTOWC
 45.1474 ++      if (MB_CUR_MAX > 1)
 45.1475 ++      {
 45.1476 ++        size_t mblength;
 45.1477 ++        wchar_t wc, uwc;
 45.1478 ++        mbstate_t state, state_bak;
 45.1479 ++
 45.1480 ++        memset (&state, '\0', sizeof (mbstate_t));
 45.1481 ++
 45.1482 ++        for (i = 0; i < 2; i++)
 45.1483 ++          {
 45.1484 ++            mallocd = 1;
 45.1485 ++            copy[i] = xmalloc (len[i] + 1);
 45.1486 ++            memset (copy[i], '\0',len[i] + 1);
 45.1487 ++
 45.1488 ++            for (j = 0; j < MIN (len[0], len[1]);)
 45.1489 ++              {
 45.1490 ++                state_bak = state;
 45.1491 ++                mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state);
 45.1492 ++
 45.1493 ++                switch (mblength)
 45.1494 ++                  {
 45.1495 ++                  case (size_t) -1:
 45.1496 ++                  case (size_t) -2:
 45.1497 ++                    state = state_bak;
 45.1498 ++                    /* Fall through */
 45.1499 ++                  case 0:
 45.1500 ++                    mblength = 1;
 45.1501 ++                    break;
 45.1502 ++
 45.1503 ++                  default:
 45.1504 ++                    uwc = towupper (wc);
 45.1505 ++
 45.1506 ++                    if (uwc != wc)
 45.1507 ++                      {
 45.1508 ++                        mbstate_t state_wc;
 45.1509 ++                        size_t mblen;
 45.1510 ++
 45.1511 ++                        memset (&state_wc, '\0', sizeof (mbstate_t));
 45.1512 ++                        mblen = wcrtomb (copy[i] + j, uwc, &state_wc);
 45.1513 ++                        assert (mblen != (size_t)-1);
 45.1514 ++                      }
 45.1515 ++                    else
 45.1516 ++                      memcpy (copy[i] + j, beg[i] + j, mblength);
 45.1517 ++                  }
 45.1518 ++                j += mblength;
 45.1519 ++              }
 45.1520 ++            copy[i][j] = '\0';
 45.1521 ++          }
 45.1522 ++      }
 45.1523 ++      else
 45.1524 ++#endif
 45.1525 ++      {
 45.1526 ++        for (i = 0; i < 2; i++)
 45.1527 ++          {
 45.1528 ++            mallocd = 1;
 45.1529 ++            copy[i] = xmalloc (len[i] + 1);
 45.1530 ++
 45.1531 ++            for (j = 0; j < MIN (len[0], len[1]); j++)
 45.1532 ++              copy[i][j] = toupper (beg[i][j]);
 45.1533 ++
 45.1534 ++            copy[i][j] = '\0';
 45.1535 ++          }
 45.1536 ++      }
 45.1537 +     }
 45.1538 +   else
 45.1539 +     {
 45.1540 +-      if (hard_LC_COLLATE)
 45.1541 +-        return xmemcoll (beg1, len1, beg2, len2);
 45.1542 +-      diff = memcmp (beg1, beg2, MIN (len1, len2));
 45.1543 ++      copy[0] = beg[0];
 45.1544 ++      copy[1] = beg[1];
 45.1545 ++    }
 45.1546 ++
 45.1547 ++  if (hard_LC_COLLATE)
 45.1548 ++    {
 45.1549 ++      diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]);
 45.1550 ++
 45.1551 ++      if (mallocd)
 45.1552 ++        for (i = 0; i < 2; i++)
 45.1553 ++          free (copy[i]);
 45.1554 ++
 45.1555 ++      return diff;
 45.1556 +     }
 45.1557 ++  diff = memcmp (copy[0], copy[1], MIN (len[0], len[1]));
 45.1558 ++
 45.1559 ++  if (mallocd)
 45.1560 ++    for (i = 0; i < 2; i++)
 45.1561 ++      free (copy[i]);
 45.1562 ++
 45.1563 + 
 45.1564 +   if (diff)
 45.1565 +     return diff;
 45.1566 +-  return len1 < len2 ? -1 : len1 != len2;
 45.1567 ++  return len[0] - len[1];
 45.1568 + }
 45.1569 + 
 45.1570 + /* Check that successive input lines PREV and CURRENT from input file
 45.1571 +@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep,
 45.1572 +     }
 45.1573 +   ++line_no[which - 1];
 45.1574 + 
 45.1575 ++#if HAVE_MBRTOWC
 45.1576 ++  if (MB_CUR_MAX > 1)
 45.1577 ++    xfields_multibyte (line);
 45.1578 ++  else
 45.1579 ++#endif
 45.1580 +   xfields (line);
 45.1581 + 
 45.1582 +   if (prevline[which - 1])
 45.1583 +@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *li
 45.1584 + 
 45.1585 + /* Output all the fields in line, other than the join field.  */
 45.1586 + 
 45.1587 ++#define PUT_TAB_CHAR							\
 45.1588 ++  do									\
 45.1589 ++    {									\
 45.1590 ++      (tab != NULL) ?							\
 45.1591 ++	fwrite(tab, sizeof(char), tablen, stdout) : putchar (' ');	\
 45.1592 ++    }									\
 45.1593 ++  while (0)
 45.1594 ++
 45.1595 + static void
 45.1596 + prfields (struct line const *line, size_t join_field, size_t autocount)
 45.1597 + {
 45.1598 +   size_t i;
 45.1599 +   size_t nfields = autoformat ? autocount : line->nfields;
 45.1600 +-  char output_separator = tab < 0 ? ' ' : tab;
 45.1601 + 
 45.1602 +   for (i = 0; i < join_field && i < nfields; ++i)
 45.1603 +     {
 45.1604 +-      putchar (output_separator);
 45.1605 ++      PUT_TAB_CHAR;
 45.1606 +       prfield (i, line);
 45.1607 +     }
 45.1608 +   for (i = join_field + 1; i < nfields; ++i)
 45.1609 +     {
 45.1610 +-      putchar (output_separator);
 45.1611 ++      PUT_TAB_CHAR;
 45.1612 +       prfield (i, line);
 45.1613 +     }
 45.1614 + }
 45.1615 +@@ -591,7 +838,6 @@ static void
 45.1616 + prjoin (struct line const *line1, struct line const *line2)
 45.1617 + {
 45.1618 +   const struct outlist *outlist;
 45.1619 +-  char output_separator = tab < 0 ? ' ' : tab;
 45.1620 +   size_t field;
 45.1621 +   struct line const *line;
 45.1622 + 
 45.1623 +@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct
 45.1624 +           o = o->next;
 45.1625 +           if (o == NULL)
 45.1626 +             break;
 45.1627 +-          putchar (output_separator);
 45.1628 ++          PUT_TAB_CHAR;
 45.1629 +         }
 45.1630 +       putchar (eolchar);
 45.1631 +     }
 45.1632 +@@ -1103,21 +1349,46 @@ main (int argc, char **argv)
 45.1633 + 
 45.1634 +         case 't':
 45.1635 +           {
 45.1636 +-            unsigned char newtab = optarg[0];
 45.1637 ++            char *newtab = NULL;
 45.1638 ++            size_t newtablen;
 45.1639 ++            newtab = xstrdup (optarg);
 45.1640 ++#if HAVE_MBRTOWC
 45.1641 ++            if (MB_CUR_MAX > 1)
 45.1642 ++              {
 45.1643 ++                mbstate_t state;
 45.1644 ++
 45.1645 ++                memset (&state, 0, sizeof (mbstate_t));
 45.1646 ++                newtablen = mbrtowc (NULL, newtab,
 45.1647 ++                                     strnlen (newtab, MB_LEN_MAX),
 45.1648 ++                                     &state);
 45.1649 ++                if (newtablen == (size_t) 0
 45.1650 ++                    || newtablen == (size_t) -1
 45.1651 ++                    || newtablen == (size_t) -2)
 45.1652 ++                  newtablen = 1;
 45.1653 ++              }
 45.1654 ++            else
 45.1655 ++#endif
 45.1656 ++              newtablen = 1;
 45.1657 +             if (! newtab)
 45.1658 +-              newtab = '\n'; /* '' => process the whole line.  */
 45.1659 ++            {
 45.1660 ++              newtab = (char*)"\n"; /* '' => process the whole line.  */
 45.1661 ++            }
 45.1662 +             else if (optarg[1])
 45.1663 +               {
 45.1664 +-                if (STREQ (optarg, "\\0"))
 45.1665 +-                  newtab = '\0';
 45.1666 +-                else
 45.1667 +-                  error (EXIT_FAILURE, 0, _("multi-character tab %s"),
 45.1668 +-                         quote (optarg));
 45.1669 ++                if (newtablen == 1 && newtab[1])
 45.1670 ++                {
 45.1671 ++                  if (STREQ (newtab, "\\0"))
 45.1672 ++                     newtab[0] = '\0';
 45.1673 ++                }
 45.1674 ++              }
 45.1675 ++            if (tab != NULL && strcmp (tab, newtab))
 45.1676 ++              {
 45.1677 ++                free (newtab);
 45.1678 ++                error (EXIT_FAILURE, 0, _("incompatible tabs"));
 45.1679 +               }
 45.1680 +-            if (0 <= tab && tab != newtab)
 45.1681 +-              error (EXIT_FAILURE, 0, _("incompatible tabs"));
 45.1682 +             tab = newtab;
 45.1683 +-          }
 45.1684 ++            tablen = newtablen;
 45.1685 ++           }
 45.1686 +           break;
 45.1687 + 
 45.1688 +         case 'z':
 45.1689 +diff -Naurp coreutils-8.25-orig/src/pr.c coreutils-8.25/src/pr.c
 45.1690 +--- coreutils-8.25-orig/src/pr.c	2016-01-01 07:48:50.000000000 -0600
 45.1691 ++++ coreutils-8.25/src/pr.c	2016-02-08 19:07:10.306944635 -0600
 45.1692 +@@ -311,6 +311,24 @@
 45.1693 + 
 45.1694 + #include <getopt.h>
 45.1695 + #include <sys/types.h>
 45.1696 ++
 45.1697 ++/* Get MB_LEN_MAX.  */
 45.1698 ++#include <limits.h>
 45.1699 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
 45.1700 ++   installation; work around this configuration error.  */
 45.1701 ++#if !defined MB_LEN_MAX || MB_LEN_MAX == 1
 45.1702 ++# define MB_LEN_MAX 16
 45.1703 ++#endif
 45.1704 ++
 45.1705 ++/* Get MB_CUR_MAX.  */
 45.1706 ++#include <stdlib.h>
 45.1707 ++
 45.1708 ++/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
 45.1709 ++/* Get mbstate_t, mbrtowc(), wcwidth().  */
 45.1710 ++#if HAVE_WCHAR_H
 45.1711 ++# include <wchar.h>
 45.1712 ++#endif
 45.1713 ++
 45.1714 + #include "system.h"
 45.1715 + #include "error.h"
 45.1716 + #include "fadvise.h"
 45.1717 +@@ -323,6 +341,18 @@
 45.1718 + #include "xstrtol.h"
 45.1719 + #include "xdectoint.h"
 45.1720 + 
 45.1721 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
 45.1722 ++#if HAVE_MBRTOWC && defined mbstate_t
 45.1723 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
 45.1724 ++#endif
 45.1725 ++
 45.1726 ++#ifndef HAVE_DECL_WCWIDTH
 45.1727 ++"this configure-time declaration test was not run"
 45.1728 ++#endif
 45.1729 ++#if !HAVE_DECL_WCWIDTH
 45.1730 ++extern int wcwidth ();
 45.1731 ++#endif
 45.1732 ++
 45.1733 + /* The official name of this program (e.g., no 'g' prefix).  */
 45.1734 + #define PROGRAM_NAME "pr"
 45.1735 + 
 45.1736 +@@ -415,7 +445,20 @@ struct COLUMN
 45.1737 + 
 45.1738 + typedef struct COLUMN COLUMN;
 45.1739 + 
 45.1740 +-static int char_to_clump (char c);
 45.1741 ++/* Funtion pointers to switch functions for single byte locale or for
 45.1742 ++   multibyte locale. If multibyte functions do not exist in your sysytem,
 45.1743 ++   these pointers always point the function for single byte locale. */
 45.1744 ++static void (*print_char) (char c);
 45.1745 ++static int (*char_to_clump) (char c);
 45.1746 ++
 45.1747 ++/* Functions for single byte locale. */
 45.1748 ++static void print_char_single (char c);
 45.1749 ++static int char_to_clump_single (char c);
 45.1750 ++
 45.1751 ++/* Functions for multibyte locale. */
 45.1752 ++static void print_char_multi (char c);
 45.1753 ++static int char_to_clump_multi (char c);
 45.1754 ++
 45.1755 + static bool read_line (COLUMN *p);
 45.1756 + static bool print_page (void);
 45.1757 + static bool print_stored (COLUMN *p);
 45.1758 +@@ -427,6 +470,7 @@ static void add_line_number (COLUMN *p);
 45.1759 + static void getoptnum (const char *n_str, int min, int *num,
 45.1760 +                        const char *errfmt);
 45.1761 + static void getoptarg (char *arg, char switch_char, char *character,
 45.1762 ++                       int *character_length, int *character_width,
 45.1763 +                        int *number);
 45.1764 + static void print_files (int number_of_files, char **av);
 45.1765 + static void init_parameters (int number_of_files);
 45.1766 +@@ -440,7 +484,6 @@ static void store_char (char c);
 45.1767 + static void pad_down (unsigned int lines);
 45.1768 + static void read_rest_of_line (COLUMN *p);
 45.1769 + static void skip_read (COLUMN *p, int column_number);
 45.1770 +-static void print_char (char c);
 45.1771 + static void cleanup (void);
 45.1772 + static void print_sep_string (void);
 45.1773 + static void separator_string (const char *optarg_S);
 45.1774 +@@ -452,7 +495,7 @@ static COLUMN *column_vector;
 45.1775 +    we store the leftmost columns contiguously in buff.
 45.1776 +    To print a line from buff, get the index of the first character
 45.1777 +    from line_vector[i], and print up to line_vector[i + 1]. */
 45.1778 +-static char *buff;
 45.1779 ++static unsigned char *buff;
 45.1780 + 
 45.1781 + /* Index of the position in buff where the next character
 45.1782 +    will be stored. */
 45.1783 +@@ -556,7 +599,7 @@ static int chars_per_column;
 45.1784 + static bool untabify_input = false;
 45.1785 + 
 45.1786 + /* (-e) The input tab character. */
 45.1787 +-static char input_tab_char = '\t';
 45.1788 ++static char input_tab_char[MB_LEN_MAX] = "\t";
 45.1789 + 
 45.1790 + /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ...
 45.1791 +    where the leftmost column is 1. */
 45.1792 +@@ -566,7 +609,10 @@ static int chars_per_input_tab = 8;
 45.1793 + static bool tabify_output = false;
 45.1794 + 
 45.1795 + /* (-i) The output tab character. */
 45.1796 +-static char output_tab_char = '\t';
 45.1797 ++static char output_tab_char[MB_LEN_MAX] = "\t";
 45.1798 ++
 45.1799 ++/* (-i) The byte length of output tab character. */
 45.1800 ++static int output_tab_char_length = 1;
 45.1801 + 
 45.1802 + /* (-i) The width of the output tab. */
 45.1803 + static int chars_per_output_tab = 8;
 45.1804 +@@ -636,7 +682,13 @@ static int line_number;
 45.1805 + static bool numbered_lines = false;
 45.1806 + 
 45.1807 + /* (-n) Character which follows each line number. */
 45.1808 +-static char number_separator = '\t';
 45.1809 ++static char number_separator[MB_LEN_MAX] = "\t";
 45.1810 ++
 45.1811 ++/* (-n) The byte length of the character which follows each line number. */
 45.1812 ++static int number_separator_length = 1;
 45.1813 ++
 45.1814 ++/* (-n) The character width of the character which follows each line number. */
 45.1815 ++static int number_separator_width = 0;
 45.1816 + 
 45.1817 + /* (-n) line counting starts with 1st line of input file (not with 1st
 45.1818 +    line of 1st page printed). */
 45.1819 +@@ -689,6 +741,7 @@ static bool use_col_separator = false;
 45.1820 +    -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */
 45.1821 + static char *col_sep_string = (char *) "";
 45.1822 + static int col_sep_length = 0;
 45.1823 ++static int col_sep_width = 0;
 45.1824 + static char *column_separator = (char *) " ";
 45.1825 + static char *line_separator = (char *) "\t";
 45.1826 + 
 45.1827 +@@ -839,6 +892,13 @@ separator_string (const char *optarg_S)
 45.1828 +   col_sep_length = (int) strlen (optarg_S);
 45.1829 +   col_sep_string = xmalloc (col_sep_length + 1);
 45.1830 +   strcpy (col_sep_string, optarg_S);
 45.1831 ++
 45.1832 ++#if HAVE_MBRTOWC
 45.1833 ++  if (MB_CUR_MAX > 1)
 45.1834 ++    col_sep_width = mbswidth (col_sep_string, 0);
 45.1835 ++  else
 45.1836 ++#endif
 45.1837 ++    col_sep_width = col_sep_length;
 45.1838 + }
 45.1839 + 
 45.1840 + int
 45.1841 +@@ -863,6 +923,21 @@ main (int argc, char **argv)
 45.1842 + 
 45.1843 +   atexit (close_stdout);
 45.1844 + 
 45.1845 ++/* Define which functions are used, the ones for single byte locale or the ones
 45.1846 ++   for multibyte locale. */
 45.1847 ++#if HAVE_MBRTOWC
 45.1848 ++  if (MB_CUR_MAX > 1)
 45.1849 ++    {
 45.1850 ++      print_char = print_char_multi;
 45.1851 ++      char_to_clump = char_to_clump_multi;
 45.1852 ++    }
 45.1853 ++  else
 45.1854 ++#endif
 45.1855 ++    {
 45.1856 ++      print_char = print_char_single;
 45.1857 ++      char_to_clump = char_to_clump_single;
 45.1858 ++    }
 45.1859 ++
 45.1860 +   n_files = 0;
 45.1861 +   file_names = (argc > 1
 45.1862 +                 ? xmalloc ((argc - 1) * sizeof (char *))
 45.1863 +@@ -939,8 +1014,12 @@ main (int argc, char **argv)
 45.1864 +           break;
 45.1865 +         case 'e':
 45.1866 +           if (optarg)
 45.1867 +-            getoptarg (optarg, 'e', &input_tab_char,
 45.1868 +-                       &chars_per_input_tab);
 45.1869 ++            {
 45.1870 ++              int dummy_length, dummy_width;
 45.1871 ++
 45.1872 ++              getoptarg (optarg, 'e', input_tab_char, &dummy_length,
 45.1873 ++                         &dummy_width, &chars_per_input_tab);
 45.1874 ++            }
 45.1875 +           /* Could check tab width > 0. */
 45.1876 +           untabify_input = true;
 45.1877 +           break;
 45.1878 +@@ -953,8 +1032,12 @@ main (int argc, char **argv)
 45.1879 +           break;
 45.1880 +         case 'i':
 45.1881 +           if (optarg)
 45.1882 +-            getoptarg (optarg, 'i', &output_tab_char,
 45.1883 +-                       &chars_per_output_tab);
 45.1884 ++            {
 45.1885 ++              int dummy_width;
 45.1886 ++
 45.1887 ++              getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length,
 45.1888 ++                         &dummy_width, &chars_per_output_tab);
 45.1889 ++            }
 45.1890 +           /* Could check tab width > 0. */
 45.1891 +           tabify_output = true;
 45.1892 +           break;
 45.1893 +@@ -972,8 +1055,8 @@ main (int argc, char **argv)
 45.1894 +         case 'n':
 45.1895 +           numbered_lines = true;
 45.1896 +           if (optarg)
 45.1897 +-            getoptarg (optarg, 'n', &number_separator,
 45.1898 +-                       &chars_per_number);
 45.1899 ++            getoptarg (optarg, 'n', number_separator, &number_separator_length,
 45.1900 ++                       &number_separator_width, &chars_per_number);
 45.1901 +           break;
 45.1902 +         case 'N':
 45.1903 +           skip_count = false;
 45.1904 +@@ -997,7 +1080,7 @@ main (int argc, char **argv)
 45.1905 +           old_s = false;
 45.1906 +           /* Reset an additional input of -s, -S dominates -s */
 45.1907 +           col_sep_string = bad_cast ("");
 45.1908 +-          col_sep_length = 0;
 45.1909 ++          col_sep_length = col_sep_width = 0;
 45.1910 +           use_col_separator = true;
 45.1911 +           if (optarg)
 45.1912 +             separator_string (optarg);
 45.1913 +@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, i
 45.1914 +    a number. */
 45.1915 + 
 45.1916 + static void
 45.1917 +-getoptarg (char *arg, char switch_char, char *character, int *number)
 45.1918 ++getoptarg (char *arg, char switch_char, char *character, int *character_length,
 45.1919 ++           int *character_width, int *number)
 45.1920 + {
 45.1921 +   if (!ISDIGIT (*arg))
 45.1922 +-    *character = *arg++;
 45.1923 ++    {
 45.1924 ++#ifdef HAVE_MBRTOWC
 45.1925 ++      if (MB_CUR_MAX > 1)        /* for multibyte locale. */
 45.1926 ++        {
 45.1927 ++          wchar_t wc;
 45.1928 ++          size_t mblength;
 45.1929 ++          int width;
 45.1930 ++          mbstate_t state = {'\0'};
 45.1931 ++
 45.1932 ++          mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state);
 45.1933 ++
 45.1934 ++          if (mblength == (size_t)-1 || mblength == (size_t)-2)
 45.1935 ++            {
 45.1936 ++              *character_length = 1;
 45.1937 ++              *character_width = 1;
 45.1938 ++            }
 45.1939 ++          else
 45.1940 ++            {
 45.1941 ++              *character_length = (mblength < 1) ? 1 : mblength;
 45.1942 ++              width = wcwidth (wc);
 45.1943 ++              *character_width = (width < 0) ? 0 : width;
 45.1944 ++            }
 45.1945 ++
 45.1946 ++          strncpy (character, arg, *character_length);
 45.1947 ++          arg += *character_length;
 45.1948 ++        }
 45.1949 ++      else                        /* for single byte locale. */
 45.1950 ++#endif
 45.1951 ++        {
 45.1952 ++          *character = *arg++;
 45.1953 ++          *character_length = 1;
 45.1954 ++          *character_width = 1;
 45.1955 ++        }
 45.1956 ++    }
 45.1957 ++
 45.1958 +   if (*arg)
 45.1959 +     {
 45.1960 +       long int tmp_long;
 45.1961 +@@ -1177,6 +1295,11 @@ static void
 45.1962 + init_parameters (int number_of_files)
 45.1963 + {
 45.1964 +   int chars_used_by_number = 0;
 45.1965 ++  int mb_len = 1;
 45.1966 ++#if HAVE_MBRTOWC
 45.1967 ++  if (MB_CUR_MAX > 1)
 45.1968 ++    mb_len = MB_LEN_MAX;
 45.1969 ++#endif
 45.1970 + 
 45.1971 +   lines_per_body = lines_per_page - lines_per_header - lines_per_footer;
 45.1972 +   if (lines_per_body <= 0)
 45.1973 +@@ -1214,7 +1337,7 @@ init_parameters (int number_of_files)
 45.1974 +           else
 45.1975 +             col_sep_string = column_separator;
 45.1976 + 
 45.1977 +-          col_sep_length = 1;
 45.1978 ++          col_sep_length = col_sep_width = 1;
 45.1979 +           use_col_separator = true;
 45.1980 +         }
 45.1981 +       /* It's rather pointless to define a TAB separator with column
 45.1982 +@@ -1244,11 +1367,11 @@ init_parameters (int number_of_files)
 45.1983 +              + TAB_WIDTH (chars_per_input_tab, chars_per_number);   */
 45.1984 + 
 45.1985 +       /* Estimate chars_per_text without any margin and keep it constant. */
 45.1986 +-      if (number_separator == '\t')
 45.1987 ++      if (number_separator[0] == '\t')
 45.1988 +         number_width = (chars_per_number
 45.1989 +                         + TAB_WIDTH (chars_per_default_tab, chars_per_number));
 45.1990 +       else
 45.1991 +-        number_width = chars_per_number + 1;
 45.1992 ++        number_width = chars_per_number + number_separator_width;
 45.1993 + 
 45.1994 +       /* The number is part of the column width unless we are
 45.1995 +          printing files in parallel. */
 45.1996 +@@ -1257,7 +1380,7 @@ init_parameters (int number_of_files)
 45.1997 +     }
 45.1998 + 
 45.1999 +   chars_per_column = (chars_per_line - chars_used_by_number
 45.2000 +-                      - (columns - 1) * col_sep_length) / columns;
 45.2001 ++                      - (columns - 1) * col_sep_width) / columns;
 45.2002 + 
 45.2003 +   if (chars_per_column < 1)
 45.2004 +     error (EXIT_FAILURE, 0, _("page width too narrow"));
 45.2005 +@@ -1275,7 +1398,7 @@ init_parameters (int number_of_files)
 45.2006 +      We've to use 8 as the lower limit, if we use chars_per_default_tab = 8
 45.2007 +      to expand a tab which is not an input_tab-char. */
 45.2008 +   free (clump_buff);
 45.2009 +-  clump_buff = xmalloc (MAX (8, chars_per_input_tab));
 45.2010 ++  clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab));
 45.2011 + }
 45.2012 + 
 45.2013 + /* Open the necessary files,
 45.2014 +@@ -1383,7 +1506,7 @@ init_funcs (void)
 45.2015 + 
 45.2016 +   /* Enlarge p->start_position of first column to use the same form of
 45.2017 +      padding_not_printed with all columns. */
 45.2018 +-  h = h + col_sep_length;
 45.2019 ++  h = h + col_sep_width;
 45.2020 + 
 45.2021 +   /* This loop takes care of all but the rightmost column. */
 45.2022 + 
 45.2023 +@@ -1417,7 +1540,7 @@ init_funcs (void)
 45.2024 +         }
 45.2025 +       else
 45.2026 +         {
 45.2027 +-          h = h_next + col_sep_length;
 45.2028 ++          h = h_next + col_sep_width;
 45.2029 +           h_next = h + chars_per_column;
 45.2030 +         }
 45.2031 +     }
 45.2032 +@@ -1708,9 +1831,9 @@ static void
 45.2033 + align_column (COLUMN *p)
 45.2034 + {
 45.2035 +   padding_not_printed = p->start_position;
 45.2036 +-  if (padding_not_printed - col_sep_length > 0)
 45.2037 ++  if (padding_not_printed - col_sep_width > 0)
 45.2038 +     {
 45.2039 +-      pad_across_to (padding_not_printed - col_sep_length);
 45.2040 ++      pad_across_to (padding_not_printed - col_sep_width);
 45.2041 +       padding_not_printed = ANYWHERE;
 45.2042 +     }
 45.2043 + 
 45.2044 +@@ -1981,13 +2104,13 @@ store_char (char c)
 45.2045 +       /* May be too generous. */
 45.2046 +       buff = X2REALLOC (buff, &buff_allocated);
 45.2047 +     }
 45.2048 +-  buff[buff_current++] = c;
 45.2049 ++  buff[buff_current++] = (unsigned char) c;
 45.2050 + }
 45.2051 + 
 45.2052 + static void
 45.2053 + add_line_number (COLUMN *p)
 45.2054 + {
 45.2055 +-  int i;
 45.2056 ++  int i, j;
 45.2057 +   char *s;
 45.2058 +   int num_width;
 45.2059 + 
 45.2060 +@@ -2004,22 +2127,24 @@ add_line_number (COLUMN *p)
 45.2061 +       /* Tabification is assumed for multiple columns, also for n-separators,
 45.2062 +          but 'default n-separator = TAB' hasn't been given priority over
 45.2063 +          equal column_width also specified by POSIX. */
 45.2064 +-      if (number_separator == '\t')
 45.2065 ++      if (number_separator[0] == '\t')
 45.2066 +         {
 45.2067 +           i = number_width - chars_per_number;
 45.2068 +           while (i-- > 0)
 45.2069 +             (p->char_func) (' ');
 45.2070 +         }
 45.2071 +       else
 45.2072 +-        (p->char_func) (number_separator);
 45.2073 ++        for (j = 0; j < number_separator_length; j++)
 45.2074 ++          (p->char_func) (number_separator[j]);
 45.2075 +     }
 45.2076 +   else
 45.2077 +     /* To comply with POSIX, we avoid any expansion of default TAB
 45.2078 +        separator with a single column output. No column_width requirement
 45.2079 +        has to be considered. */
 45.2080 +     {
 45.2081 +-      (p->char_func) (number_separator);
 45.2082 +-      if (number_separator == '\t')
 45.2083 ++      for (j = 0; j < number_separator_length; j++)
 45.2084 ++        (p->char_func) (number_separator[j]);
 45.2085 ++      if (number_separator[0] == '\t')
 45.2086 +         output_position = POS_AFTER_TAB (chars_per_output_tab,
 45.2087 +                           output_position);
 45.2088 +     }
 45.2089 +@@ -2180,7 +2305,7 @@ print_white_space (void)
 45.2090 +   while (goal - h_old > 1
 45.2091 +          && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal)
 45.2092 +     {
 45.2093 +-      putchar (output_tab_char);
 45.2094 ++      fwrite (output_tab_char, sizeof(char), output_tab_char_length, stdout);
 45.2095 +       h_old = h_new;
 45.2096 +     }
 45.2097 +   while (++h_old <= goal)
 45.2098 +@@ -2200,6 +2325,7 @@ print_sep_string (void)
 45.2099 + {
 45.2100 +   char *s;
 45.2101 +   int l = col_sep_length;
 45.2102 ++  int not_space_flag;
 45.2103 + 
 45.2104 +   s = col_sep_string;
 45.2105 + 
 45.2106 +@@ -2213,6 +2339,7 @@ print_sep_string (void)
 45.2107 +     {
 45.2108 +       for (; separators_not_printed > 0; --separators_not_printed)
 45.2109 +         {
 45.2110 ++          not_space_flag = 0;
 45.2111 +           while (l-- > 0)
 45.2112 +             {
 45.2113 +               /* 3 types of sep_strings: spaces only, spaces and chars,
 45.2114 +@@ -2226,12 +2353,15 @@ print_sep_string (void)
 45.2115 +                 }
 45.2116 +               else
 45.2117 +                 {
 45.2118 ++                  not_space_flag = 1;
 45.2119 +                   if (spaces_not_printed > 0)
 45.2120 +                     print_white_space ();
 45.2121 +                   putchar (*s++);
 45.2122 +-                  ++output_position;
 45.2123 +                 }
 45.2124 +             }
 45.2125 ++          if (not_space_flag)
 45.2126 ++            output_position += col_sep_width;
 45.2127 ++
 45.2128 +           /* sep_string ends with some spaces */
 45.2129 +           if (spaces_not_printed > 0)
 45.2130 +             print_white_space ();
 45.2131 +@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clu
 45.2132 +    required number of tabs and spaces. */
 45.2133 + 
 45.2134 + static void
 45.2135 +-print_char (char c)
 45.2136 ++print_char_single (char c)
 45.2137 + {
 45.2138 +   if (tabify_output)
 45.2139 +     {
 45.2140 +@@ -2283,6 +2413,74 @@ print_char (char c)
 45.2141 +   putchar (c);
 45.2142 + }
 45.2143 + 
 45.2144 ++#ifdef HAVE_MBRTOWC
 45.2145 ++static void
 45.2146 ++print_char_multi (char c)
 45.2147 ++{
 45.2148 ++  static size_t mbc_pos = 0;
 45.2149 ++  static char mbc[MB_LEN_MAX] = {'\0'};
 45.2150 ++  static mbstate_t state = {'\0'};
 45.2151 ++  mbstate_t state_bak;
 45.2152 ++  wchar_t wc;
 45.2153 ++  size_t mblength;
 45.2154 ++  int width;
 45.2155 ++
 45.2156 ++  if (tabify_output)
 45.2157 ++    {
 45.2158 ++      state_bak = state;
 45.2159 ++      mbc[mbc_pos++] = c;
 45.2160 ++      mblength = mbrtowc (&wc, mbc, mbc_pos, &state);
 45.2161 ++
 45.2162 ++      while (mbc_pos > 0)
 45.2163 ++        {
 45.2164 ++          switch (mblength)
 45.2165 ++            {
 45.2166 ++            case (size_t)-2:
 45.2167 ++              state = state_bak;
 45.2168 ++              return;
 45.2169 ++
 45.2170 ++            case (size_t)-1:
 45.2171 ++              state = state_bak;
 45.2172 ++              ++output_position;
 45.2173 ++              putchar (mbc[0]);
 45.2174 ++              memmove (mbc, mbc + 1, MB_CUR_MAX - 1);
 45.2175 ++              --mbc_pos;
 45.2176 ++              break;
 45.2177 ++
 45.2178 ++            case 0:
 45.2179 ++              mblength = 1;
 45.2180 ++
 45.2181 ++            default:
 45.2182 ++              if (wc == L' ')
 45.2183 ++                {
 45.2184 ++                  memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength);
 45.2185 ++                  --mbc_pos;
 45.2186 ++                  ++spaces_not_printed;
 45.2187 ++                  return;
 45.2188 ++                }
 45.2189 ++              else if (spaces_not_printed > 0)
 45.2190 ++                print_white_space ();
 45.2191 ++
 45.2192 ++              /* Nonprintables are assumed to have width 0, except L'\b'. */
 45.2193 ++              if ((width = wcwidth (wc)) < 1)
 45.2194 ++                {
 45.2195 ++                  if (wc == L'\b')
 45.2196 ++                    --output_position;
 45.2197 ++                }
 45.2198 ++              else
 45.2199 ++                output_position += width;
 45.2200 ++
 45.2201 ++              fwrite (mbc, sizeof(char), mblength, stdout);
 45.2202 ++              memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength);
 45.2203 ++              mbc_pos -= mblength;
 45.2204 ++            }
 45.2205 ++        }
 45.2206 ++      return;
 45.2207 ++    }
 45.2208 ++  putchar (c);
 45.2209 ++}
 45.2210 ++#endif
 45.2211 ++
 45.2212 + /* Skip to page PAGE before printing.
 45.2213 +    PAGE may be larger than total number of pages. */
 45.2214 + 
 45.2215 +@@ -2462,9 +2660,9 @@ read_line (COLUMN *p)
 45.2216 +           align_empty_cols = false;
 45.2217 +         }
 45.2218 + 
 45.2219 +-      if (padding_not_printed - col_sep_length > 0)
 45.2220 ++      if (padding_not_printed - col_sep_width > 0)
 45.2221 +         {
 45.2222 +-          pad_across_to (padding_not_printed - col_sep_length);
 45.2223 ++          pad_across_to (padding_not_printed - col_sep_width);
 45.2224 +           padding_not_printed = ANYWHERE;
 45.2225 +         }
 45.2226 + 
 45.2227 +@@ -2534,7 +2732,7 @@ print_stored (COLUMN *p)
 45.2228 +   int i;
 45.2229 + 
 45.2230 +   int line = p->current_line++;
 45.2231 +-  char *first = &buff[line_vector[line]];
 45.2232 ++  unsigned char *first = &buff[line_vector[line]];
 45.2233 +   /* FIXME
 45.2234 +      UMR: Uninitialized memory read:
 45.2235 +      * This is occurring while in:
 45.2236 +@@ -2546,7 +2744,7 @@ print_stored (COLUMN *p)
 45.2237 +      xmalloc        [xmalloc.c:94]
 45.2238 +      init_store_cols [pr.c:1648]
 45.2239 +      */
 45.2240 +-  char *last = &buff[line_vector[line + 1]];
 45.2241 ++  unsigned char *last = &buff[line_vector[line + 1]];
 45.2242 + 
 45.2243 +   pad_vertically = true;
 45.2244 + 
 45.2245 +@@ -2565,9 +2763,9 @@ print_stored (COLUMN *p)
 45.2246 +         }
 45.2247 +     }
 45.2248 + 
 45.2249 +-  if (padding_not_printed - col_sep_length > 0)
 45.2250 ++  if (padding_not_printed - col_sep_width > 0)
 45.2251 +     {
 45.2252 +-      pad_across_to (padding_not_printed - col_sep_length);
 45.2253 ++      pad_across_to (padding_not_printed - col_sep_width);
 45.2254 +       padding_not_printed = ANYWHERE;
 45.2255 +     }
 45.2256 + 
 45.2257 +@@ -2580,8 +2778,8 @@ print_stored (COLUMN *p)
 45.2258 +   if (spaces_not_printed == 0)
 45.2259 +     {
 45.2260 +       output_position = p->start_position + end_vector[line];
 45.2261 +-      if (p->start_position - col_sep_length == chars_per_margin)
 45.2262 +-        output_position -= col_sep_length;
 45.2263 ++      if (p->start_position - col_sep_width == chars_per_margin)
 45.2264 ++        output_position -= col_sep_width;
 45.2265 +     }
 45.2266 + 
 45.2267 +   return true;
 45.2268 +@@ -2600,7 +2798,7 @@ print_stored (COLUMN *p)
 45.2269 +    number of characters is 1.) */
 45.2270 + 
 45.2271 + static int
 45.2272 +-char_to_clump (char c)
 45.2273 ++char_to_clump_single (char c)
 45.2274 + {
 45.2275 +   unsigned char uc = c;
 45.2276 +   char *s = clump_buff;
 45.2277 +@@ -2610,10 +2808,10 @@ char_to_clump (char c)
 45.2278 +   int chars;
 45.2279 +   int chars_per_c = 8;
 45.2280 + 
 45.2281 +-  if (c == input_tab_char)
 45.2282 ++  if (c == input_tab_char[0])
 45.2283 +     chars_per_c = chars_per_input_tab;
 45.2284 + 
 45.2285 +-  if (c == input_tab_char || c == '\t')
 45.2286 ++  if (c == input_tab_char[0] || c == '\t')
 45.2287 +     {
 45.2288 +       width = TAB_WIDTH (chars_per_c, input_position);
 45.2289 + 
 45.2290 +@@ -2694,6 +2892,164 @@ char_to_clump (char c)
 45.2291 +   return chars;
 45.2292 + }
 45.2293 + 
 45.2294 ++#ifdef HAVE_MBRTOWC
 45.2295 ++static int
 45.2296 ++char_to_clump_multi (char c)
 45.2297 ++{
 45.2298 ++  static size_t mbc_pos = 0;
 45.2299 ++  static char mbc[MB_LEN_MAX] = {'\0'};
 45.2300 ++  static mbstate_t state = {'\0'};
 45.2301 ++  mbstate_t state_bak;
 45.2302 ++  wchar_t wc;
 45.2303 ++  size_t mblength;
 45.2304 ++  int wc_width;
 45.2305 ++  register char *s = clump_buff;
 45.2306 ++  register int i, j;
 45.2307 ++  char esc_buff[4];
 45.2308 ++  int width;
 45.2309 ++  int chars;
 45.2310 ++  int chars_per_c = 8;
 45.2311 ++
 45.2312 ++  state_bak = state;
 45.2313 ++  mbc[mbc_pos++] = c;
 45.2314 ++  mblength = mbrtowc (&wc, mbc, mbc_pos, &state);
 45.2315 ++
 45.2316 ++  width = 0;
 45.2317 ++  chars = 0;
 45.2318 ++  while (mbc_pos > 0)
 45.2319 ++    {
 45.2320 ++      switch (mblength)
 45.2321 ++        {
 45.2322 ++        case (size_t)-2:
 45.2323 ++          state = state_bak;
 45.2324 ++          return 0;
 45.2325 ++
 45.2326 ++        case (size_t)-1:
 45.2327 ++          state = state_bak;
 45.2328 ++          mblength = 1;
 45.2329 ++
 45.2330 ++          if (use_esc_sequence || use_cntrl_prefix)
 45.2331 ++            {
 45.2332 ++              width = +4;
 45.2333 ++              chars = +4;
 45.2334 ++              *s++ = '\\';
 45.2335 ++              sprintf (esc_buff, "%03o", (unsigned char) mbc[0]);
 45.2336 ++              for (i = 0; i <= 2; ++i)
 45.2337 ++                *s++ = (int) esc_buff[i];
 45.2338 ++            }
 45.2339 ++          else
 45.2340 ++            {
 45.2341 ++              width += 1;
 45.2342 ++              chars += 1;
 45.2343 ++              *s++ = mbc[0];
 45.2344 ++            }
 45.2345 ++          break;
 45.2346 ++
 45.2347 ++        case 0:
 45.2348 ++          mblength = 1;
 45.2349 ++                /* Fall through */
 45.2350 ++
 45.2351 ++        default:
 45.2352 ++          if (memcmp (mbc, input_tab_char, mblength) == 0)
 45.2353 ++            chars_per_c = chars_per_input_tab;
 45.2354 ++
 45.2355 ++          if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t')
 45.2356 ++            {
 45.2357 ++              int  width_inc;
 45.2358 ++
 45.2359 ++              width_inc = TAB_WIDTH (chars_per_c, input_position);
 45.2360 ++              width += width_inc;
 45.2361 ++
 45.2362 ++              if (untabify_input)
 45.2363 ++                {
 45.2364 ++                  for (i = width_inc; i; --i)
 45.2365 ++                    *s++ = ' ';
 45.2366 ++                  chars += width_inc;
 45.2367 ++                }
 45.2368 ++              else
 45.2369 ++                {
 45.2370 ++                  for (i = 0; i <  mblength; i++)
 45.2371 ++                    *s++ = mbc[i];
 45.2372 ++                  chars += mblength;
 45.2373 ++                }
 45.2374 ++            }
 45.2375 ++          else if ((wc_width = wcwidth (wc)) < 1)
 45.2376 ++            {
 45.2377 ++              if (use_esc_sequence)
 45.2378 ++                {
 45.2379 ++                  for (i = 0; i < mblength; i++)
 45.2380 ++                    {
 45.2381 ++                      width += 4;
 45.2382 ++                      chars += 4;
 45.2383 ++                      *s++ = '\\';
 45.2384 ++                      sprintf (esc_buff, "%03o", (unsigned char) mbc[i]);
 45.2385 ++                      for (j = 0; j <= 2; ++j)
 45.2386 ++                        *s++ = (int) esc_buff[j];
 45.2387 ++                    }
 45.2388 ++                }
 45.2389 ++              else if (use_cntrl_prefix)
 45.2390 ++                {
 45.2391 ++                  if (wc < 0200)
 45.2392 ++                    {
 45.2393 ++                      width += 2;
 45.2394 ++                      chars += 2;
 45.2395 ++                      *s++ = '^';
 45.2396 ++                      *s++ = wc ^ 0100;
 45.2397 ++                    }
 45.2398 ++                  else
 45.2399 ++                    {
 45.2400 ++                      for (i = 0; i < mblength; i++)
 45.2401 ++                        {
 45.2402 ++                          width += 4;
 45.2403 ++                          chars += 4;
 45.2404 ++                          *s++ = '\\';
 45.2405 ++                          sprintf (esc_buff, "%03o", (unsigned char) mbc[i]);
 45.2406 ++                          for (j = 0; j <= 2; ++j)
 45.2407 ++                            *s++ = (int) esc_buff[j];
 45.2408 ++                        }
 45.2409 ++                    }
 45.2410 ++                }
 45.2411 ++              else if (wc == L'\b')
 45.2412 ++                {
 45.2413 ++                  width += -1;
 45.2414 ++                  chars += 1;
 45.2415 ++                  *s++ = c;
 45.2416 ++                }
 45.2417 ++              else
 45.2418 ++                {
 45.2419 ++                  width += 0;
 45.2420 ++                  chars += mblength;
 45.2421 ++                  for (i = 0; i < mblength; i++)
 45.2422 ++                    *s++ = mbc[i];
 45.2423 ++                }
 45.2424 ++            }
 45.2425 ++          else
 45.2426 ++            {
 45.2427 ++              width += wc_width;
 45.2428 ++              chars += mblength;
 45.2429 ++              for (i = 0; i < mblength; i++)
 45.2430 ++                *s++ = mbc[i];
 45.2431 ++            }
 45.2432 ++        }
 45.2433 ++      memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength);
 45.2434 ++      mbc_pos -= mblength;
 45.2435 ++    }
 45.2436 ++
 45.2437 ++  /* Too many backspaces must put us in position 0 -- never negative. */
 45.2438 ++  if (width < 0 && input_position == 0)
 45.2439 ++    {
 45.2440 ++      chars = 0;
 45.2441 ++      input_position = 0;
 45.2442 ++    }
 45.2443 ++  else if (width < 0 && input_position <= -width)
 45.2444 ++    input_position = 0;
 45.2445 ++  else
 45.2446 ++   input_position += width;
 45.2447 ++
 45.2448 ++  return chars;
 45.2449 ++}
 45.2450 ++#endif
 45.2451 ++
 45.2452 + /* We've just printed some files and need to clean up things before
 45.2453 +    looking for more options and printing the next batch of files.
 45.2454 + 
 45.2455 +diff -Naurp coreutils-8.25-orig/src/sort.c coreutils-8.25/src/sort.c
 45.2456 +--- coreutils-8.25-orig/src/sort.c	2016-01-16 13:09:33.000000000 -0600
 45.2457 ++++ coreutils-8.25/src/sort.c	2016-02-08 19:07:10.310944648 -0600
 45.2458 +@@ -29,6 +29,14 @@
 45.2459 + #include <sys/wait.h>
 45.2460 + #include <signal.h>
 45.2461 + #include <assert.h>
 45.2462 ++#if HAVE_WCHAR_H
 45.2463 ++# include <wchar.h>
 45.2464 ++#endif
 45.2465 ++/* Get isw* functions. */
 45.2466 ++#if HAVE_WCTYPE_H
 45.2467 ++# include <wctype.h>
 45.2468 ++#endif
 45.2469 ++
 45.2470 + #include "system.h"
 45.2471 + #include "argmatch.h"
 45.2472 + #include "error.h"
 45.2473 +@@ -163,14 +171,39 @@ static int decimal_point;
 45.2474 + /* Thousands separator; if -1, then there isn't one.  */
 45.2475 + static int thousands_sep;
 45.2476 + 
 45.2477 ++/* True if -f is specified.  */
 45.2478 ++static bool folding;
 45.2479 ++
 45.2480 + /* Nonzero if the corresponding locales are hard.  */
 45.2481 + static bool hard_LC_COLLATE;
 45.2482 +-#if HAVE_NL_LANGINFO
 45.2483 ++#if HAVE_LANGINFO_CODESET
 45.2484 + static bool hard_LC_TIME;
 45.2485 + #endif
 45.2486 + 
 45.2487 + #define NONZERO(x) ((x) != 0)
 45.2488 + 
 45.2489 ++/* get a multibyte character's byte length. */
 45.2490 ++#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE)                        \
 45.2491 ++  do                                                                        \
 45.2492 ++    {                                                                        \
 45.2493 ++      wchar_t wc;                                                        \
 45.2494 ++      mbstate_t state_bak;                                                \
 45.2495 ++                                                                        \
 45.2496 ++      state_bak = STATE;                                                \
 45.2497 ++      mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE);                        \
 45.2498 ++                                                                        \
 45.2499 ++      switch (MBLENGTH)                                                        \
 45.2500 ++        {                                                                \
 45.2501 ++        case (size_t)-1:                                                \
 45.2502 ++        case (size_t)-2:                                                \
 45.2503 ++          STATE = state_bak;                                                \
 45.2504 ++                /* Fall through. */                                        \
 45.2505 ++        case 0:                                                                \
 45.2506 ++          MBLENGTH = 1;                                                        \
 45.2507 ++      }                                                                        \
 45.2508 ++    }                                                                        \
 45.2509 ++  while (0)
 45.2510 ++
 45.2511 + /* The kind of blanks for '-b' to skip in various options. */
 45.2512 + enum blanktype { bl_start, bl_end, bl_both };
 45.2513 + 
 45.2514 +@@ -344,13 +377,11 @@ static bool reverse;
 45.2515 +    they were read if all keys compare equal.  */
 45.2516 + static bool stable;
 45.2517 + 
 45.2518 +-/* If TAB has this value, blanks separate fields.  */
 45.2519 +-enum { TAB_DEFAULT = CHAR_MAX + 1 };
 45.2520 +-
 45.2521 +-/* Tab character separating fields.  If TAB_DEFAULT, then fields are
 45.2522 ++/* Tab character separating fields.  If tab_length is 0, then fields are
 45.2523 +    separated by the empty string between a non-blank character and a blank
 45.2524 +    character. */
 45.2525 +-static int tab = TAB_DEFAULT;
 45.2526 ++static char tab[MB_LEN_MAX + 1];
 45.2527 ++static size_t tab_length = 0;
 45.2528 + 
 45.2529 + /* Flag to remove consecutive duplicate lines from the output.
 45.2530 +    Only the last of a sequence of equal lines will be output. */
 45.2531 +@@ -810,6 +841,46 @@ reap_all (void)
 45.2532 +     reap (-1);
 45.2533 + }
 45.2534 + 
 45.2535 ++/* Function pointers. */
 45.2536 ++static void
 45.2537 ++(*inittables) (void);
 45.2538 ++static char *
 45.2539 ++(*begfield) (const struct line*, const struct keyfield *);
 45.2540 ++static char *
 45.2541 ++(*limfield) (const struct line*, const struct keyfield *);
 45.2542 ++static void
 45.2543 ++(*skipblanks) (char **ptr, char *lim);
 45.2544 ++static int
 45.2545 ++(*getmonth) (char const *, size_t, char **);
 45.2546 ++static int
 45.2547 ++(*keycompare) (const struct line *, const struct line *);
 45.2548 ++static int
 45.2549 ++(*numcompare) (const char *, const char *);
 45.2550 ++
 45.2551 ++/* Test for white space multibyte character.
 45.2552 ++   Set LENGTH the byte length of investigated multibyte character. */
 45.2553 ++#if HAVE_MBRTOWC
 45.2554 ++static int
 45.2555 ++ismbblank (const char *str, size_t len, size_t *length)
 45.2556 ++{
 45.2557 ++  size_t mblength;
 45.2558 ++  wchar_t wc;
 45.2559 ++  mbstate_t state;
 45.2560 ++
 45.2561 ++  memset (&state, '\0', sizeof(mbstate_t));
 45.2562 ++  mblength = mbrtowc (&wc, str, len, &state);
 45.2563 ++
 45.2564 ++  if (mblength == (size_t)-1 || mblength == (size_t)-2)
 45.2565 ++    {
 45.2566 ++      *length = 1;
 45.2567 ++      return 0;
 45.2568 ++    }
 45.2569 ++
 45.2570 ++  *length = (mblength < 1) ? 1 : mblength;
 45.2571 ++  return iswblank (wc) || wc == '\n';
 45.2572 ++}
 45.2573 ++#endif
 45.2574 ++
 45.2575 + /* Clean up any remaining temporary files.  */
 45.2576 + 
 45.2577 + static void
 45.2578 +@@ -1254,7 +1325,7 @@ zaptemp (char const *name)
 45.2579 +   free (node);
 45.2580 + }
 45.2581 + 
 45.2582 +-#if HAVE_NL_LANGINFO
 45.2583 ++#if HAVE_LANGINFO_CODESET
 45.2584 + 
 45.2585 + static int
 45.2586 + struct_month_cmp (void const *m1, void const *m2)
 45.2587 +@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void c
 45.2588 + /* Initialize the character class tables. */
 45.2589 + 
 45.2590 + static void
 45.2591 +-inittables (void)
 45.2592 ++inittables_uni (void)
 45.2593 + {
 45.2594 +   size_t i;
 45.2595 + 
 45.2596 +@@ -1281,7 +1352,7 @@ inittables (void)
 45.2597 +       fold_toupper[i] = toupper (i);
 45.2598 +     }
 45.2599 + 
 45.2600 +-#if HAVE_NL_LANGINFO
 45.2601 ++#if HAVE_LANGINFO_CODESET
 45.2602 +   /* If we're not in the "C" locale, read different names for months.  */
 45.2603 +   if (hard_LC_TIME)
 45.2604 +     {
 45.2605 +@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char con
 45.2606 +     xstrtol_fatal (e, oi, c, long_options, s);
 45.2607 + }
 45.2608 + 
 45.2609 ++#if HAVE_MBRTOWC
 45.2610 ++static void
 45.2611 ++inittables_mb (void)
 45.2612 ++{
 45.2613 ++  int i, j, k, l;
 45.2614 ++  char *name, *s, *lc_time, *lc_ctype;
 45.2615 ++  size_t s_len, mblength;
 45.2616 ++  char mbc[MB_LEN_MAX];
 45.2617 ++  wchar_t wc, pwc;
 45.2618 ++  mbstate_t state_mb, state_wc;
 45.2619 ++
 45.2620 ++  lc_time = setlocale (LC_TIME, "");
 45.2621 ++  if (lc_time)
 45.2622 ++    lc_time = xstrdup (lc_time);
 45.2623 ++
 45.2624 ++  lc_ctype = setlocale (LC_CTYPE, "");
 45.2625 ++  if (lc_ctype)
 45.2626 ++    lc_ctype = xstrdup (lc_ctype);
 45.2627 ++
 45.2628 ++  if (lc_time && lc_ctype)
 45.2629 ++    /* temporarily set LC_CTYPE to match LC_TIME, so that we can convert
 45.2630 ++     * the names of months to upper case */
 45.2631 ++    setlocale (LC_CTYPE, lc_time);
 45.2632 ++
 45.2633 ++  for (i = 0; i < MONTHS_PER_YEAR; i++)
 45.2634 ++    {
 45.2635 ++      s = (char *) nl_langinfo (ABMON_1 + i);
 45.2636 ++      s_len = strlen (s);
 45.2637 ++      monthtab[i].name = name = (char *) xmalloc (s_len + 1);
 45.2638 ++      monthtab[i].val = i + 1;
 45.2639 ++
 45.2640 ++      memset (&state_mb, '\0', sizeof (mbstate_t));
 45.2641 ++      memset (&state_wc, '\0', sizeof (mbstate_t));
 45.2642 ++
 45.2643 ++      for (j = 0; j < s_len;)
 45.2644 ++        {
 45.2645 ++          if (!ismbblank (s + j, s_len - j, &mblength))
 45.2646 ++            break;
 45.2647 ++          j += mblength;
 45.2648 ++        }
 45.2649 ++
 45.2650 ++      for (k = 0; j < s_len;)
 45.2651 ++        {
 45.2652 ++          mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb);
 45.2653 ++          assert (mblength != (size_t)-1 && mblength != (size_t)-2);
 45.2654 ++          if (mblength == 0)
 45.2655 ++            break;
 45.2656 ++
 45.2657 ++          pwc = towupper (wc);
 45.2658 ++          if (pwc == wc)
 45.2659 ++            {
 45.2660 ++              memcpy (mbc, s + j, mblength);
 45.2661 ++              j += mblength;
 45.2662 ++            }
 45.2663 ++          else
 45.2664 ++            {
 45.2665 ++              j += mblength;
 45.2666 ++              mblength = wcrtomb (mbc, pwc, &state_wc);
 45.2667 ++              assert (mblength != (size_t)0 && mblength != (size_t)-1);
 45.2668 ++            }
 45.2669 ++
 45.2670 ++          for (l = 0; l < mblength; l++)
 45.2671 ++            name[k++] = mbc[l];
 45.2672 ++        }
 45.2673 ++      name[k] = '\0';
 45.2674 ++    }
 45.2675 ++  qsort ((void *) monthtab, MONTHS_PER_YEAR,
 45.2676 ++      sizeof (struct month), struct_month_cmp);
 45.2677 ++
 45.2678 ++  if (lc_time && lc_ctype)
 45.2679 ++    /* restore the original locales */
 45.2680 ++    setlocale (LC_CTYPE, lc_ctype);
 45.2681 ++
 45.2682 ++  free (lc_ctype);
 45.2683 ++  free (lc_time);
 45.2684 ++}
 45.2685 ++#endif
 45.2686 ++
 45.2687 + /* Specify the amount of main memory to use when sorting.  */
 45.2688 + static void
 45.2689 + specify_sort_size (int oi, char c, char const *s)
 45.2690 +@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf
 45.2691 +    by KEY in LINE. */
 45.2692 + 
 45.2693 + static char *
 45.2694 +-begfield (struct line const *line, struct keyfield const *key)
 45.2695 ++begfield_uni (const struct line *line, const struct keyfield *key)
 45.2696 + {
 45.2697 +   char *ptr = line->text, *lim = ptr + line->length - 1;
 45.2698 +   size_t sword = key->sword;
 45.2699 +@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struc
 45.2700 +   /* The leading field separator itself is included in a field when -t
 45.2701 +      is absent.  */
 45.2702 + 
 45.2703 +-  if (tab != TAB_DEFAULT)
 45.2704 ++  if (tab_length)
 45.2705 +     while (ptr < lim && sword--)
 45.2706 +       {
 45.2707 +-        while (ptr < lim && *ptr != tab)
 45.2708 ++        while (ptr < lim && *ptr != tab[0])
 45.2709 +           ++ptr;
 45.2710 +         if (ptr < lim)
 45.2711 +           ++ptr;
 45.2712 +@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struc
 45.2713 +   return ptr;
 45.2714 + }
 45.2715 + 
 45.2716 ++#if HAVE_MBRTOWC
 45.2717 ++static char *
 45.2718 ++begfield_mb (const struct line *line, const struct keyfield *key)
 45.2719 ++{
 45.2720 ++  int i;
 45.2721 ++  char *ptr = line->text, *lim = ptr + line->length - 1;
 45.2722 ++  size_t sword = key->sword;
 45.2723 ++  size_t schar = key->schar;
 45.2724 ++  size_t mblength;
 45.2725 ++  mbstate_t state;
 45.2726 ++
 45.2727 ++  memset (&state, '\0', sizeof(mbstate_t));
 45.2728 ++
 45.2729 ++  if (tab_length)
 45.2730 ++    while (ptr < lim && sword--)
 45.2731 ++      {
 45.2732 ++        while (ptr < lim && memcmp (ptr, tab, tab_length) != 0)
 45.2733 ++          {
 45.2734 ++            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 45.2735 ++            ptr += mblength;
 45.2736 ++          }
 45.2737 ++        if (ptr < lim)
 45.2738 ++          {
 45.2739 ++            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 45.2740 ++            ptr += mblength;
 45.2741 ++          }
 45.2742 ++      }
 45.2743 ++  else
 45.2744 ++    while (ptr < lim && sword--)
 45.2745 ++      {
 45.2746 ++        while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
 45.2747 ++          ptr += mblength;
 45.2748 ++        if (ptr < lim)
 45.2749 ++          {
 45.2750 ++            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 45.2751 ++            ptr += mblength;
 45.2752 ++          }
 45.2753 ++        while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength))
 45.2754 ++          ptr += mblength;
 45.2755 ++      }
 45.2756 ++
 45.2757 ++  if (key->skipsblanks)
 45.2758 ++    while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
 45.2759 ++      ptr += mblength;
 45.2760 ++
 45.2761 ++  for (i = 0; i < schar; i++)
 45.2762 ++    {
 45.2763 ++      GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 45.2764 ++
 45.2765 ++      if (ptr + mblength > lim)
 45.2766 ++        break;
 45.2767 ++      else
 45.2768 ++        ptr += mblength;
 45.2769 ++    }
 45.2770 ++
 45.2771 ++  return ptr;
 45.2772 ++}
 45.2773 ++#endif
 45.2774 ++
 45.2775 + /* Return the limit of (a pointer to the first character after) the field
 45.2776 +    in LINE specified by KEY. */
 45.2777 + 
 45.2778 + static char *
 45.2779 +-limfield (struct line const *line, struct keyfield const *key)
 45.2780 ++limfield_uni (const struct line *line, const struct keyfield *key)
 45.2781 + {
 45.2782 +   char *ptr = line->text, *lim = ptr + line->length - 1;
 45.2783 +   size_t eword = key->eword, echar = key->echar;
 45.2784 +@@ -1653,10 +1861,10 @@ limfield (struct line const *line, struc
 45.2785 +      'beginning' is the first character following the delimiting TAB.
 45.2786 +      Otherwise, leave PTR pointing at the first 'blank' character after
 45.2787 +      the preceding field.  */
 45.2788 +-  if (tab != TAB_DEFAULT)
 45.2789 ++  if (tab_length)
 45.2790 +     while (ptr < lim && eword--)
 45.2791 +       {
 45.2792 +-        while (ptr < lim && *ptr != tab)
 45.2793 ++        while (ptr < lim && *ptr != tab[0])
 45.2794 +           ++ptr;
 45.2795 +         if (ptr < lim && (eword || echar))
 45.2796 +           ++ptr;
 45.2797 +@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struc
 45.2798 +      */
 45.2799 + 
 45.2800 +   /* Make LIM point to the end of (one byte past) the current field.  */
 45.2801 +-  if (tab != TAB_DEFAULT)
 45.2802 ++  if (tab_length)
 45.2803 +     {
 45.2804 +       char *newlim;
 45.2805 +-      newlim = memchr (ptr, tab, lim - ptr);
 45.2806 ++      newlim = memchr (ptr, tab[0], lim - ptr);
 45.2807 +       if (newlim)
 45.2808 +         lim = newlim;
 45.2809 +     }
 45.2810 +@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struc
 45.2811 +   return ptr;
 45.2812 + }
 45.2813 + 
 45.2814 ++#if HAVE_MBRTOWC
 45.2815 ++static char *
 45.2816 ++limfield_mb (const struct line *line, const struct keyfield *key)
 45.2817 ++{
 45.2818 ++  char *ptr = line->text, *lim = ptr + line->length - 1;
 45.2819 ++  size_t eword = key->eword, echar = key->echar;
 45.2820 ++  int i;
 45.2821 ++  size_t mblength;
 45.2822 ++  mbstate_t state;
 45.2823 ++
 45.2824 ++  if (echar == 0)
 45.2825 ++    eword++; /* skip all of end field. */
 45.2826 ++
 45.2827 ++  memset (&state, '\0', sizeof(mbstate_t));
 45.2828 ++
 45.2829 ++  if (tab_length)
 45.2830 ++    while (ptr < lim && eword--)
 45.2831 ++      {
 45.2832 ++        while (ptr < lim && memcmp (ptr, tab, tab_length) != 0)
 45.2833 ++          {
 45.2834 ++            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 45.2835 ++            ptr += mblength;
 45.2836 ++          }
 45.2837 ++        if (ptr < lim && (eword | echar))
 45.2838 ++          {
 45.2839 ++            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 45.2840 ++            ptr += mblength;
 45.2841 ++          }
 45.2842 ++      }
 45.2843 ++  else
 45.2844 ++    while (ptr < lim && eword--)
 45.2845 ++      {
 45.2846 ++        while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
 45.2847 ++          ptr += mblength;
 45.2848 ++        if (ptr < lim)
 45.2849 ++          {
 45.2850 ++            GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 45.2851 ++            ptr += mblength;
 45.2852 ++          }
 45.2853 ++        while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength))
 45.2854 ++          ptr += mblength;
 45.2855 ++      }
 45.2856 ++
 45.2857 ++
 45.2858 ++# ifdef POSIX_UNSPECIFIED
 45.2859 ++  /* Make LIM point to the end of (one byte past) the current field.  */
 45.2860 ++  if (tab_length)
 45.2861 ++    {
 45.2862 ++      char *newlim, *p;
 45.2863 ++
 45.2864 ++      newlim = NULL;
 45.2865 ++      for (p = ptr; p < lim;)
 45.2866 ++         {
 45.2867 ++          if (memcmp (p, tab, tab_length) == 0)
 45.2868 ++            {
 45.2869 ++              newlim = p;
 45.2870 ++              break;
 45.2871 ++            }
 45.2872 ++
 45.2873 ++          GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 45.2874 ++          p += mblength;
 45.2875 ++        }
 45.2876 ++    }
 45.2877 ++  else
 45.2878 ++    {
 45.2879 ++      char *newlim;
 45.2880 ++      newlim = ptr;
 45.2881 ++
 45.2882 ++      while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength))
 45.2883 ++        newlim += mblength;
 45.2884 ++      if (ptr < lim)
 45.2885 ++        {
 45.2886 ++          GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 45.2887 ++          ptr += mblength;
 45.2888 ++        }
 45.2889 ++      while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength))
 45.2890 ++        newlim += mblength;
 45.2891 ++      lim = newlim;
 45.2892 ++    }
 45.2893 ++# endif
 45.2894 ++
 45.2895 ++  if (echar != 0)
 45.2896 ++  {
 45.2897 ++    /* If we're skipping leading blanks, don't start counting characters
 45.2898 ++     *      until after skipping past any leading blanks.  */
 45.2899 ++    if (key->skipeblanks)
 45.2900 ++      while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
 45.2901 ++        ptr += mblength;
 45.2902 ++
 45.2903 ++    memset (&state, '\0', sizeof(mbstate_t));
 45.2904 ++
 45.2905 ++    /* Advance PTR by ECHAR (if possible), but no further than LIM.  */
 45.2906 ++    for (i = 0; i < echar; i++)
 45.2907 ++     {
 45.2908 ++        GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
 45.2909 ++
 45.2910 ++        if (ptr + mblength > lim)
 45.2911 ++          break;
 45.2912 ++        else
 45.2913 ++          ptr += mblength;
 45.2914 ++      }
 45.2915 ++  }
 45.2916 ++
 45.2917 ++  return ptr;
 45.2918 ++}
 45.2919 ++#endif
 45.2920 ++
 45.2921 ++static void
 45.2922 ++skipblanks_uni (char **ptr, char *lim)
 45.2923 ++{
 45.2924 ++  while (*ptr < lim && blanks[to_uchar (**ptr)])
 45.2925 ++    ++(*ptr);
 45.2926 ++}
 45.2927 ++
 45.2928 ++#if HAVE_MBRTOWC
 45.2929 ++static void
 45.2930 ++skipblanks_mb (char **ptr, char *lim)
 45.2931 ++{
 45.2932 ++  size_t mblength;
 45.2933 ++  while (*ptr < lim && ismbblank (*ptr, lim - *ptr, &mblength))
 45.2934 ++    (*ptr) += mblength;
 45.2935 ++}
 45.2936 ++#endif
 45.2937 ++
 45.2938 + /* Fill BUF reading from FP, moving buf->left bytes from the end
 45.2939 +    of buf->buf to the beginning first.  If EOF is reached and the
 45.2940 +    file wasn't terminated by a newline, supply one.  Set up BUF's line
 45.2941 +@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, c
 45.2942 +                   else
 45.2943 +                     {
 45.2944 +                       if (key->skipsblanks)
 45.2945 +-                        while (blanks[to_uchar (*line_start)])
 45.2946 +-                          line_start++;
 45.2947 ++                        {
 45.2948 ++#if HAVE_MBRTOWC
 45.2949 ++                          if (MB_CUR_MAX > 1)
 45.2950 ++                            {
 45.2951 ++                              size_t mblength;
 45.2952 ++                              while (line_start < line->keylim &&
 45.2953 ++                                     ismbblank (line_start,
 45.2954 ++                                                line->keylim - line_start,
 45.2955 ++                                                &mblength))
 45.2956 ++                                line_start += mblength;
 45.2957 ++                            }
 45.2958 ++                          else
 45.2959 ++#endif
 45.2960 ++                          while (blanks[to_uchar (*line_start)])
 45.2961 ++                            line_start++;
 45.2962 ++                        }
 45.2963 +                       line->keybeg = line_start;
 45.2964 +                     }
 45.2965 +                 }
 45.2966 +@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char co
 45.2967 +    hideously fast. */
 45.2968 + 
 45.2969 + static int
 45.2970 +-numcompare (char const *a, char const *b)
 45.2971 ++numcompare_uni (const char *a, const char *b)
 45.2972 + {
 45.2973 +   while (blanks[to_uchar (*a)])
 45.2974 +     a++;
 45.2975 +@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b
 45.2976 +   return strnumcmp (a, b, decimal_point, thousands_sep);
 45.2977 + }
 45.2978 + 
 45.2979 ++#if HAVE_MBRTOWC
 45.2980 ++static int
 45.2981 ++numcompare_mb (const char *a, const char *b)
 45.2982 ++{
 45.2983 ++  size_t mblength, len;
 45.2984 ++  len = strlen (a); /* okay for UTF-8 */
 45.2985 ++  while (*a && ismbblank (a, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength))
 45.2986 ++    {
 45.2987 ++      a += mblength;
 45.2988 ++      len -= mblength;
 45.2989 ++    }
 45.2990 ++  len = strlen (b); /* okay for UTF-8 */
 45.2991 ++  while (*b && ismbblank (b, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength))
 45.2992 ++    b += mblength;
 45.2993 ++
 45.2994 ++  return strnumcmp (a, b, decimal_point, thousands_sep);
 45.2995 ++}
 45.2996 ++#endif /* HAV_EMBRTOWC */
 45.2997 ++
 45.2998 + /* Work around a problem whereby the long double value returned by glibc's
 45.2999 +    strtold ("NaN", ...) contains uninitialized bits: clear all bytes of
 45.3000 +    A and B before calling strtold.  FIXME: remove this function once
 45.3001 +@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char
 45.3002 +    Return 0 if the name in S is not recognized.  */
 45.3003 + 
 45.3004 + static int
 45.3005 +-getmonth (char const *month, char **ea)
 45.3006 ++getmonth_uni (char const *month, size_t len, char **ea)
 45.3007 + {
 45.3008 +   size_t lo = 0;
 45.3009 +   size_t hi = MONTHS_PER_YEAR;
 45.3010 +@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, stru
 45.3011 +           char saved = *lim;
 45.3012 +           *lim = '\0';
 45.3013 + 
 45.3014 +-          while (blanks[to_uchar (*beg)])
 45.3015 +-            beg++;
 45.3016 ++          skipblanks (&beg, lim);
 45.3017 + 
 45.3018 +           char *tighter_lim = beg;
 45.3019 + 
 45.3020 +           if (lim < beg)
 45.3021 +             tighter_lim = lim;
 45.3022 +           else if (key->month)
 45.3023 +-            getmonth (beg, &tighter_lim);
 45.3024 ++            getmonth (beg, lim-beg, &tighter_lim);
 45.3025 +           else if (key->general_numeric)
 45.3026 +             ignore_value (strtold (beg, &tighter_lim));
 45.3027 +           else if (key->numeric || key->human_numeric)
 45.3028 +@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gke
 45.3029 +       bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key)
 45.3030 +                                  && !(key->schar || key->echar);
 45.3031 +       bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y  */
 45.3032 +-      if (!gkey_only && tab == TAB_DEFAULT && !line_offset
 45.3033 ++      if (!gkey_only && !tab_length && !line_offset
 45.3034 +           && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned))
 45.3035 +               || (!key->skipsblanks && key->schar)
 45.3036 +               || (!key->skipeblanks && key->echar)))
 45.3037 +@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gke
 45.3038 +     error (0, 0, _("option '-r' only applies to last-resort comparison"));
 45.3039 + }
 45.3040 + 
 45.3041 ++#if HAVE_MBRTOWC
 45.3042 ++static int
 45.3043 ++getmonth_mb (const char *s, size_t len, char **ea)
 45.3044 ++{
 45.3045 ++  char *month;
 45.3046 ++  register size_t i;
 45.3047 ++  register int lo = 0, hi = MONTHS_PER_YEAR, result;
 45.3048 ++  char *tmp;
 45.3049 ++  size_t wclength, mblength;
 45.3050 ++  const char *pp;
 45.3051 ++  const wchar_t *wpp;
 45.3052 ++  wchar_t *month_wcs;
 45.3053 ++  mbstate_t state;
 45.3054 ++
 45.3055 ++  while (len > 0 && ismbblank (s, len, &mblength))
 45.3056 ++    {
 45.3057 ++      s += mblength;
 45.3058 ++      len -= mblength;
 45.3059 ++    }
 45.3060 ++
 45.3061 ++  if (len == 0)
 45.3062 ++    return 0;
 45.3063 ++
 45.3064 ++  if (SIZE_MAX - len < 1)
 45.3065 ++    xalloc_die ();
 45.3066 ++
 45.3067 ++  month = (char *) xnmalloc (len + 1, MB_CUR_MAX);
 45.3068 ++
 45.3069 ++  pp = tmp = (char *) xnmalloc (len + 1, MB_CUR_MAX);
 45.3070 ++  memcpy (tmp, s, len);
 45.3071 ++  tmp[len] = '\0';
 45.3072 ++  wpp = month_wcs = (wchar_t *) xnmalloc (len + 1, sizeof (wchar_t));
 45.3073 ++  memset (&state, '\0', sizeof (mbstate_t));
 45.3074 ++
 45.3075 ++  wclength = mbsrtowcs (month_wcs, &pp, len + 1, &state);
 45.3076 ++  if (wclength == (size_t)-1 || pp != NULL)
 45.3077 ++    error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s));
 45.3078 ++
 45.3079 ++  for (i = 0; i < wclength; i++)
 45.3080 ++    {
 45.3081 ++      month_wcs[i] = towupper(month_wcs[i]);
 45.3082 ++      if (iswblank (month_wcs[i]))
 45.3083 ++        {
 45.3084 ++          month_wcs[i] = L'\0';
 45.3085 ++          break;
 45.3086 ++        }
 45.3087 ++    }
 45.3088 ++
 45.3089 ++  mblength = wcsrtombs (month, &wpp, (len + 1) * MB_CUR_MAX, &state);
 45.3090 ++  assert (mblength != (-1) && wpp == NULL);
 45.3091 ++
 45.3092 ++  do
 45.3093 ++    {
 45.3094 ++      int ix = (lo + hi) / 2;
 45.3095 ++
 45.3096 ++      if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0)
 45.3097 ++        hi = ix;
 45.3098 ++      else
 45.3099 ++        lo = ix;
 45.3100 ++    }
 45.3101 ++  while (hi - lo > 1);
 45.3102 ++
 45.3103 ++  result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name))
 45.3104 ++      ? monthtab[lo].val : 0);
 45.3105 ++
 45.3106 ++  if (ea && result)
 45.3107 ++     *ea = (char*) s + strlen (monthtab[lo].name);
 45.3108 ++
 45.3109 ++  free (month);
 45.3110 ++  free (tmp);
 45.3111 ++  free (month_wcs);
 45.3112 ++
 45.3113 ++  return result;
 45.3114 ++}
 45.3115 ++#endif
 45.3116 ++
 45.3117 + /* Compare two lines A and B trying every key in sequence until there
 45.3118 +    are no more keys or a difference is found. */
 45.3119 + 
 45.3120 + static int
 45.3121 +-keycompare (struct line const *a, struct line const *b)
 45.3122 ++keycompare_uni (const struct line *a, const struct line *b)
 45.3123 + {
 45.3124 +   struct keyfield *key = keylist;
 45.3125 + 
 45.3126 +@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct
 45.3127 +           else if (key->human_numeric)
 45.3128 +             diff = human_numcompare (ta, tb);
 45.3129 +           else if (key->month)
 45.3130 +-            diff = getmonth (ta, NULL) - getmonth (tb, NULL);
 45.3131 ++            diff = getmonth (ta, tlena, NULL) - getmonth (tb, tlenb, NULL);
 45.3132 +           else if (key->random)
 45.3133 +             diff = compare_random (ta, tlena, tb, tlenb);
 45.3134 +           else if (key->version)
 45.3135 +@@ -2695,6 +3135,211 @@ keycompare (struct line const *a, struct
 45.3136 +   return key->reverse ? -diff : diff;
 45.3137 + }
 45.3138 + 
 45.3139 ++#if HAVE_MBRTOWC
 45.3140 ++static int
 45.3141 ++keycompare_mb (const struct line *a, const struct line *b)
 45.3142 ++{
 45.3143 ++  struct keyfield *key = keylist;
 45.3144 ++
 45.3145 ++  /* For the first iteration only, the key positions have been
 45.3146 ++     precomputed for us. */
 45.3147 ++  char *texta = a->keybeg;
 45.3148 ++  char *textb = b->keybeg;
 45.3149 ++  char *lima = a->keylim;
 45.3150 ++  char *limb = b->keylim;
 45.3151 ++
 45.3152 ++  size_t mblength_a, mblength_b;
 45.3153 ++  wchar_t wc_a, wc_b;
 45.3154 ++  mbstate_t state_a, state_b;
 45.3155 ++
 45.3156 ++  int diff = 0;
 45.3157 ++
 45.3158 ++  memset (&state_a, '\0', sizeof(mbstate_t));
 45.3159 ++  memset (&state_b, '\0', sizeof(mbstate_t));
 45.3160 ++  /* Ignore keys with start after end.  */
 45.3161 ++  if (a->keybeg - a->keylim > 0)
 45.3162 ++    return 0;
 45.3163 ++
 45.3164 ++
 45.3165 ++              /* Ignore and/or translate chars before comparing.  */
 45.3166 ++# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE)        \
 45.3167 ++  do                                                                        \
 45.3168 ++    {                                                                        \
 45.3169 ++      wchar_t uwc;                                                        \
 45.3170 ++      char mbc[MB_LEN_MAX];                                                \
 45.3171 ++      mbstate_t state_wc;                                                \
 45.3172 ++                                                                        \
 45.3173 ++      for (NEW_LEN = i = 0; i < LEN;)                                        \
 45.3174 ++        {                                                                \
 45.3175 ++          mbstate_t state_bak;                                                \
 45.3176 ++                                                                        \
 45.3177 ++          state_bak = STATE;                                                \
 45.3178 ++          MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE);                \
 45.3179 ++                                                                        \
 45.3180 ++          if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1                \
 45.3181 ++              || MBLENGTH == 0)                                                \
 45.3182 ++            {                                                                \
 45.3183 ++              if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1)        \
 45.3184 ++                STATE = state_bak;                                        \
 45.3185 ++              if (!ignore)                                                \
 45.3186 ++                COPY[NEW_LEN++] = TEXT[i];                                \
 45.3187 ++              i++;                                                         \
 45.3188 ++              continue;                                                        \
 45.3189 ++            }                                                                \
 45.3190 ++                                                                        \
 45.3191 ++          if (ignore)                                                        \
 45.3192 ++            {                                                                \
 45.3193 ++              if ((ignore == nonprinting && !iswprint (WC))                \
 45.3194 ++                   || (ignore == nondictionary                                \
 45.3195 ++                       && !iswalnum (WC) && !iswblank (WC)))                \
 45.3196 ++                {                                                        \
 45.3197 ++                  i += MBLENGTH;                                        \
 45.3198 ++                  continue;                                                \
 45.3199 ++                }                                                        \
 45.3200 ++            }                                                                \
 45.3201 ++                                                                        \
 45.3202 ++          if (translate)                                                \
 45.3203 ++            {                                                                \
 45.3204 ++                                                                        \
 45.3205 ++              uwc = towupper(WC);                                        \
 45.3206 ++              if (WC == uwc)                                                \
 45.3207 ++                {                                                        \
 45.3208 ++                  memcpy (mbc, TEXT + i, MBLENGTH);                        \
 45.3209 ++                  i += MBLENGTH;                                        \
 45.3210 ++                }                                                        \
 45.3211 ++              else                                                        \
 45.3212 ++                {                                                        \
 45.3213 ++                  i += MBLENGTH;                                        \
 45.3214 ++                  WC = uwc;                                                \
 45.3215 ++                  memset (&state_wc, '\0', sizeof (mbstate_t));                \
 45.3216 ++                                                                        \
 45.3217 ++                  MBLENGTH = wcrtomb (mbc, WC, &state_wc);                \
 45.3218 ++                  assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0);        \
 45.3219 ++                }                                                        \
 45.3220 ++                                                                        \
 45.3221 ++              for (j = 0; j < MBLENGTH; j++)                                \
 45.3222 ++                COPY[NEW_LEN++] = mbc[j];                                \
 45.3223 ++            }                                                                \
 45.3224 ++          else                                                                \
 45.3225 ++            for (j = 0; j < MBLENGTH; j++)                                \
 45.3226 ++              COPY[NEW_LEN++] = TEXT[i++];                                \
 45.3227 ++        }                                                                \
 45.3228 ++      COPY[NEW_LEN] = '\0';                                                \
 45.3229 ++    }                                                                        \
 45.3230 ++  while (0)
 45.3231 ++
 45.3232 ++      /* Actually compare the fields. */
 45.3233 ++
 45.3234 ++  for (;;)
 45.3235 ++    {
 45.3236 ++      /* Find the lengths. */
 45.3237 ++      size_t lena = lima <= texta ? 0 : lima - texta;
 45.3238 ++      size_t lenb = limb <= textb ? 0 : limb - textb;
 45.3239 ++
 45.3240 ++      char enda IF_LINT (= 0);
 45.3241 ++      char endb IF_LINT (= 0);
 45.3242 ++
 45.3243 ++      char const *translate = key->translate;
 45.3244 ++      bool const *ignore = key->ignore;
 45.3245 ++
 45.3246 ++      if (ignore || translate)
 45.3247 ++        {
 45.3248 ++          if (SIZE_MAX - lenb - 2 < lena)
 45.3249 ++            xalloc_die ();
 45.3250 ++          char *copy_a = (char *) xnmalloc (lena + lenb + 2, MB_CUR_MAX);
 45.3251 ++          char *copy_b = copy_a + lena * MB_CUR_MAX + 1;
 45.3252 ++          size_t new_len_a, new_len_b;
 45.3253 ++          size_t i, j;
 45.3254 ++
 45.3255 ++          IGNORE_CHARS (new_len_a, lena, texta, copy_a,
 45.3256 ++                        wc_a, mblength_a, state_a);
 45.3257 ++          IGNORE_CHARS (new_len_b, lenb, textb, copy_b,
 45.3258 ++                        wc_b, mblength_b, state_b);
 45.3259 ++          texta = copy_a; textb = copy_b;
 45.3260 ++          lena = new_len_a; lenb = new_len_b;
 45.3261 ++        }
 45.3262 ++      else
 45.3263 ++        {
 45.3264 ++          /* Use the keys in-place, temporarily null-terminated.  */
 45.3265 ++          enda = texta[lena]; texta[lena] = '\0';
 45.3266 ++          endb = textb[lenb]; textb[lenb] = '\0';
 45.3267 ++        }
 45.3268 ++
 45.3269 ++      if (key->random)
 45.3270 ++        diff = compare_random (texta, lena, textb, lenb);
 45.3271 ++      else if (key->numeric | key->general_numeric | key->human_numeric)
 45.3272 ++        {
 45.3273 ++          char savea = *lima, saveb = *limb;
 45.3274 ++
 45.3275 ++          *lima = *limb = '\0';
 45.3276 ++          diff = (key->numeric ? numcompare (texta, textb)
 45.3277 ++                  : key->general_numeric ? general_numcompare (texta, textb)
 45.3278 ++                  : human_numcompare (texta, textb));
 45.3279 ++          *lima = savea, *limb = saveb;
 45.3280 ++        }
 45.3281 ++      else if (key->version)
 45.3282 ++        diff = filevercmp (texta, textb);
 45.3283 ++      else if (key->month)
 45.3284 ++        diff = getmonth (texta, lena, NULL) - getmonth (textb, lenb, NULL);
 45.3285 ++      else if (lena == 0)
 45.3286 ++        diff = - NONZERO (lenb);
 45.3287 ++      else if (lenb == 0)
 45.3288 ++        diff = 1;
 45.3289 ++      else if (hard_LC_COLLATE && !folding)
 45.3290 ++        {
 45.3291 ++          diff = xmemcoll0 (texta, lena + 1, textb, lenb + 1);
 45.3292 ++        }
 45.3293 ++      else
 45.3294 ++        {
 45.3295 ++          diff = memcmp (texta, textb, MIN (lena, lenb));
 45.3296 ++          if (diff == 0)
 45.3297 ++            diff = lena < lenb ? -1 : lena != lenb;
 45.3298 ++        }
 45.3299 ++
 45.3300 ++      if (ignore || translate)
 45.3301 ++        free (texta);
 45.3302 ++      else
 45.3303 ++        {
 45.3304 ++          texta[lena] = enda;
 45.3305 ++          textb[lenb] = endb;
 45.3306 ++        }
 45.3307 ++
 45.3308 ++      if (diff)
 45.3309 ++        goto not_equal;
 45.3310 ++
 45.3311 ++      key = key->next;
 45.3312 ++      if (! key)
 45.3313 ++        break;
 45.3314 ++
 45.3315 ++      /* Find the beginning and limit of the next field.  */
 45.3316 ++      if (key->eword != -1)
 45.3317 ++        lima = limfield (a, key), limb = limfield (b, key);
 45.3318 ++      else
 45.3319 ++        lima = a->text + a->length - 1, limb = b->text + b->length - 1;
 45.3320 ++
 45.3321 ++      if (key->sword != -1)
 45.3322 ++        texta = begfield (a, key), textb = begfield (b, key);
 45.3323 ++      else
 45.3324 ++        {
 45.3325 ++          texta = a->text, textb = b->text;
 45.3326 ++          if (key->skipsblanks)
 45.3327 ++            {
 45.3328 ++              while (texta < lima && ismbblank (texta, lima - texta, &mblength_a))
 45.3329 ++                texta += mblength_a;
 45.3330 ++              while (textb < limb && ismbblank (textb, limb - textb, &mblength_b))
 45.3331 ++                textb += mblength_b;
 45.3332 ++            }
 45.3333 ++        }
 45.3334 ++    }
 45.3335 ++
 45.3336 ++not_equal:
 45.3337 ++  if (key && key->reverse)
 45.3338 ++    return -diff;
 45.3339 ++  else
 45.3340 ++    return diff;
 45.3341 ++}
 45.3342 ++#endif
 45.3343 ++
 45.3344 + /* Compare two lines A and B, returning negative, zero, or positive
 45.3345 +    depending on whether A compares less than, equal to, or greater than B. */
 45.3346 + 
 45.3347 +@@ -2722,7 +3367,7 @@ compare (struct line const *a, struct li
 45.3348 +     diff = - NONZERO (blen);
 45.3349 +   else if (blen == 0)
 45.3350 +     diff = 1;
 45.3351 +-  else if (hard_LC_COLLATE)
 45.3352 ++  else if (hard_LC_COLLATE && !folding)
 45.3353 +     {
 45.3354 +       /* Note xmemcoll0 is a performance enhancement as
 45.3355 +          it will not unconditionally write '\0' after the
 45.3356 +@@ -4121,6 +4766,7 @@ set_ordering (char const *s, struct keyf
 45.3357 +           break;
 45.3358 +         case 'f':
 45.3359 +           key->translate = fold_toupper;
 45.3360 ++          folding = true;
 45.3361 +           break;
 45.3362 +         case 'g':
 45.3363 +           key->general_numeric = true;
 45.3364 +@@ -4199,7 +4845,7 @@ main (int argc, char **argv)
 45.3365 +   initialize_exit_failure (SORT_FAILURE);
 45.3366 + 
 45.3367 +   hard_LC_COLLATE = hard_locale (LC_COLLATE);
 45.3368 +-#if HAVE_NL_LANGINFO
 45.3369 ++#if HAVE_LANGINFO_CODESET
 45.3370 +   hard_LC_TIME = hard_locale (LC_TIME);
 45.3371 + #endif
 45.3372 + 
 45.3373 +@@ -4220,6 +4866,29 @@ main (int argc, char **argv)
 45.3374 +       thousands_sep = -1;
 45.3375 +   }
 45.3376 + 
 45.3377 ++#if HAVE_MBRTOWC
 45.3378 ++  if (MB_CUR_MAX > 1)
 45.3379 ++    {
 45.3380 ++      inittables = inittables_mb;
 45.3381 ++      begfield = begfield_mb;
 45.3382 ++      limfield = limfield_mb;
 45.3383 ++      skipblanks = skipblanks_mb;
 45.3384 ++      getmonth = getmonth_mb;
 45.3385 ++      keycompare = keycompare_mb;
 45.3386 ++      numcompare = numcompare_mb;
 45.3387 ++    }
 45.3388 ++  else
 45.3389 ++#endif
 45.3390 ++    {
 45.3391 ++      inittables = inittables_uni;
 45.3392 ++      begfield = begfield_uni;
 45.3393 ++      limfield = limfield_uni;
 45.3394 ++      skipblanks = skipblanks_uni;
 45.3395 ++      getmonth = getmonth_uni;
 45.3396 ++      keycompare = keycompare_uni;
 45.3397 ++      numcompare = numcompare_uni;
 45.3398 ++    }
 45.3399 ++
 45.3400 +   have_read_stdin = false;
 45.3401 +   inittables ();
 45.3402 + 
 45.3403 +@@ -4494,13 +5163,34 @@ main (int argc, char **argv)
 45.3404 + 
 45.3405 +         case 't':
 45.3406 +           {
 45.3407 +-            char newtab = optarg[0];
 45.3408 +-            if (! newtab)
 45.3409 ++            char newtab[MB_LEN_MAX + 1];
 45.3410 ++            size_t newtab_length = 1;
 45.3411 ++            strncpy (newtab, optarg, MB_LEN_MAX);
 45.3412 ++            if (! newtab[0])
 45.3413 +               error (SORT_FAILURE, 0, _("empty tab"));
 45.3414 +-            if (optarg[1])
 45.3415 ++#if HAVE_MBRTOWC
 45.3416 ++            if (MB_CUR_MAX > 1)
 45.3417 ++              {
 45.3418 ++                wchar_t wc;
 45.3419 ++                mbstate_t state;
 45.3420 ++
 45.3421 ++                memset (&state, '\0', sizeof (mbstate_t));
 45.3422 ++                newtab_length = mbrtowc (&wc, newtab, strnlen (newtab,
 45.3423 ++                                                               MB_LEN_MAX),
 45.3424 ++                                         &state);
 45.3425 ++                switch (newtab_length)
 45.3426 ++                  {
 45.3427 ++                  case (size_t) -1:
 45.3428 ++                  case (size_t) -2:
 45.3429 ++                  case 0:
 45.3430 ++                    newtab_length = 1;
 45.3431 ++                  }
 45.3432 ++              }
 45.3433 ++#endif
 45.3434 ++            if (newtab_length == 1 && optarg[1])
 45.3435 +               {
 45.3436 +                 if (STREQ (optarg, "\\0"))
 45.3437 +-                  newtab = '\0';
 45.3438 ++                  newtab[0] = '\0';
 45.3439 +                 else
 45.3440 +                   {
 45.3441 +                     /* Provoke with 'sort -txx'.  Complain about
 45.3442 +@@ -4511,9 +5201,12 @@ main (int argc, char **argv)
 45.3443 +                            quote (optarg));
 45.3444 +                   }
 45.3445 +               }
 45.3446 +-            if (tab != TAB_DEFAULT && tab != newtab)
 45.3447 ++            if (tab_length
 45.3448 ++                && (tab_length != newtab_length
 45.3449 ++                    || memcmp (tab, newtab, tab_length) != 0))
 45.3450 +               error (SORT_FAILURE, 0, _("incompatible tabs"));
 45.3451 +-            tab = newtab;
 45.3452 ++            memcpy (tab, newtab, newtab_length);
 45.3453 ++            tab_length = newtab_length;
 45.3454 +           }
 45.3455 +           break;
 45.3456 + 
 45.3457 +@@ -4751,12 +5444,10 @@ main (int argc, char **argv)
 45.3458 +       sort (files, nfiles, outfile, nthreads);
 45.3459 +     }
 45.3460 + 
 45.3461 +-#ifdef lint
 45.3462 +   if (files_from)
 45.3463 +     readtokens0_free (&tok);
 45.3464 +   else
 45.3465 +     free (files);
 45.3466 +-#endif
 45.3467 + 
 45.3468 +   if (have_read_stdin && fclose (stdin) == EOF)
 45.3469 +     die (_("close failed"), "-");
 45.3470 +diff -Naurp coreutils-8.25-orig/src/unexpand.c coreutils-8.25/src/unexpand.c
 45.3471 +--- coreutils-8.25-orig/src/unexpand.c	2016-01-01 07:48:50.000000000 -0600
 45.3472 ++++ coreutils-8.25/src/unexpand.c	2016-02-08 19:07:10.311944651 -0600
 45.3473 +@@ -38,12 +38,29 @@
 45.3474 + #include <stdio.h>
 45.3475 + #include <getopt.h>
 45.3476 + #include <sys/types.h>
 45.3477 ++
 45.3478 ++/* Get mbstate_t, mbrtowc(), wcwidth(). */
 45.3479 ++#if HAVE_WCHAR_H
 45.3480 ++# include <wchar.h>
 45.3481 ++#endif
 45.3482 ++
 45.3483 + #include "system.h"
 45.3484 + #include "error.h"
 45.3485 + #include "fadvise.h"
 45.3486 + #include "quote.h"
 45.3487 + #include "xstrndup.h"
 45.3488 + 
 45.3489 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
 45.3490 ++      installation; work around this configuration error.  */
 45.3491 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
 45.3492 ++# define MB_LEN_MAX 16
 45.3493 ++#endif
 45.3494 ++
 45.3495 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
 45.3496 ++#if HAVE_MBRTOWC && defined mbstate_t
 45.3497 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
 45.3498 ++#endif
 45.3499 ++
 45.3500 + /* The official name of this program (e.g., no 'g' prefix).  */
 45.3501 + #define PROGRAM_NAME "unexpand"
 45.3502 + 
 45.3503 +@@ -103,6 +120,210 @@ static struct option const longopts[] =
 45.3504 +   {NULL, 0, NULL, 0}
 45.3505 + };
 45.3506 + 
 45.3507 ++static FILE *next_file (FILE *fp);
 45.3508 ++
 45.3509 ++#if HAVE_MBRTOWC
 45.3510 ++static void
 45.3511 ++unexpand_multibyte (void)
 45.3512 ++{
 45.3513 ++  FILE *fp;			/* Input stream. */
 45.3514 ++  mbstate_t i_state;		/* Current shift state of the input stream. */
 45.3515 ++  mbstate_t i_state_bak;	/* Back up the I_STATE. */
 45.3516 ++  mbstate_t o_state;		/* Current shift state of the output stream. */
 45.3517 ++  char buf[MB_LEN_MAX + BUFSIZ];  /* For spooling a read byte sequence. */
 45.3518 ++  char *bufpos = buf;			/* Next read position of BUF. */
 45.3519 ++  size_t buflen = 0;		/* The length of the byte sequence in buf. */
 45.3520 ++  wint_t wc;			/* A gotten wide character. */
 45.3521 ++  size_t mblength;		/* The byte size of a multibyte character
 45.3522 ++				   which shows as same character as WC. */
 45.3523 ++  bool prev_tab = false;
 45.3524 ++
 45.3525 ++  /* Index in `tab_list' of next tabstop: */
 45.3526 ++  int tab_index = 0;		/* For calculating width of pending tabs. */
 45.3527 ++  int print_tab_index = 0;	/* For printing as many tabs as possible. */
 45.3528 ++  unsigned int column = 0;	/* Column on screen of next char. */
 45.3529 ++  int next_tab_column;		/* Column the next tab stop is on. */
 45.3530 ++  int convert = 1;		/* If nonzero, perform translations. */
 45.3531 ++  unsigned int pending = 0;	/* Pending columns of blanks. */
 45.3532 ++
 45.3533 ++  fp = next_file ((FILE *) NULL);
 45.3534 ++  if (fp == NULL)
 45.3535 ++    return;
 45.3536 ++
 45.3537 ++  memset (&o_state, '\0', sizeof(mbstate_t));
 45.3538 ++  memset (&i_state, '\0', sizeof(mbstate_t));
 45.3539 ++
 45.3540 ++  for (;;)
 45.3541 ++    {
 45.3542 ++      if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp))
 45.3543 ++	{
 45.3544 ++	  memmove (buf, bufpos, buflen);
 45.3545 ++	  buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp);
 45.3546 ++	  bufpos = buf;
 45.3547 ++	}
 45.3548 ++
 45.3549 ++      /* Get a wide character. */
 45.3550 ++      if (buflen < 1)
 45.3551 ++	{
 45.3552 ++	  mblength = 1;
 45.3553 ++	  wc = WEOF;
 45.3554 ++	}
 45.3555 ++      else
 45.3556 ++	{
 45.3557 ++	  i_state_bak = i_state;
 45.3558 ++	  mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &i_state);
 45.3559 ++	}
 45.3560 ++
 45.3561 ++      if (mblength == (size_t)-1 || mblength == (size_t)-2)
 45.3562 ++	{
 45.3563 ++	  i_state = i_state_bak;
 45.3564 ++	  wc = L'\0';
 45.3565 ++	}
 45.3566 ++
 45.3567 ++      if (wc == L' ' && convert && column < INT_MAX)
 45.3568 ++	{
 45.3569 ++	  ++pending;
 45.3570 ++	  ++column;
 45.3571 ++	}
 45.3572 ++      else if (wc == L'\t' && convert)
 45.3573 ++	{
 45.3574 ++	  if (tab_size == 0)
 45.3575 ++	    {
 45.3576 ++	      /* Do not let tab_index == first_free_tab;
 45.3577 ++		 stop when it is 1 less. */
 45.3578 ++	      while (tab_index < first_free_tab - 1
 45.3579 ++		  && column >= tab_list[tab_index])
 45.3580 ++		tab_index++;
 45.3581 ++	      next_tab_column = tab_list[tab_index];
 45.3582 ++	      if (tab_index < first_free_tab - 1)
 45.3583 ++		tab_index++;
 45.3584 ++	      if (column >= next_tab_column)
 45.3585 ++		{
 45.3586 ++		  convert = 0;	/* Ran out of tab stops. */
 45.3587 ++		  goto flush_pend_mb;
 45.3588 ++		}
 45.3589 ++	    }
 45.3590 ++	  else
 45.3591 ++	    {
 45.3592 ++	      next_tab_column = column + tab_size - column % tab_size;
 45.3593 ++	    }
 45.3594 ++	  pending += next_tab_column - column;
 45.3595 ++	  column = next_tab_column;
 45.3596 ++	}
 45.3597 ++      else
 45.3598 ++	{
 45.3599 ++flush_pend_mb:
 45.3600 ++	  /* Flush pending spaces.  Print as many tabs as possible,
 45.3601 ++	     then print the rest as spaces. */
 45.3602 ++	  if (pending == 1 && column != 1 && !prev_tab)
 45.3603 ++	    {
 45.3604 ++	      putchar (' ');
 45.3605 ++	      pending = 0;
 45.3606 ++	    }
 45.3607 ++	  column -= pending;
 45.3608 ++	  while (pending > 0)
 45.3609 ++	    {
 45.3610 ++	      if (tab_size == 0)
 45.3611 ++		{
 45.3612 ++		  /* Do not let print_tab_index == first_free_tab;
 45.3613 ++		     stop when it is 1 less. */
 45.3614 ++		  while (print_tab_index < first_free_tab - 1
 45.3615 ++		      && column >= tab_list[print_tab_index])
 45.3616 ++		    print_tab_index++;
 45.3617 ++		  next_tab_column = tab_list[print_tab_index];
 45.3618 ++		  if (print_tab_index < first_free_tab - 1)
 45.3619 ++		    print_tab_index++;
 45.3620 ++		}
 45.3621 ++	      else
 45.3622 ++		{
 45.3623 ++		  next_tab_column =
 45.3624 ++		    column + tab_size - column % tab_size;
 45.3625 ++		}
 45.3626 ++	      if (next_tab_column - column <= pending)
 45.3627 ++		{
 45.3628 ++		  putchar ('\t');
 45.3629 ++		  pending -= next_tab_column - column;
 45.3630 ++		  column = next_tab_column;
 45.3631 ++		}
 45.3632 ++	      else
 45.3633 ++		{
 45.3634 ++		  --print_tab_index;
 45.3635 ++		  column += pending;
 45.3636 ++		  while (pending != 0)
 45.3637 ++		    {
 45.3638 ++		      putchar (' ');
 45.3639 ++		      pending--;
 45.3640 ++		    }
 45.3641 ++		}
 45.3642 ++	    }
 45.3643 ++
 45.3644 ++	  if (wc == WEOF)
 45.3645 ++	    {
 45.3646 ++	      fp = next_file (fp);
 45.3647 ++	      if (fp == NULL)
 45.3648 ++		break;          /* No more files. */
 45.3649 ++	      else
 45.3650 ++		{
 45.3651 ++		  memset (&i_state, '\0', sizeof(mbstate_t));
 45.3652 ++		  continue;
 45.3653 ++		}
 45.3654 ++	    }
 45.3655 ++
 45.3656 ++	  if (mblength == (size_t)-1 || mblength == (size_t)-2)
 45.3657 ++	    {
 45.3658 ++	      if (convert)
 45.3659 ++		{
 45.3660 ++		  ++column;
 45.3661 ++		  if (convert_entire_line == 0)
 45.3662 ++		    convert = 0;
 45.3663 ++		}
 45.3664 ++	      mblength = 1;
 45.3665 ++	      putchar (buf[0]);
 45.3666 ++	    }
 45.3667 ++	  else if (mblength == 0)
 45.3668 ++	    {
 45.3669 ++	      if (convert && convert_entire_line == 0)
 45.3670 ++		convert = 0;
 45.3671 ++	      mblength = 1;
 45.3672 ++	      putchar ('\0');
 45.3673 ++	    }
 45.3674 ++	  else
 45.3675 ++	    {
 45.3676 ++	      if (convert)
 45.3677 ++		{
 45.3678 ++		  if (wc == L'\b')
 45.3679 ++		    {
 45.3680 ++		      if (column > 0)
 45.3681 ++			--column;
 45.3682 ++		    }
 45.3683 ++		  else
 45.3684 ++		    {
 45.3685 ++		      int width;            /* The width of WC. */
 45.3686 ++
 45.3687 ++		      width = wcwidth (wc);
 45.3688 ++		      column += (width > 0) ? width : 0;
 45.3689 ++		      if (convert_entire_line == 0)
 45.3690 ++			convert = 0;
 45.3691 ++		    }
 45.3692 ++		}
 45.3693 ++
 45.3694 ++	      if (wc == L'\n')
 45.3695 ++		{
 45.3696 ++		  tab_index = print_tab_index = 0;
 45.3697 ++		  column = pending = 0;
 45.3698 ++		  convert = 1;
 45.3699 ++		}
 45.3700 ++	      fwrite (bufpos, sizeof(char), mblength, stdout);
 45.3701 ++	    }
 45.3702 ++	}
 45.3703 ++      prev_tab = wc == L'\t';
 45.3704 ++      buflen -= mblength;
 45.3705 ++      bufpos += mblength;
 45.3706 ++    }
 45.3707 ++}
 45.3708 ++#endif
 45.3709 ++
 45.3710 ++
 45.3711 + void
 45.3712 + usage (int status)
 45.3713 + {
 45.3714 +@@ -523,7 +744,12 @@ main (int argc, char **argv)
 45.3715 + 
 45.3716 +   file_list = (optind < argc ? &argv[optind] : stdin_argv);
 45.3717 + 
 45.3718 +-  unexpand ();
 45.3719 ++#if HAVE_MBRTOWC
 45.3720 ++  if (MB_CUR_MAX > 1)
 45.3721 ++    unexpand_multibyte ();
 45.3722 ++  else
 45.3723 ++#endif
 45.3724 ++    unexpand ();
 45.3725 + 
 45.3726 +   if (have_read_stdin && fclose (stdin) != 0)
 45.3727 +     error (EXIT_FAILURE, errno, "-");
 45.3728 +diff -Naurp coreutils-8.25-orig/src/uniq.c coreutils-8.25/src/uniq.c
 45.3729 +--- coreutils-8.25-orig/src/uniq.c	2016-01-13 05:08:59.000000000 -0600
 45.3730 ++++ coreutils-8.25/src/uniq.c	2016-02-08 19:07:10.312944654 -0600
 45.3731 +@@ -21,6 +21,17 @@
 45.3732 + #include <getopt.h>
 45.3733 + #include <sys/types.h>
 45.3734 + 
 45.3735 ++/* Get mbstate_t, mbrtowc(). */
 45.3736 ++#if HAVE_WCHAR_H
 45.3737 ++# include <wchar.h>
 45.3738 ++#endif
 45.3739 ++
 45.3740 ++/* Get isw* functions. */
 45.3741 ++#if HAVE_WCTYPE_H
 45.3742 ++# include <wctype.h>
 45.3743 ++#endif
 45.3744 ++#include <assert.h>
 45.3745 ++
 45.3746 + #include "system.h"
 45.3747 + #include "argmatch.h"
 45.3748 + #include "linebuffer.h"
 45.3749 +@@ -33,6 +44,18 @@
 45.3750 + #include "xstrtol.h"
 45.3751 + #include "memcasecmp.h"
 45.3752 + #include "quote.h"
 45.3753 ++#include "xmemcoll.h"
 45.3754 ++
 45.3755 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
 45.3756 ++   installation; work around this configuration error.  */
 45.3757 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
 45.3758 ++# define MB_LEN_MAX 16
 45.3759 ++#endif
 45.3760 ++
 45.3761 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
 45.3762 ++#if HAVE_MBRTOWC && defined mbstate_t
 45.3763 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
 45.3764 ++#endif
 45.3765 + 
 45.3766 + /* The official name of this program (e.g., no 'g' prefix).  */
 45.3767 + #define PROGRAM_NAME "uniq"
 45.3768 +@@ -143,6 +166,10 @@ enum
 45.3769 +   GROUP_OPTION = CHAR_MAX + 1
 45.3770 + };
 45.3771 + 
 45.3772 ++/* Function pointers. */
 45.3773 ++static char *
 45.3774 ++(*find_field) (struct linebuffer *line);
 45.3775 ++
 45.3776 + static struct option const longopts[] =
 45.3777 + {
 45.3778 +   {"count", no_argument, NULL, 'c'},
 45.3779 +@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *m
 45.3780 +    return a pointer to the beginning of the line's field to be compared. */
 45.3781 + 
 45.3782 + static char * _GL_ATTRIBUTE_PURE
 45.3783 +-find_field (struct linebuffer const *line)
 45.3784 ++find_field_uni (struct linebuffer *line)
 45.3785 + {
 45.3786 +   size_t count;
 45.3787 +   char const *lp = line->buffer;
 45.3788 +@@ -272,6 +299,83 @@ find_field (struct linebuffer const *lin
 45.3789 +   return line->buffer + i;
 45.3790 + }
 45.3791 + 
 45.3792 ++#if HAVE_MBRTOWC
 45.3793 ++
 45.3794 ++# define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL)  \
 45.3795 ++  do                                                                        \
 45.3796 ++    {                                                                        \
 45.3797 ++      mbstate_t state_bak;                                                \
 45.3798 ++                                                                        \
 45.3799 ++      CONVFAIL = 0;                                                        \
 45.3800 ++      state_bak = *STATEP;                                                \
 45.3801 ++                                                                        \
 45.3802 ++      MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP);                \
 45.3803 ++                                                                        \
 45.3804 ++      switch (MBLENGTH)                                                        \
 45.3805 ++        {                                                                \
 45.3806 ++        case (size_t)-2:                                                \
 45.3807 ++        case (size_t)-1:                                                \
 45.3808 ++          *STATEP = state_bak;                                                \
 45.3809 ++          CONVFAIL++;                                                        \
 45.3810 ++          /* Fall through */                                                \
 45.3811 ++        case 0:                                                                \
 45.3812 ++          MBLENGTH = 1;                                                        \
 45.3813 ++        }                                                                \
 45.3814 ++    }                                                                        \
 45.3815 ++  while (0)
 45.3816 ++
 45.3817 ++static char *
 45.3818 ++find_field_multi (struct linebuffer *line)
 45.3819 ++{
 45.3820 ++  size_t count;
 45.3821 ++  char *lp = line->buffer;
 45.3822 ++  size_t size = line->length - 1;
 45.3823 ++  size_t pos;
 45.3824 ++  size_t mblength;
 45.3825 ++  wchar_t wc;
 45.3826 ++  mbstate_t *statep;
 45.3827 ++  int convfail = 0;
 45.3828 ++
 45.3829 ++  pos = 0;
 45.3830 ++  statep = &(line->state);
 45.3831 ++
 45.3832 ++  /* skip fields. */
 45.3833 ++  for (count = 0; count < skip_fields && pos < size; count++)
 45.3834 ++    {
 45.3835 ++      while (pos < size)
 45.3836 ++        {
 45.3837 ++          MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
 45.3838 ++
 45.3839 ++          if (convfail || !(iswblank (wc) || wc == '\n'))
 45.3840 ++            {
 45.3841 ++              pos += mblength;
 45.3842 ++              break;
 45.3843 ++            }
 45.3844 ++          pos += mblength;
 45.3845 ++        }
 45.3846 ++
 45.3847 ++      while (pos < size)
 45.3848 ++        {
 45.3849 ++          MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
 45.3850 ++
 45.3851 ++          if (!convfail && (iswblank (wc) || wc == '\n'))
 45.3852 ++            break;
 45.3853 ++
 45.3854 ++          pos += mblength;
 45.3855 ++        }
 45.3856 ++    }
 45.3857 ++
 45.3858 ++  /* skip fields. */
 45.3859 ++  for (count = 0; count < skip_chars && pos < size; count++)
 45.3860 ++    {
 45.3861 ++      MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
 45.3862 ++      pos += mblength;
 45.3863 ++    }
 45.3864 ++
 45.3865 ++  return lp + pos;
 45.3866 ++}
 45.3867 ++#endif
 45.3868 ++
 45.3869 + /* Return false if two strings OLD and NEW match, true if not.
 45.3870 +    OLD and NEW point not to the beginnings of the lines
 45.3871 +    but rather to the beginnings of the fields to compare.
 45.3872 +@@ -280,6 +384,8 @@ find_field (struct linebuffer const *lin
 45.3873 + static bool
 45.3874 + different (char *old, char *new, size_t oldlen, size_t newlen)
 45.3875 + {
 45.3876 ++  char *copy_old, *copy_new;
 45.3877 ++
 45.3878 +   if (check_chars < oldlen)
 45.3879 +     oldlen = check_chars;
 45.3880 +   if (check_chars < newlen)
 45.3881 +@@ -287,15 +393,104 @@ different (char *old, char *new, size_t
 45.3882 + 
 45.3883 +   if (ignore_case)
 45.3884 +     {
 45.3885 +-      /* FIXME: This should invoke strcoll somehow.  */
 45.3886 +-      return oldlen != newlen || memcasecmp (old, new, oldlen);
 45.3887 ++      size_t i;
 45.3888 ++
 45.3889 ++      copy_old = xmalloc (oldlen + 1);
 45.3890 ++      copy_new = xmalloc (oldlen + 1);
 45.3891 ++
 45.3892 ++      for (i = 0; i < oldlen; i++)
 45.3893 ++        {
 45.3894 ++          copy_old[i] = toupper (old[i]);
 45.3895 ++          copy_new[i] = toupper (new[i]);
 45.3896 ++        }
 45.3897 ++      bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen);
 45.3898 ++      free (copy_old);
 45.3899 ++      free (copy_new);
 45.3900 ++      return rc;
 45.3901 +     }
 45.3902 +-  else if (hard_LC_COLLATE)
 45.3903 +-    return xmemcoll (old, oldlen, new, newlen) != 0;
 45.3904 +   else
 45.3905 +-    return oldlen != newlen || memcmp (old, new, oldlen);
 45.3906 ++    {
 45.3907 ++      copy_old = (char *)old;
 45.3908 ++      copy_new = (char *)new;
 45.3909 ++    }
 45.3910 ++
 45.3911 ++  return xmemcoll (copy_old, oldlen, copy_new, newlen);
 45.3912 ++
 45.3913 + }
 45.3914 + 
 45.3915 ++#if HAVE_MBRTOWC
 45.3916 ++static int
 45.3917 ++different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate)
 45.3918 ++{
 45.3919 ++  size_t i, j, chars;
 45.3920 ++  const char *str[2];
 45.3921 ++  char *copy[2];
 45.3922 ++  size_t len[2];
 45.3923 ++  mbstate_t state[2];
 45.3924 ++  size_t mblength;
 45.3925 ++  wchar_t wc, uwc;
 45.3926 ++  mbstate_t state_bak;
 45.3927 ++
 45.3928 ++  str[0] = old;
 45.3929 ++  str[1] = new;
 45.3930 ++  len[0] = oldlen;
 45.3931 ++  len[1] = newlen;
 45.3932 ++  state[0] = oldstate;
 45.3933 ++  state[1] = newstate;
 45.3934 ++
 45.3935 ++  for (i = 0; i < 2; i++)
 45.3936 ++    {
 45.3937 ++      copy[i] = xmalloc (len[i] + 1);
 45.3938 ++      memset (copy[i], '\0', len[i] + 1);
 45.3939 ++
 45.3940 ++      for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++)
 45.3941 ++        {
 45.3942 ++          state_bak = state[i];
 45.3943 ++          mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i]));
 45.3944 ++
 45.3945 ++          switch (mblength)
 45.3946 ++            {
 45.3947 ++            case (size_t)-1:
 45.3948 ++            case (size_t)-2:
 45.3949 ++              state[i] = state_bak;
 45.3950 ++              /* Fall through */
 45.3951 ++            case 0:
 45.3952 ++              mblength = 1;
 45.3953 ++              break;
 45.3954 ++
 45.3955 ++            default:
 45.3956 ++              if (ignore_case)
 45.3957 ++                {
 45.3958 ++                  uwc = towupper (wc);
 45.3959 ++
 45.3960 ++                  if (uwc != wc)
 45.3961 ++                    {
 45.3962 ++                      mbstate_t state_wc;
 45.3963 ++                      size_t mblen;
 45.3964 ++
 45.3965 ++                      memset (&state_wc, '\0', sizeof(mbstate_t));
 45.3966 ++                      mblen = wcrtomb (copy[i] + j, uwc, &state_wc);
 45.3967 ++                      assert (mblen != (size_t)-1);
 45.3968 ++                    }
 45.3969 ++                  else
 45.3970 ++                    memcpy (copy[i] + j, str[i] + j, mblength);
 45.3971 ++                }
 45.3972 ++              else
 45.3973 ++                memcpy (copy[i] + j, str[i] + j, mblength);
 45.3974 ++            }
 45.3975 ++          j += mblength;
 45.3976 ++        }
 45.3977 ++      copy[i][j] = '\0';
 45.3978 ++      len[i] = j;
 45.3979 ++    }
 45.3980 ++  int rc = xmemcoll (copy[0], len[0], copy[1], len[1]);
 45.3981 ++  free (copy[0]);
 45.3982 ++  free (copy[1]);
 45.3983 ++  return rc;
 45.3984 ++
 45.3985 ++}
 45.3986 ++#endif
 45.3987 ++
 45.3988 + /* Output the line in linebuffer LINE to standard output
 45.3989 +    provided that the switches say it should be output.
 45.3990 +    MATCH is true if the line matches the previous line.
 45.3991 +@@ -359,19 +554,38 @@ check_file (const char *infile, const ch
 45.3992 +       char *prevfield IF_LINT ( = NULL);
 45.3993 +       size_t prevlen IF_LINT ( = 0);
 45.3994 +       bool first_group_printed = false;
 45.3995 ++#if HAVE_MBRTOWC
 45.3996 ++      mbstate_t prevstate;
 45.3997 ++
 45.3998 ++      memset (&prevstate, '\0', sizeof (mbstate_t));
 45.3999 ++#endif
 45.4000 + 
 45.4001 +       while (!feof (stdin))
 45.4002 +         {
 45.4003 +           char *thisfield;
 45.4004 +           size_t thislen;
 45.4005 +           bool new_group;
 45.4006 ++#if HAVE_MBRTOWC
 45.4007 ++          mbstate_t thisstate;
 45.4008 ++#endif
 45.4009 + 
 45.4010 +           if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
 45.4011 +             break;
 45.4012 + 
 45.4013 +           thisfield = find_field (thisline);
 45.4014 +           thislen = thisline->length - 1 - (thisfield - thisline->buffer);
 45.4015 ++#if HAVE_MBRTOWC
 45.4016 ++          if (MB_CUR_MAX > 1)
 45.4017 ++            {
 45.4018 ++              thisstate = thisline->state;
 45.4019 + 
 45.4020 ++              new_group = (prevline->length == 0
 45.4021 ++                           || different_multi (thisfield, prevfield,
 45.4022 ++                                               thislen, prevlen,
 45.4023 ++                                               thisstate, prevstate));
 45.4024 ++            }
 45.4025 ++          else
 45.4026 ++#endif
 45.4027 +           new_group = (prevline->length == 0
 45.4028 +                        || different (thisfield, prevfield, thislen, prevlen));
 45.4029 + 
 45.4030 +@@ -389,6 +603,10 @@ check_file (const char *infile, const ch
 45.4031 +               SWAP_LINES (prevline, thisline);
 45.4032 +               prevfield = thisfield;
 45.4033 +               prevlen = thislen;
 45.4034 ++#if HAVE_MBRTOWC
 45.4035 ++              if (MB_CUR_MAX > 1)
 45.4036 ++                prevstate = thisstate;
 45.4037 ++#endif
 45.4038 +               first_group_printed = true;
 45.4039 +             }
 45.4040 +         }
 45.4041 +@@ -401,17 +619,26 @@ check_file (const char *infile, const ch
 45.4042 +       size_t prevlen;
 45.4043 +       uintmax_t match_count = 0;
 45.4044 +       bool first_delimiter = true;
 45.4045 ++#if HAVE_MBRTOWC
 45.4046 ++      mbstate_t prevstate;
 45.4047 ++#endif
 45.4048 + 
 45.4049 +       if (readlinebuffer_delim (prevline, stdin, delimiter) == 0)
 45.4050 +         goto closefiles;
 45.4051 +       prevfield = find_field (prevline);
 45.4052 +       prevlen = prevline->length - 1 - (prevfield - prevline->buffer);
 45.4053 ++#if HAVE_MBRTOWC
 45.4054 ++      prevstate = prevline->state;
 45.4055 ++#endif
 45.4056 + 
 45.4057 +       while (!feof (stdin))
 45.4058 +         {
 45.4059 +           bool match;
 45.4060 +           char *thisfield;
 45.4061 +           size_t thislen;
 45.4062 ++#if HAVE_MBRTOWC
 45.4063 ++          mbstate_t thisstate = thisline->state;
 45.4064 ++#endif
 45.4065 +           if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
 45.4066 +             {
 45.4067 +               if (ferror (stdin))
 45.4068 +@@ -420,6 +647,14 @@ check_file (const char *infile, const ch
 45.4069 +             }
 45.4070 +           thisfield = find_field (thisline);
 45.4071 +           thislen = thisline->length - 1 - (thisfield - thisline->buffer);
 45.4072 ++#if HAVE_MBRTOWC
 45.4073 ++          if (MB_CUR_MAX > 1)
 45.4074 ++            {
 45.4075 ++              match = !different_multi (thisfield, prevfield,
 45.4076 ++                                thislen, prevlen, thisstate, prevstate);
 45.4077 ++            }
 45.4078 ++          else
 45.4079 ++#endif
 45.4080 +           match = !different (thisfield, prevfield, thislen, prevlen);
 45.4081 +           match_count += match;
 45.4082 + 
 45.4083 +@@ -452,6 +687,9 @@ check_file (const char *infile, const ch
 45.4084 +               SWAP_LINES (prevline, thisline);
 45.4085 +               prevfield = thisfield;
 45.4086 +               prevlen = thislen;
 45.4087 ++#if HAVE_MBRTOWC
 45.4088 ++              prevstate = thisstate;
 45.4089 ++#endif
 45.4090 +               if (!match)
 45.4091 +                 match_count = 0;
 45.4092 +             }
 45.4093 +@@ -498,6 +736,19 @@ main (int argc, char **argv)
 45.4094 + 
 45.4095 +   atexit (close_stdout);
 45.4096 + 
 45.4097 ++#if HAVE_MBRTOWC
 45.4098 ++  if (MB_CUR_MAX > 1)
 45.4099 ++    {
 45.4100 ++      find_field = find_field_multi;
 45.4101 ++    }
 45.4102 ++  else
 45.4103 ++#endif
 45.4104 ++    {
 45.4105 ++      find_field = find_field_uni;
 45.4106 ++    }
 45.4107 ++
 45.4108 ++
 45.4109 ++
 45.4110 +   skip_chars = 0;
 45.4111 +   skip_fields = 0;
 45.4112 +   check_chars = SIZE_MAX;
 45.4113 +diff -Naurp coreutils-8.25-orig/tests/i18n/sort-month.sh coreutils-8.25/tests/i18n/sort-month.sh
 45.4114 +--- coreutils-8.25-orig/tests/i18n/sort-month.sh	1969-12-31 18:00:00.000000000 -0600
 45.4115 ++++ coreutils-8.25/tests/i18n/sort-month.sh	2016-02-08 19:07:10.312944654 -0600
 45.4116 +@@ -0,0 +1,34 @@
 45.4117 ++#!/bin/sh
 45.4118 ++# Verify sort -M multi-byte support.
 45.4119 ++
 45.4120 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 45.4121 ++print_ver_ sort
 45.4122 ++require_valgrind_
 45.4123 ++
 45.4124 ++# Skip this test if some deallocations are
 45.4125 ++# avoided at process end.
 45.4126 ++grep '^#define lint 1' $CONFIG_HEADER > /dev/null ||
 45.4127 ++  skip_ 'Allocation checks only work reliably in "lint" mode'
 45.4128 ++
 45.4129 ++export LC_ALL=en_US.UTF-8
 45.4130 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \
 45.4131 ++  || skip_ "No UTF-8 locale available"
 45.4132 ++
 45.4133 ++# Note the use of ɑ here which expands to
 45.4134 ++# a wider representation upon case conversion
 45.4135 ++# which triggered an assertion in sort -M
 45.4136 ++cat <<EOF > exp
 45.4137 ++.
 45.4138 ++ɑ
 45.4139 ++EOF
 45.4140 ++
 45.4141 ++
 45.4142 ++# check large mem leak with --month-sort
 45.4143 ++# https://bugzilla.redhat.com/show_bug.cgi?id=1259942
 45.4144 ++valgrind --leak-check=full \
 45.4145 ++         --error-exitcode=1 --errors-for-leak-kinds=definite \
 45.4146 ++         sort -M < exp > out || fail=1
 45.4147 ++compare exp out || { fail=1; cat out; }
 45.4148 ++
 45.4149 ++
 45.4150 ++Exit $fail
 45.4151 +diff -Naurp coreutils-8.25-orig/tests/i18n/sort.sh coreutils-8.25/tests/i18n/sort.sh
 45.4152 +--- coreutils-8.25-orig/tests/i18n/sort.sh	1969-12-31 18:00:00.000000000 -0600
 45.4153 ++++ coreutils-8.25/tests/i18n/sort.sh	2016-02-08 19:07:10.312944654 -0600
 45.4154 +@@ -0,0 +1,29 @@
 45.4155 ++#!/bin/sh
 45.4156 ++# Verify sort's multi-byte support.
 45.4157 ++
 45.4158 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 45.4159 ++print_ver_ sort
 45.4160 ++
 45.4161 ++export LC_ALL=en_US.UTF-8
 45.4162 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \
 45.4163 ++  || skip_ "No UTF-8 locale available"
 45.4164 ++
 45.4165 ++# Enable heap consistency checkng on older systems
 45.4166 ++export MALLOC_CHECK_=2
 45.4167 ++
 45.4168 ++
 45.4169 ++# check buffer overflow issue due to
 45.4170 ++# expanding multi-byte representation due to case conversion
 45.4171 ++# https://bugzilla.suse.com/show_bug.cgi?id=928749
 45.4172 ++cat <<EOF > exp
 45.4173 ++.
 45.4174 ++ɑ
 45.4175 ++EOF
 45.4176 ++cat <<EOF | sort -f > out || fail=1
 45.4177 ++.
 45.4178 ++ɑ
 45.4179 ++EOF
 45.4180 ++compare exp out || { fail=1; cat out; }
 45.4181 ++
 45.4182 ++
 45.4183 ++Exit $fail
 45.4184 +diff -Naurp coreutils-8.25-orig/tests/local.mk coreutils-8.25/tests/local.mk
 45.4185 +--- coreutils-8.25-orig/tests/local.mk	2016-01-16 12:18:13.000000000 -0600
 45.4186 ++++ coreutils-8.25/tests/local.mk	2016-02-08 19:07:10.313944658 -0600
 45.4187 +@@ -344,6 +344,9 @@ all_tests =					\
 45.4188 +   tests/misc/sort-discrim.sh			\
 45.4189 +   tests/misc/sort-files0-from.pl		\
 45.4190 +   tests/misc/sort-float.sh			\
 45.4191 ++  tests/misc/sort-mb-tests.sh			\
 45.4192 ++  tests/i18n/sort.sh				\
 45.4193 ++  tests/i18n/sort-month.sh			\
 45.4194 +   tests/misc/sort-merge.pl			\
 45.4195 +   tests/misc/sort-merge-fdlimit.sh		\
 45.4196 +   tests/misc/sort-month.sh			\
 45.4197 +diff -Naurp coreutils-8.25-orig/tests/misc/cut.pl coreutils-8.25/tests/misc/cut.pl
 45.4198 +--- coreutils-8.25-orig/tests/misc/cut.pl	2016-01-16 12:18:13.000000000 -0600
 45.4199 ++++ coreutils-8.25/tests/misc/cut.pl	2016-02-08 19:07:10.314944661 -0600
 45.4200 +@@ -23,9 +23,11 @@ use strict;
 45.4201 + # Turn off localization of executable's output.
 45.4202 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 45.4203 + 
 45.4204 +-my $mb_locale = $ENV{LOCALE_FR_UTF8};
 45.4205 ++my $mb_locale;
 45.4206 ++# uncommented enable multibyte paths
 45.4207 ++$mb_locale = $ENV{LOCALE_FR_UTF8};
 45.4208 + ! defined $mb_locale || $mb_locale eq 'none'
 45.4209 +-  and $mb_locale = 'C';
 45.4210 ++ and $mb_locale = 'C';
 45.4211 + 
 45.4212 + my $prog = 'cut';
 45.4213 + my $try = "Try '$prog --help' for more information.\n";
 45.4214 +@@ -240,6 +242,7 @@ if ($mb_locale ne 'C')
 45.4215 +         my @new_t = @$t;
 45.4216 +         my $test_name = shift @new_t;
 45.4217 + 
 45.4218 ++        next if ($test_name =~ "newline-[12][0-9]");
 45.4219 +         push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 45.4220 +       }
 45.4221 +     push @Tests, @new;
 45.4222 +diff -Naurp coreutils-8.25-orig/tests/misc/expand.pl coreutils-8.25/tests/misc/expand.pl
 45.4223 +--- coreutils-8.25-orig/tests/misc/expand.pl	2016-01-16 12:18:13.000000000 -0600
 45.4224 ++++ coreutils-8.25/tests/misc/expand.pl	2016-02-08 19:07:10.314944661 -0600
 45.4225 +@@ -23,6 +23,15 @@ use strict;
 45.4226 + # Turn off localization of executable's output.
 45.4227 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 45.4228 + 
 45.4229 ++#comment out next line to disable multibyte tests
 45.4230 ++my $mb_locale = $ENV{LOCALE_FR_UTF8};
 45.4231 ++! defined $mb_locale || $mb_locale eq 'none'
 45.4232 ++ and $mb_locale = 'C';
 45.4233 ++
 45.4234 ++my $prog = 'expand';
 45.4235 ++my $try = "Try \`$prog --help' for more information.\n";
 45.4236 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 45.4237 ++
 45.4238 + my @Tests =
 45.4239 +   (
 45.4240 +    ['t1', '--tabs=3',     {IN=>"a\tb"}, {OUT=>"a  b"}],
 45.4241 +@@ -31,6 +40,37 @@ my @Tests =
 45.4242 +    ['i2', '--tabs=3 -i', {IN=>" \ta\tb"}, {OUT=>"   a\tb"}],
 45.4243 +   );
 45.4244 + 
 45.4245 ++if ($mb_locale ne 'C')
 45.4246 ++  {
 45.4247 ++    # Duplicate each test vector, appending "-mb" to the test name and
 45.4248 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 45.4249 ++    # provide coverage for the distro-added multi-byte code paths.
 45.4250 ++    my @new;
 45.4251 ++    foreach my $t (@Tests)
 45.4252 ++      {
 45.4253 ++        my @new_t = @$t;
 45.4254 ++        my $test_name = shift @new_t;
 45.4255 ++
 45.4256 ++        # Depending on whether expand is multi-byte-patched,
 45.4257 ++        # it emits different diagnostics:
 45.4258 ++        #   non-MB: invalid byte or field list
 45.4259 ++        #   MB:     invalid byte, character or field list
 45.4260 ++        # Adjust the expected error output accordingly.
 45.4261 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 45.4262 ++            (@new_t))
 45.4263 ++          {
 45.4264 ++            my $sub = {ERR_SUBST => 's/, character//'};
 45.4265 ++            push @new_t, $sub;
 45.4266 ++            push @$t, $sub;
 45.4267 ++          }
 45.4268 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 45.4269 ++      }
 45.4270 ++    push @Tests, @new;
 45.4271 ++  }
 45.4272 ++
 45.4273 ++
 45.4274 ++@Tests = triple_test \@Tests;
 45.4275 ++
 45.4276 + my $save_temps = $ENV{DEBUG};
 45.4277 + my $verbose = $ENV{VERBOSE};
 45.4278 + 
 45.4279 +diff -Naurp coreutils-8.25-orig/tests/misc/fold.pl coreutils-8.25/tests/misc/fold.pl
 45.4280 +--- coreutils-8.25-orig/tests/misc/fold.pl	2016-01-16 12:18:13.000000000 -0600
 45.4281 ++++ coreutils-8.25/tests/misc/fold.pl	2016-02-08 19:07:10.314944661 -0600
 45.4282 +@@ -20,9 +20,18 @@ use strict;
 45.4283 + 
 45.4284 + (my $program_name = $0) =~ s|.*/||;
 45.4285 + 
 45.4286 ++my $prog = 'fold';
 45.4287 ++my $try = "Try \`$prog --help' for more information.\n";
 45.4288 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 45.4289 ++
 45.4290 + # Turn off localization of executable's output.
 45.4291 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 45.4292 + 
 45.4293 ++# uncommented to enable multibyte paths
 45.4294 ++my $mb_locale = $ENV{LOCALE_FR_UTF8};
 45.4295 ++! defined $mb_locale || $mb_locale eq 'none'
 45.4296 ++ and $mb_locale = 'C';
 45.4297 ++
 45.4298 + my @Tests =
 45.4299 +   (
 45.4300 +    ['s1', '-w2 -s', {IN=>"a\t"}, {OUT=>"a\n\t"}],
 45.4301 +@@ -31,9 +40,48 @@ my @Tests =
 45.4302 +    ['s4', '-w4 -s', {IN=>"abc ef\n"}, {OUT=>"abc \nef\n"}],
 45.4303 +   );
 45.4304 + 
 45.4305 ++# Add _POSIX2_VERSION=199209 to the environment of each test
 45.4306 ++# that uses an old-style option like +1.
 45.4307 ++if ($mb_locale ne 'C')
 45.4308 ++  {
 45.4309 ++    # Duplicate each test vector, appending "-mb" to the test name and
 45.4310 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 45.4311 ++    # provide coverage for the distro-added multi-byte code paths.
 45.4312 ++    my @new;
 45.4313 ++    foreach my $t (@Tests)
 45.4314 ++      {
 45.4315 ++        my @new_t = @$t;
 45.4316 ++        my $test_name = shift @new_t;
 45.4317 ++
 45.4318 ++        # Depending on whether fold is multi-byte-patched,
 45.4319 ++        # it emits different diagnostics:
 45.4320 ++        #   non-MB: invalid byte or field list
 45.4321 ++        #   MB:     invalid byte, character or field list
 45.4322 ++        # Adjust the expected error output accordingly.
 45.4323 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 45.4324 ++            (@new_t))
 45.4325 ++          {
 45.4326 ++            my $sub = {ERR_SUBST => 's/, character//'};
 45.4327 ++            push @new_t, $sub;
 45.4328 ++            push @$t, $sub;
 45.4329 ++          }
 45.4330 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 45.4331 ++      }
 45.4332 ++    push @Tests, @new;
 45.4333 ++  }
 45.4334 ++
 45.4335 ++@Tests = triple_test \@Tests;
 45.4336 ++
 45.4337 ++# Remember that triple_test creates from each test with exactly one "IN"
 45.4338 ++# file two more tests (.p and .r suffix on name) corresponding to reading
 45.4339 ++# input from a file and from a pipe.  The pipe-reading test would fail
 45.4340 ++# due to a race condition about 1 in 20 times.
 45.4341 ++# Remove the IN_PIPE version of the "output-is-input" test above.
 45.4342 ++# The others aren't susceptible because they have three inputs each.
 45.4343 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
 45.4344 ++
 45.4345 + my $save_temps = $ENV{DEBUG};
 45.4346 + my $verbose = $ENV{VERBOSE};
 45.4347 + 
 45.4348 +-my $prog = 'fold';
 45.4349 + my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose);
 45.4350 + exit $fail;
 45.4351 +diff -Naurp coreutils-8.25-orig/tests/misc/join.pl coreutils-8.25/tests/misc/join.pl
 45.4352 +--- coreutils-8.25-orig/tests/misc/join.pl	2016-01-16 12:18:13.000000000 -0600
 45.4353 ++++ coreutils-8.25/tests/misc/join.pl	2016-02-08 19:07:10.315944664 -0600
 45.4354 +@@ -25,6 +25,15 @@ my $limits = getlimits ();
 45.4355 + 
 45.4356 + my $prog = 'join';
 45.4357 + 
 45.4358 ++my $try = "Try \`$prog --help' for more information.\n";
 45.4359 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 45.4360 ++
 45.4361 ++my $mb_locale;
 45.4362 ++#Comment out next line to disable multibyte tests
 45.4363 ++$mb_locale = $ENV{LOCALE_FR_UTF8};
 45.4364 ++! defined $mb_locale || $mb_locale eq 'none'
 45.4365 ++  and $mb_locale = 'C';
 45.4366 ++
 45.4367 + my $delim = chr 0247;
 45.4368 + sub t_subst ($)
 45.4369 + {
 45.4370 +@@ -329,8 +338,49 @@ foreach my $t (@tv)
 45.4371 +     push @Tests, $new_ent;
 45.4372 +   }
 45.4373 + 
 45.4374 ++# Add _POSIX2_VERSION=199209 to the environment of each test
 45.4375 ++# that uses an old-style option like +1.
 45.4376 ++if ($mb_locale ne 'C')
 45.4377 ++  {
 45.4378 ++    # Duplicate each test vector, appending "-mb" to the test name and
 45.4379 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 45.4380 ++    # provide coverage for the distro-added multi-byte code paths.
 45.4381 ++    my @new;
 45.4382 ++    foreach my $t (@Tests)
 45.4383 ++      {
 45.4384 ++        my @new_t = @$t;
 45.4385 ++        my $test_name = shift @new_t;
 45.4386 ++
 45.4387 ++        # Depending on whether join is multi-byte-patched,
 45.4388 ++        # it emits different diagnostics:
 45.4389 ++        #   non-MB: invalid byte or field list
 45.4390 ++        #   MB:     invalid byte, character or field list
 45.4391 ++        # Adjust the expected error output accordingly.
 45.4392 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 45.4393 ++            (@new_t))
 45.4394 ++          {
 45.4395 ++            my $sub = {ERR_SUBST => 's/, character//'};
 45.4396 ++            push @new_t, $sub;
 45.4397 ++            push @$t, $sub;
 45.4398 ++          }
 45.4399 ++        #Adjust the output some error messages including test_name for mb
 45.4400 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR}}
 45.4401 ++             (@new_t))
 45.4402 ++          {
 45.4403 ++            my $sub2 = {ERR_SUBST => "s/$test_name-mb/$test_name/"};
 45.4404 ++            push @new_t, $sub2;
 45.4405 ++            push @$t, $sub2;
 45.4406 ++          }
 45.4407 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 45.4408 ++      }
 45.4409 ++    push @Tests, @new;
 45.4410 ++  }
 45.4411 ++
 45.4412 + @Tests = triple_test \@Tests;
 45.4413 + 
 45.4414 ++#skip invalid-j-mb test, it is failing because of the format
 45.4415 ++@Tests = grep {$_->[0] ne 'invalid-j-mb'} @Tests;
 45.4416 ++
 45.4417 + my $save_temps = $ENV{DEBUG};
 45.4418 + my $verbose = $ENV{VERBOSE};
 45.4419 + 
 45.4420 +diff -Naurp coreutils-8.25-orig/tests/misc/sort-mb-tests.sh coreutils-8.25/tests/misc/sort-mb-tests.sh
 45.4421 +--- coreutils-8.25-orig/tests/misc/sort-mb-tests.sh	1969-12-31 18:00:00.000000000 -0600
 45.4422 ++++ coreutils-8.25/tests/misc/sort-mb-tests.sh	2016-02-08 19:07:10.315944664 -0600
 45.4423 +@@ -0,0 +1,45 @@
 45.4424 ++#!/bin/sh
 45.4425 ++# Verify sort's multi-byte support.
 45.4426 ++
 45.4427 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 45.4428 ++print_ver_ sort
 45.4429 ++
 45.4430 ++export LC_ALL=en_US.UTF-8
 45.4431 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \
 45.4432 ++  || skip_ "No UTF-8 locale available"
 45.4433 ++
 45.4434 ++
 45.4435 ++cat <<EOF > exp
 45.4436 ++Banana@5
 45.4437 ++Apple@10
 45.4438 ++Citrus@20
 45.4439 ++Cherry@30
 45.4440 ++EOF
 45.4441 ++
 45.4442 ++cat <<EOF | sort -t @ -k2 -n > out || fail=1
 45.4443 ++Apple@10
 45.4444 ++Banana@5
 45.4445 ++Citrus@20
 45.4446 ++Cherry@30
 45.4447 ++EOF
 45.4448 ++
 45.4449 ++compare exp out || { fail=1; cat out; }
 45.4450 ++
 45.4451 ++
 45.4452 ++cat <<EOF > exp
 45.4453 ++Citrus@AA20@@5
 45.4454 ++Cherry@AA30@@10
 45.4455 ++Apple@AA10@@20
 45.4456 ++Banana@AA5@@30
 45.4457 ++EOF
 45.4458 ++
 45.4459 ++cat <<EOF | sort -t @ -k4 -n > out || fail=1
 45.4460 ++Apple@AA10@@20
 45.4461 ++Banana@AA5@@30
 45.4462 ++Citrus@AA20@@5
 45.4463 ++Cherry@AA30@@10
 45.4464 ++EOF
 45.4465 ++
 45.4466 ++compare exp out || { fail=1; cat out; }
 45.4467 ++
 45.4468 ++Exit $fail
 45.4469 +diff -Naurp coreutils-8.25-orig/tests/misc/sort-merge.pl coreutils-8.25/tests/misc/sort-merge.pl
 45.4470 +--- coreutils-8.25-orig/tests/misc/sort-merge.pl	2016-01-16 12:18:14.000000000 -0600
 45.4471 ++++ coreutils-8.25/tests/misc/sort-merge.pl	2016-02-08 19:07:10.316944667 -0600
 45.4472 +@@ -26,6 +26,15 @@ my $prog = 'sort';
 45.4473 + # Turn off localization of executable's output.
 45.4474 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 45.4475 + 
 45.4476 ++my $mb_locale;
 45.4477 ++# uncommented according to upstream commit enabling multibyte paths
 45.4478 ++$mb_locale = $ENV{LOCALE_FR_UTF8};
 45.4479 ++! defined $mb_locale || $mb_locale eq 'none'
 45.4480 ++ and $mb_locale = 'C';
 45.4481 ++
 45.4482 ++my $try = "Try \`$prog --help' for more information.\n";
 45.4483 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 45.4484 ++
 45.4485 + # three empty files and one that says 'foo'
 45.4486 + my @inputs = (+(map{{IN=> {"empty$_"=> ''}}}1..3), {IN=> {foo=> "foo\n"}});
 45.4487 + 
 45.4488 +@@ -77,6 +86,39 @@ my @Tests =
 45.4489 +         {OUT=>$big_input}],
 45.4490 +     );
 45.4491 + 
 45.4492 ++# Add _POSIX2_VERSION=199209 to the environment of each test
 45.4493 ++# that uses an old-style option like +1.
 45.4494 ++if ($mb_locale ne 'C')
 45.4495 ++  {
 45.4496 ++    # Duplicate each test vector, appending "-mb" to the test name and
 45.4497 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 45.4498 ++    # provide coverage for the distro-added multi-byte code paths.
 45.4499 ++    my @new;
 45.4500 ++    foreach my $t (@Tests)
 45.4501 ++      {
 45.4502 ++        my @new_t = @$t;
 45.4503 ++        my $test_name = shift @new_t;
 45.4504 ++
 45.4505 ++        # Depending on whether sort is multi-byte-patched,
 45.4506 ++        # it emits different diagnostics:
 45.4507 ++        #   non-MB: invalid byte or field list
 45.4508 ++        #   MB:     invalid byte, character or field list
 45.4509 ++        # Adjust the expected error output accordingly.
 45.4510 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 45.4511 ++            (@new_t))
 45.4512 ++          {
 45.4513 ++            my $sub = {ERR_SUBST => 's/, character//'};
 45.4514 ++            push @new_t, $sub;
 45.4515 ++            push @$t, $sub;
 45.4516 ++          }
 45.4517 ++        next if ($test_name =~ "nmerge-.");
 45.4518 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 45.4519 ++      }
 45.4520 ++    push @Tests, @new;
 45.4521 ++  }
 45.4522 ++
 45.4523 ++@Tests = triple_test \@Tests;
 45.4524 ++
 45.4525 + my $save_temps = $ENV{DEBUG};
 45.4526 + my $verbose = $ENV{VERBOSE};
 45.4527 + 
 45.4528 +diff -Naurp coreutils-8.25-orig/tests/misc/sort.pl coreutils-8.25/tests/misc/sort.pl
 45.4529 +--- coreutils-8.25-orig/tests/misc/sort.pl	2016-01-16 12:18:14.000000000 -0600
 45.4530 ++++ coreutils-8.25/tests/misc/sort.pl	2016-02-08 19:07:10.316944667 -0600
 45.4531 +@@ -24,10 +24,15 @@ my $prog = 'sort';
 45.4532 + # Turn off localization of executable's output.
 45.4533 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 45.4534 + 
 45.4535 +-my $mb_locale = $ENV{LOCALE_FR_UTF8};
 45.4536 ++my $mb_locale;
 45.4537 ++#Comment out next line to disable multibyte tests
 45.4538 ++$mb_locale = $ENV{LOCALE_FR_UTF8};
 45.4539 + ! defined $mb_locale || $mb_locale eq 'none'
 45.4540 +   and $mb_locale = 'C';
 45.4541 + 
 45.4542 ++my $try = "Try \`$prog --help' for more information.\n";
 45.4543 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 45.4544 ++
 45.4545 + # Since each test is run with a file name and with redirected stdin,
 45.4546 + # the name in the diagnostic is either the file name or "-".
 45.4547 + # Normalize each diagnostic to use '-'.
 45.4548 +@@ -424,6 +429,38 @@ foreach my $t (@Tests)
 45.4549 +       }
 45.4550 +   }
 45.4551 + 
 45.4552 ++if ($mb_locale ne 'C')
 45.4553 ++   {
 45.4554 ++    # Duplicate each test vector, appending "-mb" to the test name and
 45.4555 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 45.4556 ++    # provide coverage for the distro-added multi-byte code paths.
 45.4557 ++    my @new;
 45.4558 ++    foreach my $t (@Tests)
 45.4559 ++       {
 45.4560 ++        my @new_t = @$t;
 45.4561 ++        my $test_name = shift @new_t;
 45.4562 ++
 45.4563 ++        # Depending on whether sort is multi-byte-patched,
 45.4564 ++        # it emits different diagnostics:
 45.4565 ++        #   non-MB: invalid byte or field list
 45.4566 ++        #   MB:     invalid byte, character or field list
 45.4567 ++        # Adjust the expected error output accordingly.
 45.4568 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 45.4569 ++            (@new_t))
 45.4570 ++          {
 45.4571 ++            my $sub = {ERR_SUBST => 's/, character//'};
 45.4572 ++            push @new_t, $sub;
 45.4573 ++            push @$t, $sub;
 45.4574 ++          }
 45.4575 ++        #disable several failing tests until investigation, disable all tests with envvars set
 45.4576 ++        next if (grep {ref $_ eq 'HASH' && exists $_->{ENV}} (@new_t));
 45.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");
 45.4578 ++        next if ($test_name =~ "11[ab]"); # avoid FP: expected result differs to MB result due to collation rules.
 45.4579 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 45.4580 ++       }
 45.4581 ++    push @Tests, @new;
 45.4582 ++   }
 45.4583 ++
 45.4584 + @Tests = triple_test \@Tests;
 45.4585 + 
 45.4586 + # Remember that triple_test creates from each test with exactly one "IN"
 45.4587 +@@ -433,6 +470,7 @@ foreach my $t (@Tests)
 45.4588 + # Remove the IN_PIPE version of the "output-is-input" test above.
 45.4589 + # The others aren't susceptible because they have three inputs each.
 45.4590 + @Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
 45.4591 ++@Tests = grep {$_->[0] ne 'output-is-input-mb.p'} @Tests;
 45.4592 + 
 45.4593 + my $save_temps = $ENV{DEBUG};
 45.4594 + my $verbose = $ENV{VERBOSE};
 45.4595 +diff -Naurp coreutils-8.25-orig/tests/misc/unexpand.pl coreutils-8.25/tests/misc/unexpand.pl
 45.4596 +--- coreutils-8.25-orig/tests/misc/unexpand.pl	2016-01-16 12:18:14.000000000 -0600
 45.4597 ++++ coreutils-8.25/tests/misc/unexpand.pl	2016-02-08 19:07:10.317944671 -0600
 45.4598 +@@ -27,6 +27,14 @@ my $limits = getlimits ();
 45.4599 + 
 45.4600 + my $prog = 'unexpand';
 45.4601 + 
 45.4602 ++# comment out next line to disable multibyte tests
 45.4603 ++my $mb_locale = $ENV{LOCALE_FR_UTF8};
 45.4604 ++! defined $mb_locale || $mb_locale eq 'none'
 45.4605 ++ and $mb_locale = 'C';
 45.4606 ++
 45.4607 ++my $try = "Try \`$prog --help' for more information.\n";
 45.4608 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 45.4609 ++
 45.4610 + my @Tests =
 45.4611 +     (
 45.4612 +      ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}],
 45.4613 +@@ -92,6 +100,37 @@ my @Tests =
 45.4614 +       {EXIT => 1}, {ERR => "$prog: tab stop value is too large\n"}],
 45.4615 +     );
 45.4616 + 
 45.4617 ++if ($mb_locale ne 'C')
 45.4618 ++  {
 45.4619 ++    # Duplicate each test vector, appending "-mb" to the test name and
 45.4620 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 45.4621 ++    # provide coverage for the distro-added multi-byte code paths.
 45.4622 ++    my @new;
 45.4623 ++    foreach my $t (@Tests)
 45.4624 ++      {
 45.4625 ++        my @new_t = @$t;
 45.4626 ++        my $test_name = shift @new_t;
 45.4627 ++
 45.4628 ++        # Depending on whether unexpand is multi-byte-patched,
 45.4629 ++        # it emits different diagnostics:
 45.4630 ++        #   non-MB: invalid byte or field list
 45.4631 ++        #   MB:     invalid byte, character or field list
 45.4632 ++        # Adjust the expected error output accordingly.
 45.4633 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 45.4634 ++            (@new_t))
 45.4635 ++          {
 45.4636 ++            my $sub = {ERR_SUBST => 's/, character//'};
 45.4637 ++            push @new_t, $sub;
 45.4638 ++            push @$t, $sub;
 45.4639 ++          }
 45.4640 ++        next if ($test_name =~ 'b-1');
 45.4641 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 45.4642 ++      }
 45.4643 ++    push @Tests, @new;
 45.4644 ++  }
 45.4645 ++
 45.4646 ++@Tests = triple_test \@Tests;
 45.4647 ++
 45.4648 + my $save_temps = $ENV{DEBUG};
 45.4649 + my $verbose = $ENV{VERBOSE};
 45.4650 + 
 45.4651 +diff -Naurp coreutils-8.25-orig/tests/misc/uniq.pl coreutils-8.25/tests/misc/uniq.pl
 45.4652 +--- coreutils-8.25-orig/tests/misc/uniq.pl	2016-01-16 12:18:14.000000000 -0600
 45.4653 ++++ coreutils-8.25/tests/misc/uniq.pl	2016-02-08 19:07:10.317944671 -0600
 45.4654 +@@ -23,9 +23,17 @@ my $limits = getlimits ();
 45.4655 + my $prog = 'uniq';
 45.4656 + my $try = "Try '$prog --help' for more information.\n";
 45.4657 + 
 45.4658 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 45.4659 ++
 45.4660 + # Turn off localization of executable's output.
 45.4661 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 45.4662 + 
 45.4663 ++my $mb_locale;
 45.4664 ++#Comment out next line to disable multibyte tests
 45.4665 ++$mb_locale = $ENV{LOCALE_FR_UTF8};
 45.4666 ++! defined $mb_locale || $mb_locale eq 'none'
 45.4667 ++  and $mb_locale = 'C';
 45.4668 ++
 45.4669 + # When possible, create a "-z"-testing variant of each test.
 45.4670 + sub add_z_variants($)
 45.4671 + {
 45.4672 +@@ -262,6 +270,53 @@ foreach my $t (@Tests)
 45.4673 +       and push @$t, {ENV=>'_POSIX2_VERSION=199209'};
 45.4674 +   }
 45.4675 + 
 45.4676 ++if ($mb_locale ne 'C')
 45.4677 ++  {
 45.4678 ++    # Duplicate each test vector, appending "-mb" to the test name and
 45.4679 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 45.4680 ++    # provide coverage for the distro-added multi-byte code paths.
 45.4681 ++    my @new;
 45.4682 ++    foreach my $t (@Tests)
 45.4683 ++      {
 45.4684 ++        my @new_t = @$t;
 45.4685 ++        my $test_name = shift @new_t;
 45.4686 ++
 45.4687 ++        # Depending on whether uniq is multi-byte-patched,
 45.4688 ++        # it emits different diagnostics:
 45.4689 ++        #   non-MB: invalid byte or field list
 45.4690 ++        #   MB:     invalid byte, character or field list
 45.4691 ++        # Adjust the expected error output accordingly.
 45.4692 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 45.4693 ++            (@new_t))
 45.4694 ++          {
 45.4695 ++            my $sub = {ERR_SUBST => 's/, character//'};
 45.4696 ++            push @new_t, $sub;
 45.4697 ++            push @$t, $sub;
 45.4698 ++          }
 45.4699 ++        # In test #145, replace the each ‘...’ by '...'.
 45.4700 ++        if ($test_name =~ "145")
 45.4701 ++          {
 45.4702 ++            my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"};
 45.4703 ++            push @new_t, $sub;
 45.4704 ++            push @$t, $sub;
 45.4705 ++          }
 45.4706 ++        next if (   $test_name =~ "schar"
 45.4707 ++                 or $test_name =~ "^obs-plus"
 45.4708 ++                 or $test_name =~ "119");
 45.4709 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 45.4710 ++      }
 45.4711 ++    push @Tests, @new;
 45.4712 ++   }
 45.4713 ++
 45.4714 ++# Remember that triple_test creates from each test with exactly one "IN"
 45.4715 ++# file two more tests (.p and .r suffix on name) corresponding to reading
 45.4716 ++# input from a file and from a pipe.  The pipe-reading test would fail
 45.4717 ++# due to a race condition about 1 in 20 times.
 45.4718 ++# Remove the IN_PIPE version of the "output-is-input" test above.
 45.4719 ++# The others aren't susceptible because they have three inputs each.
 45.4720 ++
 45.4721 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
 45.4722 ++
 45.4723 + @Tests = add_z_variants \@Tests;
 45.4724 + @Tests = triple_test \@Tests;
 45.4725 + 
 45.4726 +diff -Naurp coreutils-8.25-orig/tests/pr/pr-tests.pl coreutils-8.25/tests/pr/pr-tests.pl
 45.4727 +--- coreutils-8.25-orig/tests/pr/pr-tests.pl	2016-01-16 12:18:14.000000000 -0600
 45.4728 ++++ coreutils-8.25/tests/pr/pr-tests.pl	2016-02-08 19:07:10.318944674 -0600
 45.4729 +@@ -24,6 +24,15 @@ use strict;
 45.4730 + my $prog = 'pr';
 45.4731 + my $normalize_strerror = "s/': .*/'/";
 45.4732 + 
 45.4733 ++my $mb_locale;
 45.4734 ++#Uncomment the following line to enable multibyte tests
 45.4735 ++$mb_locale = $ENV{LOCALE_FR_UTF8};
 45.4736 ++! defined $mb_locale || $mb_locale eq 'none'
 45.4737 ++  and $mb_locale = 'C';
 45.4738 ++
 45.4739 ++my $try = "Try \`$prog --help' for more information.\n";
 45.4740 ++my $inval = "$prog: invalid byte, character or field list\n$try";
 45.4741 ++
 45.4742 + my @tv = (
 45.4743 + 
 45.4744 + # -b option is no longer an official option. But it's still working to
 45.4745 +@@ -467,8 +476,48 @@ push @Tests,
 45.4746 +     {IN=>{3=>"x\ty\tz\n"}},
 45.4747 +      {OUT=>join("\t", qw(a b c m n o x y z)) . "\n"} ];
 45.4748 + 
 45.4749 ++# Add _POSIX2_VERSION=199209 to the environment of each test
 45.4750 ++# that uses an old-style option like +1.
 45.4751 ++if ($mb_locale ne 'C')
 45.4752 ++  {
 45.4753 ++    # Duplicate each test vector, appending "-mb" to the test name and
 45.4754 ++    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
 45.4755 ++    # provide coverage for the distro-added multi-byte code paths.
 45.4756 ++    my @new;
 45.4757 ++    foreach my $t (@Tests)
 45.4758 ++      {
 45.4759 ++        my @new_t = @$t;
 45.4760 ++        my $test_name = shift @new_t;
 45.4761 ++
 45.4762 ++        # Depending on whether pr is multi-byte-patched,
 45.4763 ++        # it emits different diagnostics:
 45.4764 ++        #   non-MB: invalid byte or field list
 45.4765 ++        #   MB:     invalid byte, character or field list
 45.4766 ++        # Adjust the expected error output accordingly.
 45.4767 ++        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
 45.4768 ++            (@new_t))
 45.4769 ++          {
 45.4770 ++            my $sub = {ERR_SUBST => 's/, character//'};
 45.4771 ++            push @new_t, $sub;
 45.4772 ++            push @$t, $sub;
 45.4773 ++          }
 45.4774 ++        #temporarily skip some failing tests
 45.4775 ++        next if ($test_name =~ "col-0" or $test_name =~ "col-inval");
 45.4776 ++        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
 45.4777 ++      }
 45.4778 ++    push @Tests, @new;
 45.4779 ++  }
 45.4780 ++
 45.4781 + @Tests = triple_test \@Tests;
 45.4782 + 
 45.4783 ++# Remember that triple_test creates from each test with exactly one "IN"
 45.4784 ++# file two more tests (.p and .r suffix on name) corresponding to reading
 45.4785 ++# input from a file and from a pipe.  The pipe-reading test would fail
 45.4786 ++# due to a race condition about 1 in 20 times.
 45.4787 ++# Remove the IN_PIPE version of the "output-is-input" test above.
 45.4788 ++# The others aren't susceptible because they have three inputs each.
 45.4789 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
 45.4790 ++
 45.4791 + my $save_temps = $ENV{DEBUG};
 45.4792 + my $verbose = $ENV{VERBOSE};
 45.4793 +