wok-6.x rev 19215
Up coreutils(8.25)
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 +