wok-next rev 19735
Update some more receipts to v2: coreutils, attr, libpng16 (former libpng), libpng12, libwebp, libxml2.
author | Aleksej Bobylev <al.bobylev@gmail.com> |
---|---|
date | Sat May 27 16:55:17 2017 +0300 (2017-05-27) |
parents | b75a21e7b544 |
children | 11f96bc53c0e |
files | attr-dev/receipt attr/receipt coreutils-character/description.txt coreutils-character/receipt coreutils-command/description.txt coreutils-command/receipt coreutils-conditions/description.txt coreutils-conditions/receipt coreutils-context-system/description.txt coreutils-context-system/receipt coreutils-context-user/description.txt coreutils-context-user/receipt coreutils-context-working/description.txt coreutils-context-working/receipt coreutils-directory/description.txt coreutils-directory/receipt coreutils-disk/description.txt coreutils-disk/receipt coreutils-file-attributes/description.txt coreutils-file-attributes/receipt coreutils-file-format/description.txt coreutils-file-format/receipt coreutils-file-output-full/description.txt coreutils-file-output-full/receipt coreutils-file-output-part/description.txt coreutils-file-output-part/receipt coreutils-file-sort/description.txt coreutils-file-sort/receipt coreutils-file-special/description.txt coreutils-file-special/receipt coreutils-file-summarize/description.txt coreutils-file-summarize/receipt coreutils-line/description.txt coreutils-line/receipt coreutils-numeric/description.txt coreutils-numeric/receipt coreutils-operations/description.txt coreutils-operations/receipt coreutils-path/description.txt coreutils-path/receipt coreutils-print/description.txt coreutils-print/receipt coreutils-redirection/description.txt coreutils-redirection/receipt coreutils/description.coreutils-character.txt coreutils/description.coreutils-command.txt coreutils/description.coreutils-conditions.txt coreutils/description.coreutils-context-system.txt coreutils/description.coreutils-context-user.txt coreutils/description.coreutils-context-working.txt coreutils/description.coreutils-directory.txt coreutils/description.coreutils-disk.txt coreutils/description.coreutils-file-attributes.txt coreutils/description.coreutils-file-format.txt coreutils/description.coreutils-file-output-full.txt coreutils/description.coreutils-file-output-part.txt coreutils/description.coreutils-file-sort.txt coreutils/description.coreutils-file-special.txt coreutils/description.coreutils-file-summarize.txt coreutils/description.coreutils-line.txt coreutils/description.coreutils-numeric.txt coreutils/description.coreutils-operations.txt coreutils/description.coreutils-path.txt coreutils/description.coreutils-print.txt coreutils/description.coreutils-redirection.txt coreutils/description.txt coreutils/receipt coreutils/stuff/coreutils-8.25-i18n-2.patch coreutils/stuff/coreutils-fix-po.patch coreutils/stuff/ls.u coreutils/stuff/patches/README coreutils/stuff/patches/coreutils-8.25-i18n-2.patch coreutils/stuff/patches/coreutils-fix-po.patch coreutils/stuff/patches/series coreutils/stuff/patches/uname.u coreutils/stuff/sigcontext.h coreutils/stuff/uname.u libpng-dev/receipt libpng/receipt libpng12-dev/receipt libpng12/receipt libpng16/receipt libwebp-apps/receipt libwebp-dev/receipt libwebp/receipt libxml2-dev/receipt libxml2-python/receipt libxml2-tools/receipt libxml2/receipt |
line diff
1.1 --- a/attr-dev/receipt Sat May 27 16:29:45 2017 +0300 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,19 +0,0 @@ 1.4 -# SliTaz package receipt. 1.5 - 1.6 -PACKAGE="attr-dev" 1.7 -VERSION="2.4.47" 1.8 -CATEGORY="development" 1.9 -SHORT_DESC="Development files for attr." 1.10 -MAINTAINER="rcx@zoominternet.net" 1.11 -LICENSE="GPL2" 1.12 -WEB_SITE="http://savannah.nongnu.org/projects/attr/" 1.13 -HOST_ARCH="i486 arm" 1.14 - 1.15 -WANTED="attr" 1.16 -DEPENDS="attr" 1.17 - 1.18 -# Rules to gen a SliTaz package suitable for Tazpkg. 1.19 -genpkg_rules() 1.20 -{ 1.21 - cook_copy_files *.h *.la 1.22 -}
2.1 --- a/attr/receipt Sat May 27 16:29:45 2017 +0300 2.2 +++ b/attr/receipt Sat May 27 16:55:17 2017 +0300 2.3 @@ -1,9 +1,9 @@ 2.4 -# SliTaz package receipt. 2.5 +# SliTaz package receipt v2. 2.6 2.7 PACKAGE="attr" 2.8 VERSION="2.4.47" 2.9 CATEGORY="system-tools" 2.10 -SHORT_DESC="Commands for Manipulating Filesystem Extended Attributes." 2.11 +SHORT_DESC="Commands for Manipulating Filesystem Extended Attributes" 2.12 MAINTAINER="rcx@zoominternet.net" 2.13 LICENSE="GPL2" 2.14 WEB_SITE="http://savannah.nongnu.org/projects/attr" 2.15 @@ -12,13 +12,9 @@ 2.16 TARBALL="$PACKAGE-$VERSION.src.tar.gz" 2.17 WGET_URL="http://download.savannah.gnu.org/releases/$PACKAGE/$TARBALL" 2.18 2.19 -DEPENDS="glibc-base" 2.20 BUILD_DEPENDS="autoconf automake m4 libtool gettext coreutils-operations" 2.21 - 2.22 -# When cross compiling auto-tools, gettext and m4 build system are used. 2.23 -case "$ARCH" in 2.24 - arm) BUILD_DEPENDS="" ;; 2.25 -esac 2.26 +BUILD_DEPENDS_arm=" " 2.27 +SPLIT="attr-dev" 2.28 2.29 # Rules to configure and make the package. 2.30 compile_rules() 2.31 @@ -44,6 +40,8 @@ 2.32 # Rules to gen a SliTaz package suitable for Tazpkg. 2.33 genpkg_rules() 2.34 { 2.35 - cook_copy_folders bin 2.36 - cook_copy_files *.so* 2.37 + case $PACKAGE in 2.38 + attr) copy @std ;; 2.39 + attr-dev) copy @dev ;; 2.40 + esac 2.41 }
3.1 --- a/coreutils-character/description.txt Sat May 27 16:29:45 2017 +0300 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,5 +0,0 @@ 3.4 -Coreutils: Core GNU (file, text, shell) utilities. 3.5 - 3.6 - * expand: convert tabs to spaces 3.7 - * tr: translate or delete characters 3.8 - * unexpand: convert spaces to tabs
4.1 --- a/coreutils-character/receipt Sat May 27 16:29:45 2017 +0300 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,30 +0,0 @@ 4.4 -# SliTaz package receipt. 4.5 - 4.6 -PACKAGE="coreutils-character" 4.7 -VERSION="8.25" 4.8 -CATEGORY="system-tools" 4.9 -SHORT_DESC="GNU utilities that operate on characters." 4.10 -MAINTAINER="rcx@zoominternet.net" 4.11 -LICENSE="GPL3" 4.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 4.13 - 4.14 -WANTED="coreutils" 4.15 -DEPENDS="glibc-base" 4.16 - 4.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 4.18 -genpkg_rules() 4.19 -{ 4.20 - cook_copy_files expand tr unexpand 4.21 -} 4.22 - 4.23 -post_remove() 4.24 -{ 4.25 - # Restore all Busybox applets that have been replaced 4.26 - while read i; do 4.27 - busybox ln -s /bin/busybox "$1$i" 4.28 - done <<EOT 4.29 -/usr/bin/expand 4.30 -/usr/bin/tr 4.31 -/usr/bin/unexpand 4.32 -EOT 4.33 -}
5.1 --- a/coreutils-command/description.txt Sat May 27 16:29:45 2017 +0300 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,11 +0,0 @@ 5.4 -Coreutils: Core GNU (file, text, shell) utilities. 5.5 - 5.6 - * chroot: run command or interactive shell with special root directory 5.7 - * env: run a program in a modified environment 5.8 - * kill: send signals to processes, or list signals 5.9 - * nice: run a program with modified scheduling priority 5.10 - * nohup: run a command immune to hangups, with output to a non-tty 5.11 - * sleep: delay for a specified amount of time 5.12 - * stdbuf: run command with modified buffering operations for its standard 5.13 - streams 5.14 - * timeout: run a command with a time limit
6.1 --- a/coreutils-command/receipt Sat May 27 16:29:45 2017 +0300 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,43 +0,0 @@ 6.4 -# SliTaz package receipt. 6.5 - 6.6 -PACKAGE="coreutils-command" 6.7 -VERSION="8.25" 6.8 -CATEGORY="system-tools" 6.9 -SHORT_DESC="GNU command utilities." 6.10 -MAINTAINER="rcx@zoominternet.net" 6.11 -LICENSE="GPL3" 6.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 6.13 - 6.14 -WANTED="coreutils" 6.15 -DEPENDS="glibc-base" 6.16 - 6.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 6.18 -genpkg_rules() 6.19 -{ 6.20 - cook_copy_files env kill nice nohup sleep stdbuf timeout libstdbuf.so chroot 6.21 -} 6.22 - 6.23 -post_install() 6.24 -{ 6.25 - # Remove Busybox applets in order to not clash with ("/bin", "/sbin", 6.26 - # "/usr/bin" and "/usr/sbin" conflicts with the same filename) 6.27 - rm "$1/bin/kill" # for /usr/bin/kill 6.28 - rm "$1/bin/nice" # for /usr/bin/nice 6.29 - rm "$1/bin/sleep" # for /usr/bin/sleep 6.30 -} 6.31 - 6.32 -post_remove() 6.33 -{ 6.34 - # Restore all Busybox applets that have been replaced 6.35 - while read i; do 6.36 - busybox ln -s /bin/busybox "$1$i" 6.37 - done <<EOT 6.38 -/bin/kill 6.39 -/bin/nice 6.40 -/bin/sleep 6.41 -/usr/bin/env 6.42 -/usr/bin/nohup 6.43 -/usr/bin/timeout 6.44 -/usr/sbin/chroot 6.45 -EOT 6.46 -}
7.1 --- a/coreutils-conditions/description.txt Sat May 27 16:29:45 2017 +0300 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,7 +0,0 @@ 7.4 -Coreutils: Core GNU (file, text, shell) utilities. 7.5 - 7.6 - * [ exit with the status determined by expression 7.7 - * expr: evaluate expressions 7.8 - * false: do nothing, unsuccessfully 7.9 - * test: check file types and compare values 7.10 - * true: do nothing, successfully
8.1 --- a/coreutils-conditions/receipt Sat May 27 16:29:45 2017 +0300 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,32 +0,0 @@ 8.4 -# SliTaz package receipt. 8.5 - 8.6 -PACKAGE="coreutils-conditions" 8.7 -VERSION="8.25" 8.8 -CATEGORY="system-tools" 8.9 -SHORT_DESC="GNU utilities for conditions." 8.10 -MAINTAINER="rcx@zoominternet.net" 8.11 -LICENSE="GPL3" 8.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 8.13 - 8.14 -WANTED="coreutils" 8.15 -DEPENDS="glibc-base gmp" 8.16 - 8.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 8.18 -genpkg_rules() 8.19 -{ 8.20 - cook_copy_files false true [ expr test 8.21 -} 8.22 - 8.23 -post_remove() 8.24 -{ 8.25 - # Restore all Busybox applets that have been replaced 8.26 - while read i; do 8.27 - busybox ln -s /bin/busybox "$1$i" 8.28 - done <<EOT 8.29 -/bin/false 8.30 -/bin/true 8.31 -/usr/bin/[ 8.32 -/usr/bin/expr 8.33 -/usr/bin/test 8.34 -EOT 8.35 -}
9.1 --- a/coreutils-context-system/description.txt Sat May 27 16:29:45 2017 +0300 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,9 +0,0 @@ 9.4 -Coreutils: Core GNU (file, text, shell) utilities. 9.5 - 9.6 - * chcon: change file SELinux security context 9.7 - * date: print or set the system date and time 9.8 - * hostid: print the numeric identifier for the current host 9.9 - * nproc: print the number of processing units available 9.10 - * runcon: run command with specified SELinux security context 9.11 - * uname: print system information 9.12 - * uptime: tell how long the system has been running
10.1 --- a/coreutils-context-system/receipt Sat May 27 16:29:45 2017 +0300 10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 10.3 @@ -1,31 +0,0 @@ 10.4 -# SliTaz package receipt. 10.5 - 10.6 -PACKAGE="coreutils-context-system" 10.7 -VERSION="8.25" 10.8 -CATEGORY="system-tools" 10.9 -SHORT_DESC="GNU utilities related to the system context." 10.10 -MAINTAINER="rcx@zoominternet.net" 10.11 -LICENSE="GPL3" 10.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 10.13 - 10.14 -WANTED="coreutils" 10.15 -DEPENDS="glibc-base" 10.16 - 10.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 10.18 -genpkg_rules() 10.19 -{ 10.20 - cook_copy_files date uname chcon hostid nproc runcon uptime 10.21 -} 10.22 - 10.23 -post_remove() 10.24 -{ 10.25 - # Restore all Busybox applets that have been replaced 10.26 - while read i; do 10.27 - busybox ln -s /bin/busybox "$1$i" 10.28 - done <<EOT 10.29 -/bin/date 10.30 -/bin/uname 10.31 -/usr/bin/hostid 10.32 -/usr/bin/uptime 10.33 -EOT 10.34 -}
11.1 --- a/coreutils-context-user/description.txt Sat May 27 16:29:45 2017 +0300 11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3 @@ -1,10 +0,0 @@ 11.4 -Coreutils: Core GNU (file, text, shell) utilities. 11.5 - 11.6 - * groups: print the groups a user is in 11.7 - * id: print real and effective user and group IDs 11.8 - * logname: print user's login name 11.9 - * pinky: lightweight finger 11.10 - * users: print the user names of users currently logged in to the current 11.11 - host 11.12 - * who: show who is logged on 11.13 - * whoami: print effective user ID
12.1 --- a/coreutils-context-user/receipt Sat May 27 16:29:45 2017 +0300 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,33 +0,0 @@ 12.4 -# SliTaz package receipt. 12.5 - 12.6 -PACKAGE="coreutils-context-user" 12.7 -VERSION="8.25" 12.8 -CATEGORY="system-tools" 12.9 -SHORT_DESC="GNU utilities related to the user context." 12.10 -MAINTAINER="rcx@zoominternet.net" 12.11 -LICENSE="GPL3" 12.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 12.13 - 12.14 -WANTED="coreutils" 12.15 -DEPENDS="glibc-base" 12.16 - 12.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 12.18 -genpkg_rules() 12.19 -{ 12.20 - cook_copy_files groups id logname pinky users who whoami 12.21 -} 12.22 - 12.23 -post_remove() 12.24 -{ 12.25 - # Restore all Busybox applets that have been replaced 12.26 - while read i; do 12.27 - busybox ln -s /bin/busybox "$1$i" 12.28 - done <<EOT 12.29 -/usr/bin/groups 12.30 -/usr/bin/id 12.31 -/usr/bin/logname 12.32 -/usr/bin/users 12.33 -/usr/bin/who 12.34 -/usr/bin/whoami 12.35 -EOT 12.36 -}
13.1 --- a/coreutils-context-working/description.txt Sat May 27 16:29:45 2017 +0300 13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 13.3 @@ -1,6 +0,0 @@ 13.4 -Coreutils: Core GNU (file, text, shell) utilities. 13.5 - 13.6 - * printenv: print all or part of environment 13.7 - * pwd: print name of current/working directory 13.8 - * stty: change and print terminal line settings 13.9 - * tty: print the file name of the terminal connected to standard input
14.1 --- a/coreutils-context-working/receipt Sat May 27 16:29:45 2017 +0300 14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 14.3 @@ -1,38 +0,0 @@ 14.4 -# SliTaz package receipt. 14.5 - 14.6 -PACKAGE="coreutils-context-working" 14.7 -VERSION="8.25" 14.8 -CATEGORY="system-tools" 14.9 -SHORT_DESC="GNU utilities related to the working context." 14.10 -MAINTAINER="rcx@zoominternet.net" 14.11 -LICENSE="GPL3" 14.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 14.13 - 14.14 -WANTED="coreutils" 14.15 -DEPENDS="glibc-base" 14.16 - 14.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 14.18 -genpkg_rules() 14.19 -{ 14.20 - cook_copy_files pwd stty printenv tty 14.21 -} 14.22 - 14.23 -post_install() 14.24 -{ 14.25 - # Remove Busybox applets in order to not clash with ("/bin", "/sbin", 14.26 - # "/usr/bin" and "/usr/sbin" conflicts with the same filename) 14.27 - rm "$1/bin/printenv" # for /usr/bin/printenv 14.28 -} 14.29 - 14.30 -post_remove() 14.31 -{ 14.32 - # Restore all Busybox applets that have been replaced 14.33 - while read i; do 14.34 - busybox ln -s /bin/busybox "$1$i" 14.35 - done <<EOT 14.36 -/bin/printenv 14.37 -/bin/pwd 14.38 -/bin/stty 14.39 -/usr/bin/tty 14.40 -EOT 14.41 -}
15.1 --- a/coreutils-directory/description.txt Sat May 27 16:29:45 2017 +0300 15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 15.3 @@ -1,6 +0,0 @@ 15.4 -Coreutils: Core GNU (file, text, shell) utilities. 15.5 - 15.6 - * dir: list directory contents 15.7 - * dircolors: color setup for ls 15.8 - * ls: list directory contents 15.9 - * vdir: list directory contents
16.1 --- a/coreutils-directory/receipt Sat May 27 16:29:45 2017 +0300 16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 16.3 @@ -1,28 +0,0 @@ 16.4 -# SliTaz package receipt. 16.5 - 16.6 -PACKAGE="coreutils-directory" 16.7 -VERSION="8.25" 16.8 -CATEGORY="system-tools" 16.9 -SHORT_DESC="GNU utilities that list directories." 16.10 -MAINTAINER="rcx@zoominternet.net" 16.11 -LICENSE="GPL3" 16.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 16.13 - 16.14 -WANTED="coreutils" 16.15 -DEPENDS="glibc-base attr libcap" 16.16 - 16.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 16.18 -genpkg_rules() 16.19 -{ 16.20 - cook_copy_files ls dir dircolors vdir 16.21 -} 16.22 - 16.23 -post_remove() 16.24 -{ 16.25 - # Restore all Busybox applets that have been replaced 16.26 - while read i; do 16.27 - busybox ln -s /bin/busybox "$1$i" 16.28 - done <<EOT 16.29 -/bin/ls 16.30 -EOT 16.31 -}
17.1 --- a/coreutils-disk/description.txt Sat May 27 16:29:45 2017 +0300 17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 17.3 @@ -1,7 +0,0 @@ 17.4 -Coreutils: Core GNU (file, text, shell) utilities. 17.5 - 17.6 - * df: report file system disk space usage 17.7 - * du: estimate file space usage 17.8 - * stat: display file or file system status 17.9 - * sync: synchronize cached writes to persistent storage 17.10 - * truncate: shrink or extend the size of a file to the specified size
18.1 --- a/coreutils-disk/receipt Sat May 27 16:29:45 2017 +0300 18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 18.3 @@ -1,38 +0,0 @@ 18.4 -# SliTaz package receipt. 18.5 - 18.6 -PACKAGE="coreutils-disk" 18.7 -VERSION="8.25" 18.8 -CATEGORY="system-tools" 18.9 -SHORT_DESC="GNU utilities that work with disks." 18.10 -MAINTAINER="rcx@zoominternet.net" 18.11 -LICENSE="GPL3" 18.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 18.13 - 18.14 -WANTED="coreutils" 18.15 -DEPENDS="glibc-base" 18.16 - 18.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 18.18 -genpkg_rules() 18.19 -{ 18.20 - cook_copy_files df sync du stat truncate 18.21 -} 18.22 - 18.23 -post_install() 18.24 -{ 18.25 - # Remove Busybox applets in order to not clash with ("/bin", "/sbin", 18.26 - # "/usr/bin" and "/usr/sbin" conflicts with the same filename) 18.27 - rm "$1/bin/stat" # for /usr/bin/stat 18.28 -} 18.29 - 18.30 -post_remove() 18.31 -{ 18.32 - # Restore all Busybox applets that have been replaced 18.33 - while read i; do 18.34 - busybox ln -s /bin/busybox "$1$i" 18.35 - done <<EOT 18.36 -/bin/df 18.37 -/bin/stat 18.38 -/bin/sync 18.39 -/usr/bin/du 18.40 -EOT 18.41 -}
19.1 --- a/coreutils-file-attributes/description.txt Sat May 27 16:29:45 2017 +0300 19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 19.3 @@ -1,6 +0,0 @@ 19.4 -Coreutils: Core GNU (file, text, shell) utilities. 19.5 - 19.6 - * chgrp: change group ownership 19.7 - * chmod: change file mode bits 19.8 - * chown: change file owner and group 19.9 - * touch: change file timestamps
20.1 --- a/coreutils-file-attributes/receipt Sat May 27 16:29:45 2017 +0300 20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 20.3 @@ -1,38 +0,0 @@ 20.4 -# SliTaz package receipt. 20.5 - 20.6 -PACKAGE="coreutils-file-attributes" 20.7 -VERSION="8.25" 20.8 -CATEGORY="system-tools" 20.9 -SHORT_DESC="GNU utilities that change file attributes." 20.10 -MAINTAINER="rcx@zoominternet.net" 20.11 -LICENSE="GPL3" 20.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 20.13 - 20.14 -WANTED="coreutils" 20.15 -DEPENDS="glibc-base" 20.16 - 20.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 20.18 -genpkg_rules() 20.19 -{ 20.20 - cook_copy_files chgrp chmod chown touch 20.21 -} 20.22 - 20.23 -post_install() 20.24 -{ 20.25 - # Remove Busybox applets in order to not clash with ("/bin", "/sbin", 20.26 - # "/usr/bin" and "/usr/sbin" conflicts with the same filename) 20.27 - rm "$1/bin/touch" # for /usr/bin/touch 20.28 -} 20.29 - 20.30 -post_remove() 20.31 -{ 20.32 - # Restore all Busybox applets that have been replaced 20.33 - while read i; do 20.34 - busybox ln -s /bin/busybox "$1$i" 20.35 - done <<EOT 20.36 -/bin/chgrp 20.37 -/bin/chmod 20.38 -/bin/chown 20.39 -/bin/touch 20.40 -EOT 20.41 -}
21.1 --- a/coreutils-file-format/description.txt Sat May 27 16:29:45 2017 +0300 21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 21.3 @@ -1,5 +0,0 @@ 21.4 -Coreutils: Core GNU (file, text, shell) utilities. 21.5 - 21.6 - * fmt: simple optimal text formatter 21.7 - * fold: wrap each input line to fit in specified width 21.8 - * pr: convert text files for printing
22.1 --- a/coreutils-file-format/receipt Sat May 27 16:29:45 2017 +0300 22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 22.3 @@ -1,28 +0,0 @@ 22.4 -# SliTaz package receipt. 22.5 - 22.6 -PACKAGE="coreutils-file-format" 22.7 -VERSION="8.25" 22.8 -CATEGORY="system-tools" 22.9 -SHORT_DESC="GNU utilities that format file contents." 22.10 -MAINTAINER="rcx@zoominternet.net" 22.11 -LICENSE="GPL3" 22.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 22.13 - 22.14 -WANTED="coreutils" 22.15 -DEPENDS="glibc-base" 22.16 - 22.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 22.18 -genpkg_rules() 22.19 -{ 22.20 - cook_copy_files fmt fold pr 22.21 -} 22.22 - 22.23 -post_remove() 22.24 -{ 22.25 - # Restore all Busybox applets that have been replaced 22.26 - while read i; do 22.27 - busybox ln -s /bin/busybox "$1$i" 22.28 - done <<EOT 22.29 -/usr/bin/fold 22.30 -EOT 22.31 -}
23.1 --- a/coreutils-file-output-full/description.txt Sat May 27 16:29:45 2017 +0300 23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 23.3 @@ -1,8 +0,0 @@ 23.4 -Coreutils: Core GNU (file, text, shell) utilities. 23.5 - 23.6 - * base32: base32 encode/decode data and print to standard output 23.7 - * base64: base64 encode/decode data and print to standard output 23.8 - * cat: concatenate files and print on the standard output 23.9 - * nl: number lines of files 23.10 - * od: dump files in octal and other formats 23.11 - * tac: concatenate and print files in reverse
24.1 --- a/coreutils-file-output-full/receipt Sat May 27 16:29:45 2017 +0300 24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 24.3 @@ -1,38 +0,0 @@ 24.4 -# SliTaz package receipt. 24.5 - 24.6 -PACKAGE="coreutils-file-output-full" 24.7 -VERSION="8.25" 24.8 -CATEGORY="system-tools" 24.9 -SHORT_DESC="GNU utilities that output entire files." 24.10 -MAINTAINER="rcx@zoominternet.net" 24.11 -LICENSE="GPL3" 24.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 24.13 - 24.14 -WANTED="coreutils" 24.15 -DEPENDS="glibc-base" 24.16 - 24.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 24.18 -genpkg_rules() 24.19 -{ 24.20 - cook_copy_files cat base32 base64 nl od tac 24.21 -} 24.22 - 24.23 -post_install() 24.24 -{ 24.25 - # Remove Busybox applets in order to not clash with ("/bin", "/sbin", 24.26 - # "/usr/bin" and "/usr/sbin" conflicts with the same filename) 24.27 - rm "$1/bin/base64" # for /usr/bin/base64 24.28 -} 24.29 - 24.30 -post_remove() 24.31 -{ 24.32 - # Restore all Busybox applets that have been replaced 24.33 - while read i; do 24.34 - busybox ln -s /bin/busybox "$1$i" 24.35 - done <<EOT 24.36 -/bin/base64 24.37 -/bin/cat 24.38 -/usr/bin/od 24.39 -/usr/bin/tac 24.40 -EOT 24.41 -}
25.1 --- a/coreutils-file-output-part/description.txt Sat May 27 16:29:45 2017 +0300 25.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 25.3 @@ -1,6 +0,0 @@ 25.4 -Coreutils: Core GNU (file, text, shell) utilities. 25.5 - 25.6 - * csplit: split a file into sections determined by context lines 25.7 - * head: output the first part of files 25.8 - * split: split a file into pieces 25.9 - * tail: output the last part of files
26.1 --- a/coreutils-file-output-part/receipt Sat May 27 16:29:45 2017 +0300 26.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 26.3 @@ -1,30 +0,0 @@ 26.4 -# SliTaz package receipt. 26.5 - 26.6 -PACKAGE="coreutils-file-output-part" 26.7 -VERSION="8.25" 26.8 -CATEGORY="system-tools" 26.9 -SHORT_DESC="GNU utilities that output file parts." 26.10 -MAINTAINER="rcx@zoominternet.net" 26.11 -LICENSE="GPL3" 26.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 26.13 - 26.14 -WANTED="coreutils" 26.15 -DEPENDS="glibc-base" 26.16 - 26.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 26.18 -genpkg_rules() 26.19 -{ 26.20 - cook_copy_files csplit head split tail 26.21 -} 26.22 - 26.23 -post_remove() 26.24 -{ 26.25 - # Restore all Busybox applets that have been replaced 26.26 - while read i; do 26.27 - busybox ln -s /bin/busybox "$1$i" 26.28 - done <<EOT 26.29 -/usr/bin/head 26.30 -/usr/bin/split 26.31 -/usr/bin/tail 26.32 -EOT 26.33 -}
27.1 --- a/coreutils-file-sort/description.txt Sat May 27 16:29:45 2017 +0300 27.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 27.3 @@ -1,8 +0,0 @@ 27.4 -Coreutils: Core GNU (file, text, shell) utilities. 27.5 - 27.6 - * comm: compare two sorted files line by line 27.7 - * ptx: produce a permuted index of file contents 27.8 - * shuf: generate random permutations 27.9 - * sort: sort lines of text files 27.10 - * tsort: perform topological sort 27.11 - * uniq: report or omit repeated lines
28.1 --- a/coreutils-file-sort/receipt Sat May 27 16:29:45 2017 +0300 28.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 28.3 @@ -1,30 +0,0 @@ 28.4 -# SliTaz package receipt. 28.5 - 28.6 -PACKAGE="coreutils-file-sort" 28.7 -VERSION="8.25" 28.8 -CATEGORY="system-tools" 28.9 -SHORT_DESC="GNU utilities that operate on sorted files." 28.10 -MAINTAINER="rcx@zoominternet.net" 28.11 -LICENSE="GPL3" 28.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 28.13 - 28.14 -WANTED="coreutils" 28.15 -DEPENDS="glibc-base" 28.16 - 28.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 28.18 -genpkg_rules() 28.19 -{ 28.20 - cook_copy_files comm ptx shuf sort tsort uniq 28.21 -} 28.22 - 28.23 -post_remove() 28.24 -{ 28.25 - # Restore all Busybox applets that have been replaced 28.26 - while read i; do 28.27 - busybox ln -s /bin/busybox "$1$i" 28.28 - done <<EOT 28.29 -/usr/bin/comm 28.30 -/usr/bin/sort 28.31 -/usr/bin/uniq 28.32 -EOT 28.33 -}
29.1 --- a/coreutils-file-special/description.txt Sat May 27 16:29:45 2017 +0300 29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 29.3 @@ -1,12 +0,0 @@ 29.4 -Coreutils: Core GNU (file, text, shell) utilities. 29.5 - 29.6 - * link: call the link function to create a link to a file 29.7 - * ln: make links between files 29.8 - * mkdir: make directories 29.9 - * mkfifo: make FIFOs (named pipes) 29.10 - * mknod: make block or character special files 29.11 - * mktemp: create a temporary file or directory 29.12 - * readlink: print resolved symbolic links or canonical file names 29.13 - * realpath: print the resolved path 29.14 - * rmdir: remove empty directories 29.15 - * unlink: call the unlink function to remove the specified file
30.1 --- a/coreutils-file-special/receipt Sat May 27 16:29:45 2017 +0300 30.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 30.3 @@ -1,42 +0,0 @@ 30.4 -# SliTaz package receipt. 30.5 - 30.6 -PACKAGE="coreutils-file-special" 30.7 -VERSION="8.25" 30.8 -CATEGORY="system-tools" 30.9 -SHORT_DESC="GNU utilities that work with special file types." 30.10 -MAINTAINER="rcx@zoominternet.net" 30.11 -LICENSE="GPL3" 30.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 30.13 - 30.14 -WANTED="coreutils" 30.15 -DEPENDS="glibc-base" 30.16 - 30.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 30.18 -genpkg_rules() 30.19 -{ 30.20 - cook_copy_files ln mkdir mknod rmdir link mkfifo mktemp readlink realpath \ 30.21 - unlink 30.22 -} 30.23 - 30.24 -post_install() 30.25 -{ 30.26 - # Remove Busybox applets in order to not clash with ("/bin", "/sbin", 30.27 - # "/usr/bin" and "/usr/sbin" conflicts with the same filename) 30.28 - rm "$1/bin/mktemp" # for /usr/bin/mktemp 30.29 -} 30.30 - 30.31 -post_remove() 30.32 -{ 30.33 - # Restore all Busybox applets that have been replaced 30.34 - while read i; do 30.35 - busybox ln -s /bin/busybox "$1$i" 30.36 - done <<EOT 30.37 -/bin/ln 30.38 -/bin/mkdir 30.39 -/bin/mknod 30.40 -/bin/mktemp 30.41 -/bin/rmdir 30.42 -/usr/bin/mkfifo 30.43 -/usr/bin/realpath 30.44 -EOT 30.45 -}
31.1 --- a/coreutils-file-summarize/description.txt Sat May 27 16:29:45 2017 +0300 31.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 31.3 @@ -1,11 +0,0 @@ 31.4 -Coreutils: Core GNU (file, text, shell) utilities. 31.5 - 31.6 - * cksum: checksum and count the bytes in a file 31.7 - * md5sum: compute and check MD5 message digest 31.8 - * sha1sum: compute and check SHA1 message digest 31.9 - * sha224sum: compute and check SHA224 message digest 31.10 - * sha256sum: compute and check SHA256 message digest 31.11 - * sha384sum: compute and check SHA384 message digest 31.12 - * sha512sum: compute and check SHA512 message digest 31.13 - * sum: checksum and count the blocks in a file 31.14 - * wc: print newline, word, and byte counts for each file
32.1 --- a/coreutils-file-summarize/receipt Sat May 27 16:29:45 2017 +0300 32.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 32.3 @@ -1,35 +0,0 @@ 32.4 -# SliTaz package receipt. 32.5 - 32.6 -PACKAGE="coreutils-file-summarize" 32.7 -VERSION="8.25" 32.8 -CATEGORY="system-tools" 32.9 -SHORT_DESC="GNU utilities that summarize files." 32.10 -MAINTAINER="rcx@zoominternet.net" 32.11 -LICENSE="GPL3" 32.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 32.13 - 32.14 -WANTED="coreutils" 32.15 -DEPENDS="glibc-base" 32.16 - 32.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 32.18 -genpkg_rules() 32.19 -{ 32.20 - cook_copy_files cksum md5sum sha1sum sha224sum sha256sum sha384sum \ 32.21 - sha512sum sum wc 32.22 -} 32.23 - 32.24 -post_remove() 32.25 -{ 32.26 - # Restore all Busybox applets that have been replaced 32.27 - while read i; do 32.28 - busybox ln -s /bin/busybox "$1$i" 32.29 - done <<EOT 32.30 -/usr/bin/cksum 32.31 -/usr/bin/md5sum 32.32 -/usr/bin/sha1sum 32.33 -/usr/bin/sha256sum 32.34 -/usr/bin/sha512sum 32.35 -/usr/bin/sum 32.36 -/usr/bin/wc 32.37 -EOT 32.38 -}
33.1 --- a/coreutils-line/description.txt Sat May 27 16:29:45 2017 +0300 33.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 33.3 @@ -1,5 +0,0 @@ 33.4 -Coreutils: Core GNU (file, text, shell) utilities. 33.5 - 33.6 - * cut: remove sections from each line of files 33.7 - * join: join lines of two files on a common field 33.8 - * paste: merge lines of files
34.1 --- a/coreutils-line/receipt Sat May 27 16:29:45 2017 +0300 34.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 34.3 @@ -1,28 +0,0 @@ 34.4 -# SliTaz package receipt. 34.5 - 34.6 -PACKAGE="coreutils-line" 34.7 -VERSION="8.25" 34.8 -CATEGORY="system-tools" 34.9 -SHORT_DESC="GNU utilities that operate on fields within a line." 34.10 -MAINTAINER="rcx@zoominternet.net" 34.11 -LICENSE="GPL3" 34.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 34.13 - 34.14 -WANTED="coreutils" 34.15 -DEPENDS="glibc-base" 34.16 - 34.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 34.18 -genpkg_rules() 34.19 -{ 34.20 - cook_copy_files cut join paste 34.21 -} 34.22 - 34.23 -post_remove() 34.24 -{ 34.25 - # Restore all Busybox applets that have been replaced 34.26 - while read i; do 34.27 - busybox ln -s /bin/busybox "$1$i" 34.28 - done <<EOT 34.29 -/usr/bin/cut 34.30 -EOT 34.31 -}
35.1 --- a/coreutils-numeric/description.txt Sat May 27 16:29:45 2017 +0300 35.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 35.3 @@ -1,4 +0,0 @@ 35.4 -Coreutils: Core GNU (file, text, shell) utilities. 35.5 - 35.6 - * factor: factor numbers 35.7 - * seq: print a sequence of numbers
36.1 --- a/coreutils-numeric/receipt Sat May 27 16:29:45 2017 +0300 36.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 36.3 @@ -1,28 +0,0 @@ 36.4 -# SliTaz package receipt. 36.5 - 36.6 -PACKAGE="coreutils-numeric" 36.7 -VERSION="8.25" 36.8 -CATEGORY="system-tools" 36.9 -SHORT_DESC="GNU numeric utilities." 36.10 -MAINTAINER="rcx@zoominternet.net" 36.11 -LICENSE="GPL3" 36.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 36.13 - 36.14 -WANTED="coreutils" 36.15 -DEPENDS="glibc-base gmp" 36.16 - 36.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 36.18 -genpkg_rules() 36.19 -{ 36.20 - cook_copy_files factor seq 36.21 -} 36.22 - 36.23 -post_remove() 36.24 -{ 36.25 - # Restore all Busybox applets that have been replaced 36.26 - while read i; do 36.27 - busybox ln -s /bin/busybox "$1$i" 36.28 - done <<EOT 36.29 -/usr/bin/seq 36.30 -EOT 36.31 -}
37.1 --- a/coreutils-operations/description.txt Sat May 27 16:29:45 2017 +0300 37.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 37.3 @@ -1,7 +0,0 @@ 37.4 -Coreutils: Core GNU (file, text, shell) utilities. 37.5 - 37.6 - * cp: copy files and directories 37.7 - * dd: convert and copy a file 37.8 - * install: copy files and set attributes 37.9 - * mv: move (rename) files 37.10 - * shred: overwrite a file to hide its contents, and optionally delete it
38.1 --- a/coreutils-operations/receipt Sat May 27 16:29:45 2017 +0300 38.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 38.3 @@ -1,31 +0,0 @@ 38.4 -# SliTaz package receipt. 38.5 - 38.6 -PACKAGE="coreutils-operations" 38.7 -VERSION="8.25" 38.8 -CATEGORY="system-tools" 38.9 -SHORT_DESC="GNU utilities that perform basic operations." 38.10 -MAINTAINER="rcx@zoominternet.net" 38.11 -LICENSE="GPL3" 38.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 38.13 - 38.14 -WANTED="coreutils" 38.15 -DEPENDS="glibc-base acl attr" 38.16 - 38.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 38.18 -genpkg_rules() 38.19 -{ 38.20 - cook_copy_files cp dd mv install shred 38.21 -} 38.22 - 38.23 -post_remove() 38.24 -{ 38.25 - # Restore all Busybox applets that have been replaced 38.26 - while read i; do 38.27 - busybox ln -s /bin/busybox "$1$i" 38.28 - done <<EOT 38.29 -/bin/cp 38.30 -/bin/dd 38.31 -/bin/mv 38.32 -/usr/bin/install 38.33 -EOT 38.34 -}
39.1 --- a/coreutils-path/description.txt Sat May 27 16:29:45 2017 +0300 39.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 39.3 @@ -1,5 +0,0 @@ 39.4 -Coreutils: Core GNU (file, text, shell) utilities. 39.5 - 39.6 - * basename: strip directory and suffix from filenames 39.7 - * dirname: strip last component from file name 39.8 - * pathchk: check whether file names are valid or portable
40.1 --- a/coreutils-path/receipt Sat May 27 16:29:45 2017 +0300 40.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 40.3 @@ -1,29 +0,0 @@ 40.4 -# SliTaz package receipt. 40.5 - 40.6 -PACKAGE="coreutils-path" 40.7 -VERSION="8.25" 40.8 -CATEGORY="system-tools" 40.9 -SHORT_DESC="GNU utilities that perform path manipulation." 40.10 -MAINTAINER="rcx@zoominternet.net" 40.11 -LICENSE="GPL3" 40.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 40.13 - 40.14 -WANTED="coreutils" 40.15 -DEPENDS="glibc-base" 40.16 - 40.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 40.18 -genpkg_rules() 40.19 -{ 40.20 - cook_copy_files basename dirname pathchk 40.21 -} 40.22 - 40.23 -post_remove() 40.24 -{ 40.25 - # Restore all Busybox applets that have been replaced 40.26 - while read i; do 40.27 - busybox ln -s /bin/busybox "$1$i" 40.28 - done <<EOT 40.29 -/usr/bin/basename 40.30 -/usr/bin/dirname 40.31 -EOT 40.32 -}
41.1 --- a/coreutils-print/description.txt Sat May 27 16:29:45 2017 +0300 41.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 41.3 @@ -1,6 +0,0 @@ 41.4 -Coreutils: Core GNU (file, text, shell) utilities. 41.5 - 41.6 - * echo: display a line of text 41.7 - * numfmt: convert numbers from/to human-readable strings 41.8 - * printf: format and print data 41.9 - * yes: output a string repeatedly until killed
42.1 --- a/coreutils-print/receipt Sat May 27 16:29:45 2017 +0300 42.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 42.3 @@ -1,30 +0,0 @@ 42.4 -# SliTaz package receipt. 42.5 - 42.6 -PACKAGE="coreutils-print" 42.7 -VERSION="8.25" 42.8 -CATEGORY="system-tools" 42.9 -SHORT_DESC="GNU utilities that print text." 42.10 -MAINTAINER="rcx@zoominternet.net" 42.11 -LICENSE="GPL3" 42.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 42.13 - 42.14 -WANTED="coreutils" 42.15 -DEPENDS="glibc-base" 42.16 - 42.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 42.18 -genpkg_rules() 42.19 -{ 42.20 - cook_copy_files echo numfmt printf yes 42.21 -} 42.22 - 42.23 -post_remove() 42.24 -{ 42.25 - # Restore all Busybox applets that have been replaced 42.26 - while read i; do 42.27 - busybox ln -s /bin/busybox "$1$i" 42.28 - done <<EOT 42.29 -/bin/echo 42.30 -/bin/printf 42.31 -/bin/yes 42.32 -EOT 42.33 -}
43.1 --- a/coreutils-redirection/description.txt Sat May 27 16:29:45 2017 +0300 43.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 43.3 @@ -1,3 +0,0 @@ 43.4 -Coreutils: Core GNU (file, text, shell) utilities. 43.5 - 43.6 - * tee: read from standard input and write to standard output and files
44.1 --- a/coreutils-redirection/receipt Sat May 27 16:29:45 2017 +0300 44.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 44.3 @@ -1,28 +0,0 @@ 44.4 -# SliTaz package receipt. 44.5 - 44.6 -PACKAGE="coreutils-redirection" 44.7 -VERSION="8.25" 44.8 -CATEGORY="system-tools" 44.9 -SHORT_DESC="GNU utilities that work with disks." 44.10 -MAINTAINER="rcx@zoominternet.net" 44.11 -LICENSE="GPL3" 44.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 44.13 - 44.14 -WANTED="coreutils" 44.15 -DEPENDS="glibc-base" 44.16 - 44.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 44.18 -genpkg_rules() 44.19 -{ 44.20 - cook_copy_files tee 44.21 -} 44.22 - 44.23 -post_remove() 44.24 -{ 44.25 - # Restore all Busybox applets that have been replaced 44.26 - while read i; do 44.27 - busybox ln -s /bin/busybox "$1$i" 44.28 - done <<EOT 44.29 -/usr/bin/tee 44.30 -EOT 44.31 -}
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/coreutils/description.coreutils-character.txt Sat May 27 16:55:17 2017 +0300 45.3 @@ -0,0 +1,5 @@ 45.4 +Coreutils: Core GNU (file, text, shell) utilities. 45.5 + 45.6 + * expand: convert tabs to spaces 45.7 + * tr: translate or delete characters 45.8 + * unexpand: convert spaces to tabs
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/coreutils/description.coreutils-command.txt Sat May 27 16:55:17 2017 +0300 46.3 @@ -0,0 +1,11 @@ 46.4 +Coreutils: Core GNU (file, text, shell) utilities. 46.5 + 46.6 + * chroot: run command or interactive shell with special root directory 46.7 + * env: run a program in a modified environment 46.8 + * kill: send signals to processes, or list signals 46.9 + * nice: run a program with modified scheduling priority 46.10 + * nohup: run a command immune to hangups, with output to a non-tty 46.11 + * sleep: delay for a specified amount of time 46.12 + * stdbuf: run command with modified buffering operations for its standard 46.13 + streams 46.14 + * timeout: run a command with a time limit
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/coreutils/description.coreutils-conditions.txt Sat May 27 16:55:17 2017 +0300 47.3 @@ -0,0 +1,7 @@ 47.4 +Coreutils: Core GNU (file, text, shell) utilities. 47.5 + 47.6 + * [ exit with the status determined by expression 47.7 + * expr: evaluate expressions 47.8 + * false: do nothing, unsuccessfully 47.9 + * test: check file types and compare values 47.10 + * true: do nothing, successfully
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/coreutils/description.coreutils-context-system.txt Sat May 27 16:55:17 2017 +0300 48.3 @@ -0,0 +1,9 @@ 48.4 +Coreutils: Core GNU (file, text, shell) utilities. 48.5 + 48.6 + * chcon: change file SELinux security context 48.7 + * date: print or set the system date and time 48.8 + * hostid: print the numeric identifier for the current host 48.9 + * nproc: print the number of processing units available 48.10 + * runcon: run command with specified SELinux security context 48.11 + * uname: print system information 48.12 + * uptime: tell how long the system has been running
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 49.2 +++ b/coreutils/description.coreutils-context-user.txt Sat May 27 16:55:17 2017 +0300 49.3 @@ -0,0 +1,10 @@ 49.4 +Coreutils: Core GNU (file, text, shell) utilities. 49.5 + 49.6 + * groups: print the groups a user is in 49.7 + * id: print real and effective user and group IDs 49.8 + * logname: print user's login name 49.9 + * pinky: lightweight finger 49.10 + * users: print the user names of users currently logged in to the current 49.11 + host 49.12 + * who: show who is logged on 49.13 + * whoami: print effective user ID
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2 +++ b/coreutils/description.coreutils-context-working.txt Sat May 27 16:55:17 2017 +0300 50.3 @@ -0,0 +1,6 @@ 50.4 +Coreutils: Core GNU (file, text, shell) utilities. 50.5 + 50.6 + * printenv: print all or part of environment 50.7 + * pwd: print name of current/working directory 50.8 + * stty: change and print terminal line settings 50.9 + * tty: print the file name of the terminal connected to standard input
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2 +++ b/coreutils/description.coreutils-directory.txt Sat May 27 16:55:17 2017 +0300 51.3 @@ -0,0 +1,6 @@ 51.4 +Coreutils: Core GNU (file, text, shell) utilities. 51.5 + 51.6 + * dir: list directory contents 51.7 + * dircolors: color setup for ls 51.8 + * ls: list directory contents 51.9 + * vdir: list directory contents
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 52.2 +++ b/coreutils/description.coreutils-disk.txt Sat May 27 16:55:17 2017 +0300 52.3 @@ -0,0 +1,7 @@ 52.4 +Coreutils: Core GNU (file, text, shell) utilities. 52.5 + 52.6 + * df: report file system disk space usage 52.7 + * du: estimate file space usage 52.8 + * stat: display file or file system status 52.9 + * sync: synchronize cached writes to persistent storage 52.10 + * truncate: shrink or extend the size of a file to the specified size
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/coreutils/description.coreutils-file-attributes.txt Sat May 27 16:55:17 2017 +0300 53.3 @@ -0,0 +1,6 @@ 53.4 +Coreutils: Core GNU (file, text, shell) utilities. 53.5 + 53.6 + * chgrp: change group ownership 53.7 + * chmod: change file mode bits 53.8 + * chown: change file owner and group 53.9 + * touch: change file timestamps
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 54.2 +++ b/coreutils/description.coreutils-file-format.txt Sat May 27 16:55:17 2017 +0300 54.3 @@ -0,0 +1,5 @@ 54.4 +Coreutils: Core GNU (file, text, shell) utilities. 54.5 + 54.6 + * fmt: simple optimal text formatter 54.7 + * fold: wrap each input line to fit in specified width 54.8 + * pr: convert text files for printing
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 55.2 +++ b/coreutils/description.coreutils-file-output-full.txt Sat May 27 16:55:17 2017 +0300 55.3 @@ -0,0 +1,8 @@ 55.4 +Coreutils: Core GNU (file, text, shell) utilities. 55.5 + 55.6 + * base32: base32 encode/decode data and print to standard output 55.7 + * base64: base64 encode/decode data and print to standard output 55.8 + * cat: concatenate files and print on the standard output 55.9 + * nl: number lines of files 55.10 + * od: dump files in octal and other formats 55.11 + * tac: concatenate and print files in reverse
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 56.2 +++ b/coreutils/description.coreutils-file-output-part.txt Sat May 27 16:55:17 2017 +0300 56.3 @@ -0,0 +1,6 @@ 56.4 +Coreutils: Core GNU (file, text, shell) utilities. 56.5 + 56.6 + * csplit: split a file into sections determined by context lines 56.7 + * head: output the first part of files 56.8 + * split: split a file into pieces 56.9 + * tail: output the last part of files
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 57.2 +++ b/coreutils/description.coreutils-file-sort.txt Sat May 27 16:55:17 2017 +0300 57.3 @@ -0,0 +1,8 @@ 57.4 +Coreutils: Core GNU (file, text, shell) utilities. 57.5 + 57.6 + * comm: compare two sorted files line by line 57.7 + * ptx: produce a permuted index of file contents 57.8 + * shuf: generate random permutations 57.9 + * sort: sort lines of text files 57.10 + * tsort: perform topological sort 57.11 + * uniq: report or omit repeated lines
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2 +++ b/coreutils/description.coreutils-file-special.txt Sat May 27 16:55:17 2017 +0300 58.3 @@ -0,0 +1,12 @@ 58.4 +Coreutils: Core GNU (file, text, shell) utilities. 58.5 + 58.6 + * link: call the link function to create a link to a file 58.7 + * ln: make links between files 58.8 + * mkdir: make directories 58.9 + * mkfifo: make FIFOs (named pipes) 58.10 + * mknod: make block or character special files 58.11 + * mktemp: create a temporary file or directory 58.12 + * readlink: print resolved symbolic links or canonical file names 58.13 + * realpath: print the resolved path 58.14 + * rmdir: remove empty directories 58.15 + * unlink: call the unlink function to remove the specified file
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 59.2 +++ b/coreutils/description.coreutils-file-summarize.txt Sat May 27 16:55:17 2017 +0300 59.3 @@ -0,0 +1,11 @@ 59.4 +Coreutils: Core GNU (file, text, shell) utilities. 59.5 + 59.6 + * cksum: checksum and count the bytes in a file 59.7 + * md5sum: compute and check MD5 message digest 59.8 + * sha1sum: compute and check SHA1 message digest 59.9 + * sha224sum: compute and check SHA224 message digest 59.10 + * sha256sum: compute and check SHA256 message digest 59.11 + * sha384sum: compute and check SHA384 message digest 59.12 + * sha512sum: compute and check SHA512 message digest 59.13 + * sum: checksum and count the blocks in a file 59.14 + * wc: print newline, word, and byte counts for each file
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 60.2 +++ b/coreutils/description.coreutils-line.txt Sat May 27 16:55:17 2017 +0300 60.3 @@ -0,0 +1,5 @@ 60.4 +Coreutils: Core GNU (file, text, shell) utilities. 60.5 + 60.6 + * cut: remove sections from each line of files 60.7 + * join: join lines of two files on a common field 60.8 + * paste: merge lines of files
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2 +++ b/coreutils/description.coreutils-numeric.txt Sat May 27 16:55:17 2017 +0300 61.3 @@ -0,0 +1,4 @@ 61.4 +Coreutils: Core GNU (file, text, shell) utilities. 61.5 + 61.6 + * factor: factor numbers 61.7 + * seq: print a sequence of numbers
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2 +++ b/coreutils/description.coreutils-operations.txt Sat May 27 16:55:17 2017 +0300 62.3 @@ -0,0 +1,8 @@ 62.4 +Coreutils: Core GNU (file, text, shell) utilities. 62.5 + 62.6 + * cp: copy files and directories 62.7 + * dd: convert and copy a file 62.8 + * install: copy files and set attributes 62.9 + * mv: move (rename) files 62.10 + * rm: removes files or directories 62.11 + * shred: overwrite a file to hide its contents, and optionally delete it
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/coreutils/description.coreutils-path.txt Sat May 27 16:55:17 2017 +0300 63.3 @@ -0,0 +1,5 @@ 63.4 +Coreutils: Core GNU (file, text, shell) utilities. 63.5 + 63.6 + * basename: strip directory and suffix from filenames 63.7 + * dirname: strip last component from file name 63.8 + * pathchk: check whether file names are valid or portable
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 64.2 +++ b/coreutils/description.coreutils-print.txt Sat May 27 16:55:17 2017 +0300 64.3 @@ -0,0 +1,6 @@ 64.4 +Coreutils: Core GNU (file, text, shell) utilities. 64.5 + 64.6 + * echo: display a line of text 64.7 + * numfmt: convert numbers from/to human-readable strings 64.8 + * printf: format and print data 64.9 + * yes: output a string repeatedly until killed
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 65.2 +++ b/coreutils/description.coreutils-redirection.txt Sat May 27 16:55:17 2017 +0300 65.3 @@ -0,0 +1,3 @@ 65.4 +Coreutils: Core GNU (file, text, shell) utilities. 65.5 + 65.6 + * tee: read from standard input and write to standard output and files
66.1 --- a/coreutils/description.txt Sat May 27 16:29:45 2017 +0300 66.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 66.3 @@ -1,17 +0,0 @@ 66.4 -Coreutils: Core GNU (file, text, shell) utilities. 66.5 - 66.6 - * base64: base64 encode/decode data and print to standard output 66.7 - * cp: copy files and directories 66.8 - * csplit: split a file into sections determined by context lines 66.9 - * factor: factor numbers 66.10 - * fmt: simple optimal text formatter 66.11 - * groups: print the groups a user is in 66.12 - * join: join lines of two files on a common field 66.13 - * od: dump files in octal and other formats 66.14 - * paste: merge lines of files 66.15 - * ptx: produce a permuted index of file contents 66.16 - * shred: overwrite a file to hide its contents, and optionally delete it 66.17 - * shuf: generate random permutations 66.18 - * split: split a file into pieces 66.19 - * users: print the user names of users currently logged in to the current 66.20 - host
67.1 --- a/coreutils/receipt Sat May 27 16:29:45 2017 +0300 67.2 +++ b/coreutils/receipt Sat May 27 16:55:17 2017 +0300 67.3 @@ -1,9 +1,9 @@ 67.4 -# SliTaz package receipt. 67.5 +# SliTaz package receipt v2. 67.6 67.7 PACKAGE="coreutils" 67.8 VERSION="8.25" 67.9 CATEGORY="meta" 67.10 -SHORT_DESC="Utilities for using and setting the basic system." 67.11 +SHORT_DESC="Utilities for using and setting the basic system" 67.12 MAINTAINER="pankso@slitaz.org" 67.13 LICENSE="GPL3" 67.14 WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 67.15 @@ -12,6 +12,7 @@ 67.16 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 67.17 67.18 SIBLINGS="coreutils-multicall" 67.19 +BUILD_DEPENDS="automake autoconf gettext xz libcap-dev gmp-dev patch" 67.20 SPLIT="coreutils-character coreutils-command coreutils-conditions coreutils-\ 67.21 context-system coreutils-context-user coreutils-context-working coreutils-\ 67.22 directory coreutils-disk coreutils-file-attributes coreutils-file-format \ 67.23 @@ -19,18 +20,11 @@ 67.24 coreutils-file-special coreutils-file-summarize coreutils-line coreutils-\ 67.25 numeric coreutils-operations coreutils-path coreutils-print coreutils-\ 67.26 redirection" 67.27 -DEPENDS="glibc-base acl attr gmp $SPLIT" 67.28 -BUILD_DEPENDS="automake autoconf gettext xz libcap-dev gmp-dev patch" 67.29 67.30 # Rules to configure and make the package. 67.31 compile_rules() 67.32 { 67.33 - # LFS: Coreutils Internationalization Fixes Patch 67.34 - patch -Np1 -i $stuff/coreutils-8.25-i18n-2.patch 67.35 - # SliTaz: show extended info touching CPU via uname 67.36 - patch -p1 -i $stuff/uname.u 67.37 - # SliTaz: fix translations, especially deprecated symbol '\v' 67.38 - patch -p1 -i $stuff/coreutils-fix-po.patch 67.39 + # Rebuild fixed translations 67.40 msgfmt po/nb.po -o po/nb.gmo 67.41 msgfmt po/sl.po -o po/sl.gmo 67.42 67.43 @@ -53,3 +47,125 @@ 67.44 $install/usr/share/man/man8/chroot.8 67.45 sed -i 's|"1"|"8"|' $install/usr/share/man/man8/chroot.8 67.46 } 67.47 + 67.48 +# Rules to gen a SliTaz package suitable for Tazpkg. 67.49 +genpkg_rules() 67.50 +{ 67.51 + case $PACKAGE in 67.52 + coreutils) 67.53 + DEPENDS="$SPLIT" ;; 67.54 + coreutils-character) 67.55 + copy expand tr unexpand 67.56 + CAT="system-tools|operate on characters" 67.57 + DEPENDS="glibc-base" ;; 67.58 + coreutils-command) 67.59 + copy env kill nice nohup sleep stdbuf timeout libstdbuf.so chroot 67.60 + CAT="system-tools|commands" 67.61 + DEPENDS="glibc-base" ;; 67.62 + coreutils-conditions) 67.63 + copy false true [ expr test 67.64 + CAT="system-tools|conditions" 67.65 + DEPENDS="glibc-base gmp" ;; 67.66 + coreutils-context-system) 67.67 + copy date uname chcon hostid nproc runcon uptime 67.68 + CAT="system-tools|system context" 67.69 + DEPENDS="glibc-base" ;; 67.70 + coreutils-context-user) 67.71 + copy groups id logname pinky users who whoami 67.72 + CAT="system-tools|user context" 67.73 + DEPENDS="glibc-base" ;; 67.74 + coreutils-context-working) 67.75 + copy pwd stty printenv tty 67.76 + CAT="system-tools|working context" 67.77 + DEPENDS="glibc-base" ;; 67.78 + coreutils-directory) 67.79 + copy ls dir dircolors vdir 67.80 + CAT="system-tools|list directories" 67.81 + DEPENDS="glibc-base attr libcap" ;; 67.82 + coreutils-disk) 67.83 + copy df sync du stat truncate 67.84 + CAT="system-tools|work with disks" 67.85 + DEPENDS="glibc-base" ;; 67.86 + coreutils-file-attributes) 67.87 + copy chgrp chmod chown touch 67.88 + CAT="system-tools|change file attributes" 67.89 + DEPENDS="glibc-base" ;; 67.90 + coreutils-file-format) 67.91 + copy fmt fold pr 67.92 + CAT="system-tools|format file contents" 67.93 + DEPENDS="glibc-base" ;; 67.94 + coreutils-file-output-full) 67.95 + copy cat base32 base64 nl od tac 67.96 + CAT="system-tools|output entire files" 67.97 + DEPENDS="glibc-base" ;; 67.98 + coreutils-file-output-part) 67.99 + copy csplit head split tail 67.100 + CAT="system-tools|output file parts" 67.101 + DEPENDS="glibc-base" ;; 67.102 + coreutils-file-sort) 67.103 + copy comm ptx shuf sort tsort uniq 67.104 + CAT="system-tools|operate on sorted files" 67.105 + DEPENDS="glibc-base" ;; 67.106 + coreutils-file-special) 67.107 + copy ln mkdir mknod rmdir link mkfifo mktemp readlink realpath unlink 67.108 + CAT="system-tools|work with special file types" 67.109 + DEPENDS="glibc-base" ;; 67.110 + coreutils-file-summarize) 67.111 + copy cksum md5sum sha1sum sha224sum sha256sum sha384sum sha512sum sum wc 67.112 + CAT="system-tools|summarize files" 67.113 + DEPENDS="glibc-base" ;; 67.114 + coreutils-line) 67.115 + copy cut join paste 67.116 + CAT="system-tools|operate on fields within a line" 67.117 + DEPENDS="glibc-base" ;; 67.118 + coreutils-numeric) 67.119 + copy factor seq 67.120 + CAT="system-tools|numeric" 67.121 + DEPENDS="glibc-base gmp" ;; 67.122 + coreutils-operations) 67.123 + copy cp dd mv install rm shred 67.124 + CAT="system-tools|perform basic operations" 67.125 + DEPENDS="glibc-base acl attr" ;; 67.126 + coreutils-path) 67.127 + copy basename dirname pathchk 67.128 + CAT="system-tools|perform path manipulation" 67.129 + DEPENDS="glibc-base" ;; 67.130 + coreutils-print) 67.131 + copy echo numfmt printf yes 67.132 + CAT="system-tools|print text" 67.133 + DEPENDS="glibc-base" ;; 67.134 + coreutils-redirection) 67.135 + copy tee 67.136 + CAT="system-tools|redirection" 67.137 + DEPENDS="glibc-base" ;; 67.138 + esac 67.139 +} 67.140 + 67.141 +# Remove Busybox applets in order to not clash with ("/bin", "/sbin", 67.142 +# "/usr/bin" and "/usr/sbin" conflicts with the same filename) 67.143 +post_install_coreutils_command() 67.144 +{ 67.145 + rm "$1/bin/kill" # for /usr/bin/kill 67.146 + rm "$1/bin/nice" # for /usr/bin/nice 67.147 + rm "$1/bin/sleep" # for /usr/bin/sleep 67.148 +} 67.149 +post_install_coreutils_context_working() 67.150 +{ 67.151 + rm "$1/bin/printenv" # for /usr/bin/printenv 67.152 +} 67.153 +post_install_coreutils_disk() 67.154 +{ 67.155 + rm "$1/bin/stat" # for /usr/bin/stat 67.156 +} 67.157 +post_install_coreutils_file_attributes() 67.158 +{ 67.159 + rm "$1/bin/touch" # for /usr/bin/touch 67.160 +} 67.161 +post_install_coreutils_file_output_full() 67.162 +{ 67.163 + rm "$1/bin/base64" # for /usr/bin/base64 67.164 +} 67.165 +post_install_coreutils_file_special() 67.166 +{ 67.167 + rm "$1/bin/mktemp" # for /usr/bin/mktemp 67.168 +}
68.1 --- a/coreutils/stuff/coreutils-8.25-i18n-2.patch Sat May 27 16:29:45 2017 +0300 68.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 68.3 @@ -1,4790 +0,0 @@ 68.4 -Submitted by: DJ Lucas (dj_AT_linuxfromscratch_DOT_org) 68.5 -Date: 2016-02-09 68.6 -Initial Package Version: 8.25 68.7 -Upstream Status: Rejected 68.8 -Origin: Based on Suse's i18n patches at https://build.opensuse.org/package/view_file/Base:System/coreutils/coreutils-i18n.patch 68.9 -Description: Fixes several i18n issues with various Coreutils programs 68.10 - 68.11 -diff -Naurp coreutils-8.25-orig/lib/linebuffer.h coreutils-8.25/lib/linebuffer.h 68.12 ---- coreutils-8.25-orig/lib/linebuffer.h 2016-01-01 07:45:55.000000000 -0600 68.13 -+++ coreutils-8.25/lib/linebuffer.h 2016-02-08 19:07:10.298944609 -0600 68.14 -@@ -21,6 +21,11 @@ 68.15 - 68.16 - # include <stdio.h> 68.17 - 68.18 -+/* Get mbstate_t. */ 68.19 -+# if HAVE_WCHAR_H 68.20 -+# include <wchar.h> 68.21 -+# endif 68.22 -+ 68.23 - /* A 'struct linebuffer' holds a line of text. */ 68.24 - 68.25 - struct linebuffer 68.26 -@@ -28,6 +33,9 @@ struct linebuffer 68.27 - size_t size; /* Allocated. */ 68.28 - size_t length; /* Used. */ 68.29 - char *buffer; 68.30 -+# if HAVE_WCHAR_H 68.31 -+ mbstate_t state; 68.32 -+# endif 68.33 - }; 68.34 - 68.35 - /* Initialize linebuffer LINEBUFFER for use. */ 68.36 -diff -Naurp coreutils-8.25-orig/src/cut.c coreutils-8.25/src/cut.c 68.37 ---- coreutils-8.25-orig/src/cut.c 2016-01-13 05:08:59.000000000 -0600 68.38 -+++ coreutils-8.25/src/cut.c 2016-02-08 19:07:10.300944616 -0600 68.39 -@@ -28,6 +28,11 @@ 68.40 - #include <assert.h> 68.41 - #include <getopt.h> 68.42 - #include <sys/types.h> 68.43 -+ 68.44 -+/* Get mbstate_t, mbrtowc(). */ 68.45 -+#if HAVE_WCHAR_H 68.46 -+# include <wchar.h> 68.47 -+#endif 68.48 - #include "system.h" 68.49 - 68.50 - #include "error.h" 68.51 -@@ -38,6 +43,18 @@ 68.52 - 68.53 - #include "set-fields.h" 68.54 - 68.55 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 68.56 -+ installation; work around this configuration error. */ 68.57 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 68.58 -+# undef MB_LEN_MAX 68.59 -+# define MB_LEN_MAX 16 68.60 -+#endif 68.61 -+ 68.62 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 68.63 -+#if HAVE_MBRTOWC && defined mbstate_t 68.64 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 68.65 -+#endif 68.66 -+ 68.67 - /* The official name of this program (e.g., no 'g' prefix). */ 68.68 - #define PROGRAM_NAME "cut" 68.69 - 68.70 -@@ -54,6 +71,52 @@ 68.71 - } \ 68.72 - while (0) 68.73 - 68.74 -+/* Refill the buffer BUF to get a multibyte character. */ 68.75 -+#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM) \ 68.76 -+ do \ 68.77 -+ { \ 68.78 -+ if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM)) \ 68.79 -+ { \ 68.80 -+ memmove (BUF, BUFPOS, BUFLEN); \ 68.81 -+ BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \ 68.82 -+ BUFPOS = BUF; \ 68.83 -+ } \ 68.84 -+ } \ 68.85 -+ while (0) 68.86 -+ 68.87 -+/* Get wide character on BUFPOS. BUFPOS is not included after that. 68.88 -+ If byte sequence is not valid as a character, CONVFAIL is true. Otherwise false. */ 68.89 -+#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ 68.90 -+ do \ 68.91 -+ { \ 68.92 -+ mbstate_t state_bak; \ 68.93 -+ \ 68.94 -+ if (BUFLEN < 1) \ 68.95 -+ { \ 68.96 -+ WC = WEOF; \ 68.97 -+ break; \ 68.98 -+ } \ 68.99 -+ \ 68.100 -+ /* Get a wide character. */ \ 68.101 -+ CONVFAIL = false; \ 68.102 -+ state_bak = STATE; \ 68.103 -+ MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \ 68.104 -+ \ 68.105 -+ switch (MBLENGTH) \ 68.106 -+ { \ 68.107 -+ case (size_t)-1: \ 68.108 -+ case (size_t)-2: \ 68.109 -+ CONVFAIL = true; \ 68.110 -+ STATE = state_bak; \ 68.111 -+ /* Fall througn. */ \ 68.112 -+ \ 68.113 -+ case 0: \ 68.114 -+ MBLENGTH = 1; \ 68.115 -+ break; \ 68.116 -+ } \ 68.117 -+ } \ 68.118 -+ while (0) 68.119 -+ 68.120 - 68.121 - /* Pointer inside RP. When checking if a byte or field is selected 68.122 - by a finite range, we check if it is between CURRENT_RP.LO 68.123 -@@ -61,6 +124,9 @@ 68.124 - CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ 68.125 - static struct field_range_pair *current_rp; 68.126 - 68.127 -+/* Length of the delimiter given as argument to -d. */ 68.128 -+size_t delimlen; 68.129 -+ 68.130 - /* This buffer is used to support the semantics of the -s option 68.131 - (or lack of same) when the specified field list includes (does 68.132 - not include) the first field. In both of those cases, the entire 68.133 -@@ -77,15 +143,25 @@ enum operating_mode 68.134 - { 68.135 - undefined_mode, 68.136 - 68.137 -- /* Output characters that are in the given bytes. */ 68.138 -+ /* Output bytes that are at the given positions. */ 68.139 - byte_mode, 68.140 - 68.141 -+ /* Output characters that are at the given positions. */ 68.142 -+ character_mode, 68.143 -+ 68.144 - /* Output the given delimiter-separated fields. */ 68.145 - field_mode 68.146 - }; 68.147 - 68.148 - static enum operating_mode operating_mode; 68.149 - 68.150 -+/* If nonzero, when in byte mode, don't split multibyte characters. */ 68.151 -+static int byte_mode_character_aware; 68.152 -+ 68.153 -+/* If nonzero, the function for single byte locale is work 68.154 -+ if this program runs on multibyte locale. */ 68.155 -+static int force_singlebyte_mode; 68.156 -+ 68.157 - /* If true do not output lines containing no delimiter characters. 68.158 - Otherwise, all such lines are printed. This option is valid only 68.159 - with field mode. */ 68.160 -@@ -97,6 +173,9 @@ static bool complement; 68.161 - 68.162 - /* The delimiter character for field mode. */ 68.163 - static unsigned char delim; 68.164 -+#if HAVE_WCHAR_H 68.165 -+static wchar_t wcdelim; 68.166 -+#endif 68.167 - 68.168 - /* The delimiter for each line/record. */ 68.169 - static unsigned char line_delim = '\n'; 68.170 -@@ -164,7 +243,7 @@ Print selected parts of lines from each 68.171 - -f, --fields=LIST select only these fields; also print any line\n\ 68.172 - that contains no delimiter character, unless\n\ 68.173 - the -s option is specified\n\ 68.174 -- -n (ignored)\n\ 68.175 -+ -n with -b: don't split multibyte characters\n\ 68.176 - "), stdout); 68.177 - fputs (_("\ 68.178 - --complement complement the set of selected bytes, characters\n\ 68.179 -@@ -280,6 +359,82 @@ cut_bytes (FILE *stream) 68.180 - } 68.181 - } 68.182 - 68.183 -+#if HAVE_MBRTOWC 68.184 -+/* This function is in use for the following case. 68.185 -+ 68.186 -+ 1. Read from the stream STREAM, printing to standard output any selected 68.187 -+ characters. 68.188 -+ 68.189 -+ 2. Read from stream STREAM, printing to standard output any selected bytes, 68.190 -+ without splitting multibyte characters. */ 68.191 -+ 68.192 -+static void 68.193 -+cut_characters_or_cut_bytes_no_split (FILE *stream) 68.194 -+{ 68.195 -+ size_t idx; /* number of bytes or characters in the line so far. */ 68.196 -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 68.197 -+ char *bufpos; /* Next read position of BUF. */ 68.198 -+ size_t buflen; /* The length of the byte sequence in buf. */ 68.199 -+ wint_t wc; /* A gotten wide character. */ 68.200 -+ size_t mblength; /* The byte size of a multibyte character which shows 68.201 -+ as same character as WC. */ 68.202 -+ mbstate_t state; /* State of the stream. */ 68.203 -+ bool convfail = false; /* true, when conversion failed. Otherwise false. */ 68.204 -+ /* Whether to begin printing delimiters between ranges for the current line. 68.205 -+ Set after we've begun printing data corresponding to the first range. */ 68.206 -+ bool print_delimiter = false; 68.207 -+ 68.208 -+ idx = 0; 68.209 -+ buflen = 0; 68.210 -+ bufpos = buf; 68.211 -+ memset (&state, '\0', sizeof(mbstate_t)); 68.212 -+ 68.213 -+ current_rp = frp; 68.214 -+ 68.215 -+ while (1) 68.216 -+ { 68.217 -+ REFILL_BUFFER (buf, bufpos, buflen, stream); 68.218 -+ 68.219 -+ GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); 68.220 -+ (void) convfail; /* ignore unused */ 68.221 -+ 68.222 -+ if (wc == WEOF) 68.223 -+ { 68.224 -+ if (idx > 0) 68.225 -+ putchar (line_delim); 68.226 -+ break; 68.227 -+ } 68.228 -+ else if (wc == line_delim) 68.229 -+ { 68.230 -+ putchar (line_delim); 68.231 -+ idx = 0; 68.232 -+ print_delimiter = false; 68.233 -+ current_rp = frp; 68.234 -+ } 68.235 -+ else 68.236 -+ { 68.237 -+ next_item (&idx); 68.238 -+ if (print_kth (idx)) 68.239 -+ { 68.240 -+ if (output_delimiter_specified) 68.241 -+ { 68.242 -+ if (print_delimiter && is_range_start_index (idx)) 68.243 -+ { 68.244 -+ fwrite (output_delimiter_string, sizeof (char), 68.245 -+ output_delimiter_length, stdout); 68.246 -+ } 68.247 -+ print_delimiter = true; 68.248 -+ } 68.249 -+ fwrite (bufpos, mblength, sizeof(char), stdout); 68.250 -+ } 68.251 -+ } 68.252 -+ 68.253 -+ buflen -= mblength; 68.254 -+ bufpos += mblength; 68.255 -+ } 68.256 -+} 68.257 -+#endif 68.258 -+ 68.259 - /* Read from stream STREAM, printing to standard output any selected fields. */ 68.260 - 68.261 - static void 68.262 -@@ -425,13 +580,211 @@ cut_fields (FILE *stream) 68.263 - } 68.264 - } 68.265 - 68.266 -+#if HAVE_MBRTOWC 68.267 -+static void 68.268 -+cut_fields_mb (FILE *stream) 68.269 -+{ 68.270 -+ int c; 68.271 -+ size_t field_idx; 68.272 -+ int found_any_selected_field; 68.273 -+ int buffer_first_field; 68.274 -+ int empty_input; 68.275 -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 68.276 -+ char *bufpos; /* Next read position of BUF. */ 68.277 -+ size_t buflen; /* The length of the byte sequence in buf. */ 68.278 -+ wint_t wc = 0; /* A gotten wide character. */ 68.279 -+ size_t mblength; /* The byte size of a multibyte character which shows 68.280 -+ as same character as WC. */ 68.281 -+ mbstate_t state; /* State of the stream. */ 68.282 -+ bool convfail = false; /* true, when conversion failed. Otherwise false. */ 68.283 -+ 68.284 -+ current_rp = frp; 68.285 -+ 68.286 -+ found_any_selected_field = 0; 68.287 -+ field_idx = 1; 68.288 -+ bufpos = buf; 68.289 -+ buflen = 0; 68.290 -+ memset (&state, '\0', sizeof(mbstate_t)); 68.291 -+ 68.292 -+ c = getc (stream); 68.293 -+ empty_input = (c == EOF); 68.294 -+ if (c != EOF) 68.295 -+ { 68.296 -+ ungetc (c, stream); 68.297 -+ wc = 0; 68.298 -+ } 68.299 -+ else 68.300 -+ wc = WEOF; 68.301 -+ 68.302 -+ /* To support the semantics of the -s flag, we may have to buffer 68.303 -+ all of the first field to determine whether it is `delimited.' 68.304 -+ But that is unnecessary if all non-delimited lines must be printed 68.305 -+ and the first field has been selected, or if non-delimited lines 68.306 -+ must be suppressed and the first field has *not* been selected. 68.307 -+ That is because a non-delimited line has exactly one field. */ 68.308 -+ buffer_first_field = (suppress_non_delimited ^ !print_kth (1)); 68.309 -+ 68.310 -+ while (1) 68.311 -+ { 68.312 -+ if (field_idx == 1 && buffer_first_field) 68.313 -+ { 68.314 -+ int len = 0; 68.315 -+ 68.316 -+ while (1) 68.317 -+ { 68.318 -+ REFILL_BUFFER (buf, bufpos, buflen, stream); 68.319 -+ 68.320 -+ GET_NEXT_WC_FROM_BUFFER 68.321 -+ (wc, bufpos, buflen, mblength, state, convfail); 68.322 -+ 68.323 -+ if (wc == WEOF) 68.324 -+ break; 68.325 -+ 68.326 -+ field_1_buffer = xrealloc (field_1_buffer, len + mblength); 68.327 -+ memcpy (field_1_buffer + len, bufpos, mblength); 68.328 -+ len += mblength; 68.329 -+ buflen -= mblength; 68.330 -+ bufpos += mblength; 68.331 -+ 68.332 -+ if (!convfail && (wc == line_delim || wc == wcdelim)) 68.333 -+ break; 68.334 -+ } 68.335 -+ 68.336 -+ if (len <= 0 && wc == WEOF) 68.337 -+ break; 68.338 -+ 68.339 -+ /* If the first field extends to the end of line (it is not 68.340 -+ delimited) and we are printing all non-delimited lines, 68.341 -+ print this one. */ 68.342 -+ if (convfail || (!convfail && wc != wcdelim)) 68.343 -+ { 68.344 -+ if (suppress_non_delimited) 68.345 -+ { 68.346 -+ /* Empty. */ 68.347 -+ } 68.348 -+ else 68.349 -+ { 68.350 -+ fwrite (field_1_buffer, sizeof (char), len, stdout); 68.351 -+ /* Make sure the output line is newline terminated. */ 68.352 -+ if (convfail || (!convfail && wc != line_delim)) 68.353 -+ putchar (line_delim); 68.354 -+ } 68.355 -+ continue; 68.356 -+ } 68.357 -+ 68.358 -+ if (print_kth (1)) 68.359 -+ { 68.360 -+ /* Print the field, but not the trailing delimiter. */ 68.361 -+ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); 68.362 -+ found_any_selected_field = 1; 68.363 -+ } 68.364 -+ next_item (&field_idx); 68.365 -+ } 68.366 -+ 68.367 -+ if (wc != WEOF) 68.368 -+ { 68.369 -+ if (print_kth (field_idx)) 68.370 -+ { 68.371 -+ if (found_any_selected_field) 68.372 -+ { 68.373 -+ fwrite (output_delimiter_string, sizeof (char), 68.374 -+ output_delimiter_length, stdout); 68.375 -+ } 68.376 -+ found_any_selected_field = 1; 68.377 -+ } 68.378 -+ 68.379 -+ while (1) 68.380 -+ { 68.381 -+ REFILL_BUFFER (buf, bufpos, buflen, stream); 68.382 -+ 68.383 -+ GET_NEXT_WC_FROM_BUFFER 68.384 -+ (wc, bufpos, buflen, mblength, state, convfail); 68.385 -+ 68.386 -+ if (wc == WEOF) 68.387 -+ break; 68.388 -+ else if (!convfail && (wc == wcdelim || wc == line_delim)) 68.389 -+ { 68.390 -+ buflen -= mblength; 68.391 -+ bufpos += mblength; 68.392 -+ break; 68.393 -+ } 68.394 -+ 68.395 -+ if (print_kth (field_idx)) 68.396 -+ fwrite (bufpos, mblength, sizeof(char), stdout); 68.397 -+ 68.398 -+ buflen -= mblength; 68.399 -+ bufpos += mblength; 68.400 -+ } 68.401 -+ } 68.402 -+ 68.403 -+ if ((!convfail || wc == line_delim) && buflen < 1) 68.404 -+ wc = WEOF; 68.405 -+ 68.406 -+ if (!convfail && wc == wcdelim) 68.407 -+ next_item (&field_idx); 68.408 -+ else if (wc == WEOF || (!convfail && wc == line_delim)) 68.409 -+ { 68.410 -+ if (found_any_selected_field 68.411 -+ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) 68.412 -+ putchar (line_delim); 68.413 -+ if (wc == WEOF) 68.414 -+ break; 68.415 -+ field_idx = 1; 68.416 -+ current_rp = frp; 68.417 -+ found_any_selected_field = 0; 68.418 -+ } 68.419 -+ } 68.420 -+} 68.421 -+#endif 68.422 -+ 68.423 - static void 68.424 - cut_stream (FILE *stream) 68.425 - { 68.426 -- if (operating_mode == byte_mode) 68.427 -- cut_bytes (stream); 68.428 -+#if HAVE_MBRTOWC 68.429 -+ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) 68.430 -+ { 68.431 -+ switch (operating_mode) 68.432 -+ { 68.433 -+ case byte_mode: 68.434 -+ if (byte_mode_character_aware) 68.435 -+ cut_characters_or_cut_bytes_no_split (stream); 68.436 -+ else 68.437 -+ cut_bytes (stream); 68.438 -+ break; 68.439 -+ 68.440 -+ case character_mode: 68.441 -+ cut_characters_or_cut_bytes_no_split (stream); 68.442 -+ break; 68.443 -+ 68.444 -+ case field_mode: 68.445 -+ if (delimlen == 1) 68.446 -+ { 68.447 -+ /* Check if we have utf8 multibyte locale, so we can use this 68.448 -+ optimization because of uniqueness of characters, which is 68.449 -+ not true for e.g. SJIS */ 68.450 -+ char * loc = setlocale(LC_CTYPE, NULL); 68.451 -+ if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") || 68.452 -+ strstr (loc, "UTF8") || strstr (loc, "utf8"))) 68.453 -+ { 68.454 -+ cut_fields (stream); 68.455 -+ break; 68.456 -+ } 68.457 -+ } 68.458 -+ cut_fields_mb (stream); 68.459 -+ break; 68.460 -+ 68.461 -+ default: 68.462 -+ abort (); 68.463 -+ } 68.464 -+ } 68.465 - else 68.466 -- cut_fields (stream); 68.467 -+#endif 68.468 -+ { 68.469 -+ if (operating_mode == field_mode) 68.470 -+ cut_fields (stream); 68.471 -+ else 68.472 -+ cut_bytes (stream); 68.473 -+ } 68.474 - } 68.475 - 68.476 - /* Process file FILE to standard output. 68.477 -@@ -483,6 +836,7 @@ main (int argc, char **argv) 68.478 - bool ok; 68.479 - bool delim_specified = false; 68.480 - char *spec_list_string IF_LINT ( = NULL); 68.481 -+ char mbdelim[MB_LEN_MAX + 1]; 68.482 - 68.483 - initialize_main (&argc, &argv); 68.484 - set_program_name (argv[0]); 68.485 -@@ -505,7 +859,6 @@ main (int argc, char **argv) 68.486 - switch (optc) 68.487 - { 68.488 - case 'b': 68.489 -- case 'c': 68.490 - /* Build the byte list. */ 68.491 - if (operating_mode != undefined_mode) 68.492 - FATAL_ERROR (_("only one type of list may be specified")); 68.493 -@@ -513,6 +866,14 @@ main (int argc, char **argv) 68.494 - spec_list_string = optarg; 68.495 - break; 68.496 - 68.497 -+ case 'c': 68.498 -+ /* Build the character list. */ 68.499 -+ if (operating_mode != undefined_mode) 68.500 -+ FATAL_ERROR (_("only one type of list may be specified")); 68.501 -+ operating_mode = character_mode; 68.502 -+ spec_list_string = optarg; 68.503 -+ break; 68.504 -+ 68.505 - case 'f': 68.506 - /* Build the field list. */ 68.507 - if (operating_mode != undefined_mode) 68.508 -@@ -524,10 +885,38 @@ main (int argc, char **argv) 68.509 - case 'd': 68.510 - /* New delimiter. */ 68.511 - /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ 68.512 -- if (optarg[0] != '\0' && optarg[1] != '\0') 68.513 -- FATAL_ERROR (_("the delimiter must be a single character")); 68.514 -- delim = optarg[0]; 68.515 -- delim_specified = true; 68.516 -+ { 68.517 -+#if HAVE_MBRTOWC 68.518 -+ if(MB_CUR_MAX > 1) 68.519 -+ { 68.520 -+ mbstate_t state; 68.521 -+ 68.522 -+ memset (&state, '\0', sizeof(mbstate_t)); 68.523 -+ delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state); 68.524 -+ 68.525 -+ if (delimlen == (size_t)-1 || delimlen == (size_t)-2) 68.526 -+ ++force_singlebyte_mode; 68.527 -+ else 68.528 -+ { 68.529 -+ delimlen = (delimlen < 1) ? 1 : delimlen; 68.530 -+ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') 68.531 -+ FATAL_ERROR (_("the delimiter must be a single character")); 68.532 -+ memcpy (mbdelim, optarg, delimlen); 68.533 -+ mbdelim[delimlen] = '\0'; 68.534 -+ if (delimlen == 1) 68.535 -+ delim = *optarg; 68.536 -+ } 68.537 -+ } 68.538 -+ 68.539 -+ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) 68.540 -+#endif 68.541 -+ { 68.542 -+ if (optarg[0] != '\0' && optarg[1] != '\0') 68.543 -+ FATAL_ERROR (_("the delimiter must be a single character")); 68.544 -+ delim = (unsigned char) optarg[0]; 68.545 -+ } 68.546 -+ delim_specified = true; 68.547 -+ } 68.548 - break; 68.549 - 68.550 - case OUTPUT_DELIMITER_OPTION: 68.551 -@@ -540,6 +929,7 @@ main (int argc, char **argv) 68.552 - break; 68.553 - 68.554 - case 'n': 68.555 -+ byte_mode_character_aware = 1; 68.556 - break; 68.557 - 68.558 - case 's': 68.559 -@@ -579,15 +969,34 @@ main (int argc, char **argv) 68.560 - | (complement ? SETFLD_COMPLEMENT : 0) ); 68.561 - 68.562 - if (!delim_specified) 68.563 -- delim = '\t'; 68.564 -+ { 68.565 -+ delim = '\t'; 68.566 -+#ifdef HAVE_MBRTOWC 68.567 -+ wcdelim = L'\t'; 68.568 -+ mbdelim[0] = '\t'; 68.569 -+ mbdelim[1] = '\0'; 68.570 -+ delimlen = 1; 68.571 -+#endif 68.572 -+ } 68.573 - 68.574 - if (output_delimiter_string == NULL) 68.575 - { 68.576 -- static char dummy[2]; 68.577 -- dummy[0] = delim; 68.578 -- dummy[1] = '\0'; 68.579 -- output_delimiter_string = dummy; 68.580 -- output_delimiter_length = 1; 68.581 -+#ifdef HAVE_MBRTOWC 68.582 -+ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) 68.583 -+ { 68.584 -+ output_delimiter_string = xstrdup(mbdelim); 68.585 -+ output_delimiter_length = delimlen; 68.586 -+ } 68.587 -+ 68.588 -+ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) 68.589 -+#endif 68.590 -+ { 68.591 -+ static char dummy[2]; 68.592 -+ dummy[0] = delim; 68.593 -+ dummy[1] = '\0'; 68.594 -+ output_delimiter_string = dummy; 68.595 -+ output_delimiter_length = 1; 68.596 -+ } 68.597 - } 68.598 - 68.599 - if (optind == argc) 68.600 -diff -Naurp coreutils-8.25-orig/src/expand.c coreutils-8.25/src/expand.c 68.601 ---- coreutils-8.25-orig/src/expand.c 2016-01-01 07:48:50.000000000 -0600 68.602 -+++ coreutils-8.25/src/expand.c 2016-02-08 19:07:10.301944619 -0600 68.603 -@@ -37,12 +37,34 @@ 68.604 - #include <stdio.h> 68.605 - #include <getopt.h> 68.606 - #include <sys/types.h> 68.607 -+ 68.608 -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ 68.609 -+#if HAVE_WCHAR_H 68.610 -+# include <wchar.h> 68.611 -+#endif 68.612 -+ 68.613 -+/* Get iswblank(). */ 68.614 -+#if HAVE_WCTYPE_H 68.615 -+# include <wctype.h> 68.616 -+#endif 68.617 -+ 68.618 - #include "system.h" 68.619 - #include "error.h" 68.620 - #include "fadvise.h" 68.621 - #include "quote.h" 68.622 - #include "xstrndup.h" 68.623 - 68.624 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 68.625 -+ installation; work around this configuration error. */ 68.626 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 68.627 -+# define MB_LEN_MAX 16 68.628 -+#endif 68.629 -+ 68.630 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 68.631 -+#if HAVE_MBRTOWC && defined mbstate_t 68.632 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 68.633 -+#endif 68.634 -+ 68.635 - /* The official name of this program (e.g., no 'g' prefix). */ 68.636 - #define PROGRAM_NAME "expand" 68.637 - 68.638 -@@ -357,6 +379,142 @@ expand (void) 68.639 - } 68.640 - } 68.641 - 68.642 -+#if HAVE_MBRTOWC 68.643 -+static void 68.644 -+expand_multibyte (void) 68.645 -+{ 68.646 -+ FILE *fp; /* Input strem. */ 68.647 -+ mbstate_t i_state; /* Current shift state of the input stream. */ 68.648 -+ mbstate_t i_state_bak; /* Back up the I_STATE. */ 68.649 -+ mbstate_t o_state; /* Current shift state of the output stream. */ 68.650 -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 68.651 -+ char *bufpos = buf; /* Next read position of BUF. */ 68.652 -+ size_t buflen = 0; /* The length of the byte sequence in buf. */ 68.653 -+ wchar_t wc; /* A gotten wide character. */ 68.654 -+ size_t mblength; /* The byte size of a multibyte character 68.655 -+ which shows as same character as WC. */ 68.656 -+ int tab_index = 0; /* Index in `tab_list' of next tabstop. */ 68.657 -+ int column = 0; /* Column on screen of the next char. */ 68.658 -+ int next_tab_column; /* Column the next tab stop is on. */ 68.659 -+ int convert = 1; /* If nonzero, perform translations. */ 68.660 -+ 68.661 -+ fp = next_file ((FILE *) NULL); 68.662 -+ if (fp == NULL) 68.663 -+ return; 68.664 -+ 68.665 -+ memset (&o_state, '\0', sizeof(mbstate_t)); 68.666 -+ memset (&i_state, '\0', sizeof(mbstate_t)); 68.667 -+ 68.668 -+ for (;;) 68.669 -+ { 68.670 -+ /* Refill the buffer BUF. */ 68.671 -+ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) 68.672 -+ { 68.673 -+ memmove (buf, bufpos, buflen); 68.674 -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); 68.675 -+ bufpos = buf; 68.676 -+ } 68.677 -+ 68.678 -+ /* No character is left in BUF. */ 68.679 -+ if (buflen < 1) 68.680 -+ { 68.681 -+ fp = next_file (fp); 68.682 -+ 68.683 -+ if (fp == NULL) 68.684 -+ break; /* No more files. */ 68.685 -+ else 68.686 -+ { 68.687 -+ memset (&i_state, '\0', sizeof(mbstate_t)); 68.688 -+ continue; 68.689 -+ } 68.690 -+ } 68.691 -+ 68.692 -+ /* Get a wide character. */ 68.693 -+ i_state_bak = i_state; 68.694 -+ mblength = mbrtowc (&wc, bufpos, buflen, &i_state); 68.695 -+ 68.696 -+ switch (mblength) 68.697 -+ { 68.698 -+ case (size_t)-1: /* illegal byte sequence. */ 68.699 -+ case (size_t)-2: 68.700 -+ mblength = 1; 68.701 -+ i_state = i_state_bak; 68.702 -+ if (convert) 68.703 -+ { 68.704 -+ ++column; 68.705 -+ if (convert_entire_line == 0 && !isblank(*bufpos)) 68.706 -+ convert = 0; 68.707 -+ } 68.708 -+ putchar (*bufpos); 68.709 -+ break; 68.710 -+ 68.711 -+ case 0: /* null. */ 68.712 -+ mblength = 1; 68.713 -+ if (convert && convert_entire_line == 0) 68.714 -+ convert = 0; 68.715 -+ putchar ('\0'); 68.716 -+ break; 68.717 -+ 68.718 -+ default: 68.719 -+ if (wc == L'\n') /* LF. */ 68.720 -+ { 68.721 -+ tab_index = 0; 68.722 -+ column = 0; 68.723 -+ convert = 1; 68.724 -+ putchar ('\n'); 68.725 -+ } 68.726 -+ else if (wc == L'\t' && convert) /* Tab. */ 68.727 -+ { 68.728 -+ if (tab_size == 0) 68.729 -+ { 68.730 -+ /* Do not let tab_index == first_free_tab; 68.731 -+ stop when it is 1 less. */ 68.732 -+ while (tab_index < first_free_tab - 1 68.733 -+ && column >= tab_list[tab_index]) 68.734 -+ tab_index++; 68.735 -+ next_tab_column = tab_list[tab_index]; 68.736 -+ if (tab_index < first_free_tab - 1) 68.737 -+ tab_index++; 68.738 -+ if (column >= next_tab_column) 68.739 -+ next_tab_column = column + 1; 68.740 -+ } 68.741 -+ else 68.742 -+ next_tab_column = column + tab_size - column % tab_size; 68.743 -+ 68.744 -+ while (column < next_tab_column) 68.745 -+ { 68.746 -+ putchar (' '); 68.747 -+ ++column; 68.748 -+ } 68.749 -+ } 68.750 -+ else /* Others. */ 68.751 -+ { 68.752 -+ if (convert) 68.753 -+ { 68.754 -+ if (wc == L'\b') 68.755 -+ { 68.756 -+ if (column > 0) 68.757 -+ --column; 68.758 -+ } 68.759 -+ else 68.760 -+ { 68.761 -+ int width; /* The width of WC. */ 68.762 -+ 68.763 -+ width = wcwidth (wc); 68.764 -+ column += (width > 0) ? width : 0; 68.765 -+ if (convert_entire_line == 0 && !iswblank(wc)) 68.766 -+ convert = 0; 68.767 -+ } 68.768 -+ } 68.769 -+ fwrite (bufpos, sizeof(char), mblength, stdout); 68.770 -+ } 68.771 -+ } 68.772 -+ buflen -= mblength; 68.773 -+ bufpos += mblength; 68.774 -+ } 68.775 -+} 68.776 -+#endif 68.777 -+ 68.778 - int 68.779 - main (int argc, char **argv) 68.780 - { 68.781 -@@ -421,7 +579,12 @@ main (int argc, char **argv) 68.782 - 68.783 - file_list = (optind < argc ? &argv[optind] : stdin_argv); 68.784 - 68.785 -- expand (); 68.786 -+#if HAVE_MBRTOWC 68.787 -+ if (MB_CUR_MAX > 1) 68.788 -+ expand_multibyte (); 68.789 -+ else 68.790 -+#endif 68.791 -+ expand (); 68.792 - 68.793 - if (have_read_stdin && fclose (stdin) != 0) 68.794 - error (EXIT_FAILURE, errno, "-"); 68.795 -diff -Naurp coreutils-8.25-orig/src/fold.c coreutils-8.25/src/fold.c 68.796 ---- coreutils-8.25-orig/src/fold.c 2016-01-01 07:48:50.000000000 -0600 68.797 -+++ coreutils-8.25/src/fold.c 2016-02-08 19:07:10.302944622 -0600 68.798 -@@ -22,11 +22,33 @@ 68.799 - #include <getopt.h> 68.800 - #include <sys/types.h> 68.801 - 68.802 -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ 68.803 -+#if HAVE_WCHAR_H 68.804 -+# include <wchar.h> 68.805 -+#endif 68.806 -+ 68.807 -+/* Get iswprint(), iswblank(), wcwidth(). */ 68.808 -+#if HAVE_WCTYPE_H 68.809 -+# include <wctype.h> 68.810 -+#endif 68.811 -+ 68.812 - #include "system.h" 68.813 - #include "error.h" 68.814 - #include "fadvise.h" 68.815 - #include "xdectoint.h" 68.816 - 68.817 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 68.818 -+ installation; work around this configuration error. */ 68.819 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 68.820 -+# undef MB_LEN_MAX 68.821 -+# define MB_LEN_MAX 16 68.822 -+#endif 68.823 -+ 68.824 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 68.825 -+#if HAVE_MBRTOWC && defined mbstate_t 68.826 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 68.827 -+#endif 68.828 -+ 68.829 - #define TAB_WIDTH 8 68.830 - 68.831 - /* The official name of this program (e.g., no 'g' prefix). */ 68.832 -@@ -34,20 +56,41 @@ 68.833 - 68.834 - #define AUTHORS proper_name ("David MacKenzie") 68.835 - 68.836 -+#define FATAL_ERROR(Message) \ 68.837 -+ do \ 68.838 -+ { \ 68.839 -+ error (0, 0, (Message)); \ 68.840 -+ usage (2); \ 68.841 -+ } \ 68.842 -+ while (0) 68.843 -+ 68.844 -+enum operating_mode 68.845 -+{ 68.846 -+ /* Fold texts by columns that are at the given positions. */ 68.847 -+ column_mode, 68.848 -+ 68.849 -+ /* Fold texts by bytes that are at the given positions. */ 68.850 -+ byte_mode, 68.851 -+ 68.852 -+ /* Fold texts by characters that are at the given positions. */ 68.853 -+ character_mode, 68.854 -+}; 68.855 -+ 68.856 -+/* The argument shows current mode. (Default: column_mode) */ 68.857 -+static enum operating_mode operating_mode; 68.858 -+ 68.859 - /* If nonzero, try to break on whitespace. */ 68.860 - static bool break_spaces; 68.861 - 68.862 --/* If nonzero, count bytes, not column positions. */ 68.863 --static bool count_bytes; 68.864 -- 68.865 - /* If nonzero, at least one of the files we read was standard input. */ 68.866 - static bool have_read_stdin; 68.867 - 68.868 --static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::"; 68.869 -+static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::"; 68.870 - 68.871 - static struct option const longopts[] = 68.872 - { 68.873 - {"bytes", no_argument, NULL, 'b'}, 68.874 -+ {"characters", no_argument, NULL, 'c'}, 68.875 - {"spaces", no_argument, NULL, 's'}, 68.876 - {"width", required_argument, NULL, 'w'}, 68.877 - {GETOPT_HELP_OPTION_DECL}, 68.878 -@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing t 68.879 - 68.880 - fputs (_("\ 68.881 - -b, --bytes count bytes rather than columns\n\ 68.882 -+ -c, --characters count characters rather than columns\n\ 68.883 - -s, --spaces break at spaces\n\ 68.884 - -w, --width=WIDTH use WIDTH columns instead of 80\n\ 68.885 - "), stdout); 68.886 -@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing t 68.887 - static size_t 68.888 - adjust_column (size_t column, char c) 68.889 - { 68.890 -- if (!count_bytes) 68.891 -+ if (operating_mode != byte_mode) 68.892 - { 68.893 - if (c == '\b') 68.894 - { 68.895 -@@ -115,30 +159,14 @@ adjust_column (size_t column, char c) 68.896 - to stdout, with maximum line length WIDTH. 68.897 - Return true if successful. */ 68.898 - 68.899 --static bool 68.900 --fold_file (char const *filename, size_t width) 68.901 -+static void 68.902 -+fold_text (FILE *istream, size_t width, int *saved_errno) 68.903 - { 68.904 -- FILE *istream; 68.905 - int c; 68.906 - size_t column = 0; /* Screen column where next char will go. */ 68.907 - size_t offset_out = 0; /* Index in 'line_out' for next char. */ 68.908 - static char *line_out = NULL; 68.909 - static size_t allocated_out = 0; 68.910 -- int saved_errno; 68.911 -- 68.912 -- if (STREQ (filename, "-")) 68.913 -- { 68.914 -- istream = stdin; 68.915 -- have_read_stdin = true; 68.916 -- } 68.917 -- else 68.918 -- istream = fopen (filename, "r"); 68.919 -- 68.920 -- if (istream == NULL) 68.921 -- { 68.922 -- error (0, errno, "%s", quotef (filename)); 68.923 -- return false; 68.924 -- } 68.925 - 68.926 - fadvise (istream, FADVISE_SEQUENTIAL); 68.927 - 68.928 -@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t 68.929 - bool found_blank = false; 68.930 - size_t logical_end = offset_out; 68.931 - 68.932 -+ /* If LINE_OUT has no wide character, 68.933 -+ put a new wide character in LINE_OUT 68.934 -+ if column is bigger than width. */ 68.935 -+ if (offset_out == 0) 68.936 -+ { 68.937 -+ line_out[offset_out++] = c; 68.938 -+ continue; 68.939 -+ } 68.940 -+ 68.941 - /* Look for the last blank. */ 68.942 - while (logical_end) 68.943 - { 68.944 -@@ -214,11 +251,221 @@ fold_file (char const *filename, size_t 68.945 - line_out[offset_out++] = c; 68.946 - } 68.947 - 68.948 -- saved_errno = errno; 68.949 -+ *saved_errno = errno; 68.950 -+ 68.951 -+ if (offset_out) 68.952 -+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); 68.953 -+ 68.954 -+} 68.955 -+ 68.956 -+#if HAVE_MBRTOWC 68.957 -+static void 68.958 -+fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) 68.959 -+{ 68.960 -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 68.961 -+ size_t buflen = 0; /* The length of the byte sequence in buf. */ 68.962 -+ char *bufpos = buf; /* Next read position of BUF. */ 68.963 -+ wint_t wc; /* A gotten wide character. */ 68.964 -+ size_t mblength; /* The byte size of a multibyte character which shows 68.965 -+ as same character as WC. */ 68.966 -+ mbstate_t state, state_bak; /* State of the stream. */ 68.967 -+ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ 68.968 -+ 68.969 -+ static char *line_out = NULL; 68.970 -+ size_t offset_out = 0; /* Index in `line_out' for next char. */ 68.971 -+ static size_t allocated_out = 0; 68.972 -+ 68.973 -+ int increment; 68.974 -+ size_t column = 0; 68.975 -+ 68.976 -+ size_t last_blank_pos; 68.977 -+ size_t last_blank_column; 68.978 -+ int is_blank_seen; 68.979 -+ int last_blank_increment = 0; 68.980 -+ int is_bs_following_last_blank; 68.981 -+ size_t bs_following_last_blank_num; 68.982 -+ int is_cr_after_last_blank; 68.983 -+ 68.984 -+#define CLEAR_FLAGS \ 68.985 -+ do \ 68.986 -+ { \ 68.987 -+ last_blank_pos = 0; \ 68.988 -+ last_blank_column = 0; \ 68.989 -+ is_blank_seen = 0; \ 68.990 -+ is_bs_following_last_blank = 0; \ 68.991 -+ bs_following_last_blank_num = 0; \ 68.992 -+ is_cr_after_last_blank = 0; \ 68.993 -+ } \ 68.994 -+ while (0) 68.995 -+ 68.996 -+#define START_NEW_LINE \ 68.997 -+ do \ 68.998 -+ { \ 68.999 -+ putchar ('\n'); \ 68.1000 -+ column = 0; \ 68.1001 -+ offset_out = 0; \ 68.1002 -+ CLEAR_FLAGS; \ 68.1003 -+ } \ 68.1004 -+ while (0) 68.1005 -+ 68.1006 -+ CLEAR_FLAGS; 68.1007 -+ memset (&state, '\0', sizeof(mbstate_t)); 68.1008 -+ 68.1009 -+ for (;; bufpos += mblength, buflen -= mblength) 68.1010 -+ { 68.1011 -+ if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream)) 68.1012 -+ { 68.1013 -+ memmove (buf, bufpos, buflen); 68.1014 -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream); 68.1015 -+ bufpos = buf; 68.1016 -+ } 68.1017 -+ 68.1018 -+ if (buflen < 1) 68.1019 -+ break; 68.1020 -+ 68.1021 -+ /* Get a wide character. */ 68.1022 -+ state_bak = state; 68.1023 -+ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state); 68.1024 -+ 68.1025 -+ switch (mblength) 68.1026 -+ { 68.1027 -+ case (size_t)-1: 68.1028 -+ case (size_t)-2: 68.1029 -+ convfail++; 68.1030 -+ state = state_bak; 68.1031 -+ /* Fall through. */ 68.1032 -+ 68.1033 -+ case 0: 68.1034 -+ mblength = 1; 68.1035 -+ break; 68.1036 -+ } 68.1037 -+ 68.1038 -+rescan: 68.1039 -+ if (operating_mode == byte_mode) /* byte mode */ 68.1040 -+ increment = mblength; 68.1041 -+ else if (operating_mode == character_mode) /* character mode */ 68.1042 -+ increment = 1; 68.1043 -+ else /* column mode */ 68.1044 -+ { 68.1045 -+ if (convfail) 68.1046 -+ increment = 1; 68.1047 -+ else 68.1048 -+ { 68.1049 -+ switch (wc) 68.1050 -+ { 68.1051 -+ case L'\n': 68.1052 -+ fwrite (line_out, sizeof(char), offset_out, stdout); 68.1053 -+ START_NEW_LINE; 68.1054 -+ continue; 68.1055 -+ 68.1056 -+ case L'\b': 68.1057 -+ increment = (column > 0) ? -1 : 0; 68.1058 -+ break; 68.1059 -+ 68.1060 -+ case L'\r': 68.1061 -+ increment = -1 * column; 68.1062 -+ break; 68.1063 -+ 68.1064 -+ case L'\t': 68.1065 -+ increment = 8 - column % 8; 68.1066 -+ break; 68.1067 -+ 68.1068 -+ default: 68.1069 -+ increment = wcwidth (wc); 68.1070 -+ increment = (increment < 0) ? 0 : increment; 68.1071 -+ } 68.1072 -+ } 68.1073 -+ } 68.1074 -+ 68.1075 -+ if (column + increment > width && break_spaces && last_blank_pos) 68.1076 -+ { 68.1077 -+ fwrite (line_out, sizeof(char), last_blank_pos, stdout); 68.1078 -+ putchar ('\n'); 68.1079 -+ 68.1080 -+ offset_out = offset_out - last_blank_pos; 68.1081 -+ column = column - last_blank_column + ((is_cr_after_last_blank) 68.1082 -+ ? last_blank_increment : bs_following_last_blank_num); 68.1083 -+ memmove (line_out, line_out + last_blank_pos, offset_out); 68.1084 -+ CLEAR_FLAGS; 68.1085 -+ goto rescan; 68.1086 -+ } 68.1087 -+ 68.1088 -+ if (column + increment > width && column != 0) 68.1089 -+ { 68.1090 -+ fwrite (line_out, sizeof(char), offset_out, stdout); 68.1091 -+ START_NEW_LINE; 68.1092 -+ goto rescan; 68.1093 -+ } 68.1094 -+ 68.1095 -+ if (allocated_out < offset_out + mblength) 68.1096 -+ { 68.1097 -+ line_out = X2REALLOC (line_out, &allocated_out); 68.1098 -+ } 68.1099 -+ 68.1100 -+ memcpy (line_out + offset_out, bufpos, mblength); 68.1101 -+ offset_out += mblength; 68.1102 -+ column += increment; 68.1103 -+ 68.1104 -+ if (is_blank_seen && !convfail && wc == L'\r') 68.1105 -+ is_cr_after_last_blank = 1; 68.1106 -+ 68.1107 -+ if (is_bs_following_last_blank && !convfail && wc == L'\b') 68.1108 -+ ++bs_following_last_blank_num; 68.1109 -+ else 68.1110 -+ is_bs_following_last_blank = 0; 68.1111 -+ 68.1112 -+ if (break_spaces && !convfail && iswblank (wc)) 68.1113 -+ { 68.1114 -+ last_blank_pos = offset_out; 68.1115 -+ last_blank_column = column; 68.1116 -+ is_blank_seen = 1; 68.1117 -+ last_blank_increment = increment; 68.1118 -+ is_bs_following_last_blank = 1; 68.1119 -+ bs_following_last_blank_num = 0; 68.1120 -+ is_cr_after_last_blank = 0; 68.1121 -+ } 68.1122 -+ } 68.1123 -+ 68.1124 -+ *saved_errno = errno; 68.1125 - 68.1126 - if (offset_out) 68.1127 - fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); 68.1128 - 68.1129 -+} 68.1130 -+#endif 68.1131 -+ 68.1132 -+/* Fold file FILENAME, or standard input if FILENAME is "-", 68.1133 -+ to stdout, with maximum line length WIDTH. 68.1134 -+ Return 0 if successful, 1 if an error occurs. */ 68.1135 -+ 68.1136 -+static bool 68.1137 -+fold_file (char const *filename, size_t width) 68.1138 -+{ 68.1139 -+ FILE *istream; 68.1140 -+ int saved_errno; 68.1141 -+ 68.1142 -+ if (STREQ (filename, "-")) 68.1143 -+ { 68.1144 -+ istream = stdin; 68.1145 -+ have_read_stdin = 1; 68.1146 -+ } 68.1147 -+ else 68.1148 -+ istream = fopen (filename, "r"); 68.1149 -+ 68.1150 -+ if (istream == NULL) 68.1151 -+ { 68.1152 -+ error (0, errno, "%s", quotef (filename)); 68.1153 -+ return 1; 68.1154 -+ } 68.1155 -+ 68.1156 -+ /* Define how ISTREAM is being folded. */ 68.1157 -+#if HAVE_MBRTOWC 68.1158 -+ if (MB_CUR_MAX > 1) 68.1159 -+ fold_multibyte_text (istream, width, &saved_errno); 68.1160 -+ else 68.1161 -+#endif 68.1162 -+ fold_text (istream, width, &saved_errno); 68.1163 -+ 68.1164 - if (ferror (istream)) 68.1165 - { 68.1166 - error (0, saved_errno, "%s", quotef (filename)); 68.1167 -@@ -251,7 +498,8 @@ main (int argc, char **argv) 68.1168 - 68.1169 - atexit (close_stdout); 68.1170 - 68.1171 -- break_spaces = count_bytes = have_read_stdin = false; 68.1172 -+ operating_mode = column_mode; 68.1173 -+ break_spaces = have_read_stdin = false; 68.1174 - 68.1175 - while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) 68.1176 - { 68.1177 -@@ -260,7 +508,15 @@ main (int argc, char **argv) 68.1178 - switch (optc) 68.1179 - { 68.1180 - case 'b': /* Count bytes rather than columns. */ 68.1181 -- count_bytes = true; 68.1182 -+ if (operating_mode != column_mode) 68.1183 -+ FATAL_ERROR (_("only one way of folding may be specified")); 68.1184 -+ operating_mode = byte_mode; 68.1185 -+ break; 68.1186 -+ 68.1187 -+ case 'c': 68.1188 -+ if (operating_mode != column_mode) 68.1189 -+ FATAL_ERROR (_("only one way of folding may be specified")); 68.1190 -+ operating_mode = character_mode; 68.1191 - break; 68.1192 - 68.1193 - case 's': /* Break at word boundaries. */ 68.1194 -diff -Naurp coreutils-8.25-orig/src/join.c coreutils-8.25/src/join.c 68.1195 ---- coreutils-8.25-orig/src/join.c 2016-01-13 05:08:59.000000000 -0600 68.1196 -+++ coreutils-8.25/src/join.c 2016-02-08 19:07:10.303944625 -0600 68.1197 -@@ -22,18 +22,32 @@ 68.1198 - #include <sys/types.h> 68.1199 - #include <getopt.h> 68.1200 - 68.1201 -+/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth(). */ 68.1202 -+#if HAVE_WCHAR_H 68.1203 -+# include <wchar.h> 68.1204 -+#endif 68.1205 -+ 68.1206 -+/* Get iswblank(), towupper. */ 68.1207 -+#if HAVE_WCTYPE_H 68.1208 -+# include <wctype.h> 68.1209 -+#endif 68.1210 -+ 68.1211 - #include "system.h" 68.1212 - #include "error.h" 68.1213 - #include "fadvise.h" 68.1214 - #include "hard-locale.h" 68.1215 - #include "linebuffer.h" 68.1216 --#include "memcasecmp.h" 68.1217 - #include "quote.h" 68.1218 - #include "stdio--.h" 68.1219 - #include "xmemcoll.h" 68.1220 - #include "xstrtol.h" 68.1221 - #include "argmatch.h" 68.1222 - 68.1223 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 68.1224 -+#if HAVE_MBRTOWC && defined mbstate_t 68.1225 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 68.1226 -+#endif 68.1227 -+ 68.1228 - /* The official name of this program (e.g., no 'g' prefix). */ 68.1229 - #define PROGRAM_NAME "join" 68.1230 - 68.1231 -@@ -135,10 +149,12 @@ static struct outlist outlist_head; 68.1232 - /* Last element in 'outlist', where a new element can be added. */ 68.1233 - static struct outlist *outlist_end = &outlist_head; 68.1234 - 68.1235 --/* Tab character separating fields. If negative, fields are separated 68.1236 -- by any nonempty string of blanks, otherwise by exactly one 68.1237 -- tab character whose value (when cast to unsigned char) equals TAB. */ 68.1238 --static int tab = -1; 68.1239 -+/* Tab character separating fields. If NULL, fields are separated 68.1240 -+ by any nonempty string of blanks. */ 68.1241 -+static char *tab = NULL; 68.1242 -+ 68.1243 -+/* The number of bytes used for tab. */ 68.1244 -+static size_t tablen = 0; 68.1245 - 68.1246 - /* If nonzero, check that the input is correctly ordered. */ 68.1247 - static enum 68.1248 -@@ -275,13 +291,14 @@ xfields (struct line *line) 68.1249 - if (ptr == lim) 68.1250 - return; 68.1251 - 68.1252 -- if (0 <= tab && tab != '\n') 68.1253 -+ if (tab != NULL) 68.1254 - { 68.1255 -+ unsigned char t = tab[0]; 68.1256 - char *sep; 68.1257 -- for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1) 68.1258 -+ for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1) 68.1259 - extract_field (line, ptr, sep - ptr); 68.1260 - } 68.1261 -- else if (tab < 0) 68.1262 -+ else 68.1263 - { 68.1264 - /* Skip leading blanks before the first field. */ 68.1265 - while (field_sep (*ptr)) 68.1266 -@@ -305,6 +322,147 @@ xfields (struct line *line) 68.1267 - extract_field (line, ptr, lim - ptr); 68.1268 - } 68.1269 - 68.1270 -+#if HAVE_MBRTOWC 68.1271 -+static void 68.1272 -+xfields_multibyte (struct line *line) 68.1273 -+{ 68.1274 -+ char *ptr = line->buf.buffer; 68.1275 -+ char const *lim = ptr + line->buf.length - 1; 68.1276 -+ wchar_t wc = 0; 68.1277 -+ size_t mblength = 1; 68.1278 -+ mbstate_t state, state_bak; 68.1279 -+ 68.1280 -+ memset (&state, 0, sizeof (mbstate_t)); 68.1281 -+ 68.1282 -+ if (ptr >= lim) 68.1283 -+ return; 68.1284 -+ 68.1285 -+ if (tab != NULL) 68.1286 -+ { 68.1287 -+ char *sep = ptr; 68.1288 -+ for (; ptr < lim; ptr = sep + mblength) 68.1289 -+ { 68.1290 -+ sep = ptr; 68.1291 -+ while (sep < lim) 68.1292 -+ { 68.1293 -+ state_bak = state; 68.1294 -+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 68.1295 -+ 68.1296 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 68.1297 -+ { 68.1298 -+ mblength = 1; 68.1299 -+ state = state_bak; 68.1300 -+ } 68.1301 -+ mblength = (mblength < 1) ? 1 : mblength; 68.1302 -+ 68.1303 -+ if (mblength == tablen && !memcmp (sep, tab, mblength)) 68.1304 -+ break; 68.1305 -+ else 68.1306 -+ { 68.1307 -+ sep += mblength; 68.1308 -+ continue; 68.1309 -+ } 68.1310 -+ } 68.1311 -+ 68.1312 -+ if (sep >= lim) 68.1313 -+ break; 68.1314 -+ 68.1315 -+ extract_field (line, ptr, sep - ptr); 68.1316 -+ } 68.1317 -+ } 68.1318 -+ else 68.1319 -+ { 68.1320 -+ /* Skip leading blanks before the first field. */ 68.1321 -+ while(ptr < lim) 68.1322 -+ { 68.1323 -+ state_bak = state; 68.1324 -+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 68.1325 -+ 68.1326 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 68.1327 -+ { 68.1328 -+ mblength = 1; 68.1329 -+ state = state_bak; 68.1330 -+ break; 68.1331 -+ } 68.1332 -+ mblength = (mblength < 1) ? 1 : mblength; 68.1333 -+ 68.1334 -+ if (!iswblank(wc) && wc != '\n') 68.1335 -+ break; 68.1336 -+ ptr += mblength; 68.1337 -+ } 68.1338 -+ 68.1339 -+ do 68.1340 -+ { 68.1341 -+ char *sep; 68.1342 -+ state_bak = state; 68.1343 -+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 68.1344 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 68.1345 -+ { 68.1346 -+ mblength = 1; 68.1347 -+ state = state_bak; 68.1348 -+ break; 68.1349 -+ } 68.1350 -+ mblength = (mblength < 1) ? 1 : mblength; 68.1351 -+ 68.1352 -+ sep = ptr + mblength; 68.1353 -+ while (sep < lim) 68.1354 -+ { 68.1355 -+ state_bak = state; 68.1356 -+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 68.1357 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 68.1358 -+ { 68.1359 -+ mblength = 1; 68.1360 -+ state = state_bak; 68.1361 -+ break; 68.1362 -+ } 68.1363 -+ mblength = (mblength < 1) ? 1 : mblength; 68.1364 -+ 68.1365 -+ if (iswblank (wc) || wc == '\n') 68.1366 -+ break; 68.1367 -+ 68.1368 -+ sep += mblength; 68.1369 -+ } 68.1370 -+ 68.1371 -+ extract_field (line, ptr, sep - ptr); 68.1372 -+ if (sep >= lim) 68.1373 -+ return; 68.1374 -+ 68.1375 -+ state_bak = state; 68.1376 -+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 68.1377 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 68.1378 -+ { 68.1379 -+ mblength = 1; 68.1380 -+ state = state_bak; 68.1381 -+ break; 68.1382 -+ } 68.1383 -+ mblength = (mblength < 1) ? 1 : mblength; 68.1384 -+ 68.1385 -+ ptr = sep + mblength; 68.1386 -+ while (ptr < lim) 68.1387 -+ { 68.1388 -+ state_bak = state; 68.1389 -+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 68.1390 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 68.1391 -+ { 68.1392 -+ mblength = 1; 68.1393 -+ state = state_bak; 68.1394 -+ break; 68.1395 -+ } 68.1396 -+ mblength = (mblength < 1) ? 1 : mblength; 68.1397 -+ 68.1398 -+ if (!iswblank (wc) && wc != '\n') 68.1399 -+ break; 68.1400 -+ 68.1401 -+ ptr += mblength; 68.1402 -+ } 68.1403 -+ } 68.1404 -+ while (ptr < lim); 68.1405 -+ } 68.1406 -+ 68.1407 -+ extract_field (line, ptr, lim - ptr); 68.1408 -+} 68.1409 -+#endif 68.1410 -+ 68.1411 - static void 68.1412 - freeline (struct line *line) 68.1413 - { 68.1414 -@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct 68.1415 - size_t jf_1, size_t jf_2) 68.1416 - { 68.1417 - /* Start of field to compare in each file. */ 68.1418 -- char *beg1; 68.1419 -- char *beg2; 68.1420 -- 68.1421 -- size_t len1; 68.1422 -- size_t len2; /* Length of fields to compare. */ 68.1423 -+ char *beg[2]; 68.1424 -+ char *copy[2]; 68.1425 -+ size_t len[2]; /* Length of fields to compare. */ 68.1426 - int diff; 68.1427 -+ int i, j; 68.1428 -+ int mallocd = 0; 68.1429 - 68.1430 - if (jf_1 < line1->nfields) 68.1431 - { 68.1432 -- beg1 = line1->fields[jf_1].beg; 68.1433 -- len1 = line1->fields[jf_1].len; 68.1434 -+ beg[0] = line1->fields[jf_1].beg; 68.1435 -+ len[0] = line1->fields[jf_1].len; 68.1436 - } 68.1437 - else 68.1438 - { 68.1439 -- beg1 = NULL; 68.1440 -- len1 = 0; 68.1441 -+ beg[0] = NULL; 68.1442 -+ len[0] = 0; 68.1443 - } 68.1444 - 68.1445 - if (jf_2 < line2->nfields) 68.1446 - { 68.1447 -- beg2 = line2->fields[jf_2].beg; 68.1448 -- len2 = line2->fields[jf_2].len; 68.1449 -+ beg[1] = line2->fields[jf_2].beg; 68.1450 -+ len[1] = line2->fields[jf_2].len; 68.1451 - } 68.1452 - else 68.1453 - { 68.1454 -- beg2 = NULL; 68.1455 -- len2 = 0; 68.1456 -+ beg[1] = NULL; 68.1457 -+ len[1] = 0; 68.1458 - } 68.1459 - 68.1460 -- if (len1 == 0) 68.1461 -- return len2 == 0 ? 0 : -1; 68.1462 -- if (len2 == 0) 68.1463 -+ if (len[0] == 0) 68.1464 -+ return len[1] == 0 ? 0 : -1; 68.1465 -+ if (len[1] == 0) 68.1466 - return 1; 68.1467 - 68.1468 - if (ignore_case) 68.1469 - { 68.1470 -- /* FIXME: ignore_case does not work with NLS (in particular, 68.1471 -- with multibyte chars). */ 68.1472 -- diff = memcasecmp (beg1, beg2, MIN (len1, len2)); 68.1473 -+#ifdef HAVE_MBRTOWC 68.1474 -+ if (MB_CUR_MAX > 1) 68.1475 -+ { 68.1476 -+ size_t mblength; 68.1477 -+ wchar_t wc, uwc; 68.1478 -+ mbstate_t state, state_bak; 68.1479 -+ 68.1480 -+ memset (&state, '\0', sizeof (mbstate_t)); 68.1481 -+ 68.1482 -+ for (i = 0; i < 2; i++) 68.1483 -+ { 68.1484 -+ mallocd = 1; 68.1485 -+ copy[i] = xmalloc (len[i] + 1); 68.1486 -+ memset (copy[i], '\0',len[i] + 1); 68.1487 -+ 68.1488 -+ for (j = 0; j < MIN (len[0], len[1]);) 68.1489 -+ { 68.1490 -+ state_bak = state; 68.1491 -+ mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state); 68.1492 -+ 68.1493 -+ switch (mblength) 68.1494 -+ { 68.1495 -+ case (size_t) -1: 68.1496 -+ case (size_t) -2: 68.1497 -+ state = state_bak; 68.1498 -+ /* Fall through */ 68.1499 -+ case 0: 68.1500 -+ mblength = 1; 68.1501 -+ break; 68.1502 -+ 68.1503 -+ default: 68.1504 -+ uwc = towupper (wc); 68.1505 -+ 68.1506 -+ if (uwc != wc) 68.1507 -+ { 68.1508 -+ mbstate_t state_wc; 68.1509 -+ size_t mblen; 68.1510 -+ 68.1511 -+ memset (&state_wc, '\0', sizeof (mbstate_t)); 68.1512 -+ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); 68.1513 -+ assert (mblen != (size_t)-1); 68.1514 -+ } 68.1515 -+ else 68.1516 -+ memcpy (copy[i] + j, beg[i] + j, mblength); 68.1517 -+ } 68.1518 -+ j += mblength; 68.1519 -+ } 68.1520 -+ copy[i][j] = '\0'; 68.1521 -+ } 68.1522 -+ } 68.1523 -+ else 68.1524 -+#endif 68.1525 -+ { 68.1526 -+ for (i = 0; i < 2; i++) 68.1527 -+ { 68.1528 -+ mallocd = 1; 68.1529 -+ copy[i] = xmalloc (len[i] + 1); 68.1530 -+ 68.1531 -+ for (j = 0; j < MIN (len[0], len[1]); j++) 68.1532 -+ copy[i][j] = toupper (beg[i][j]); 68.1533 -+ 68.1534 -+ copy[i][j] = '\0'; 68.1535 -+ } 68.1536 -+ } 68.1537 - } 68.1538 - else 68.1539 - { 68.1540 -- if (hard_LC_COLLATE) 68.1541 -- return xmemcoll (beg1, len1, beg2, len2); 68.1542 -- diff = memcmp (beg1, beg2, MIN (len1, len2)); 68.1543 -+ copy[0] = beg[0]; 68.1544 -+ copy[1] = beg[1]; 68.1545 -+ } 68.1546 -+ 68.1547 -+ if (hard_LC_COLLATE) 68.1548 -+ { 68.1549 -+ diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); 68.1550 -+ 68.1551 -+ if (mallocd) 68.1552 -+ for (i = 0; i < 2; i++) 68.1553 -+ free (copy[i]); 68.1554 -+ 68.1555 -+ return diff; 68.1556 - } 68.1557 -+ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); 68.1558 -+ 68.1559 -+ if (mallocd) 68.1560 -+ for (i = 0; i < 2; i++) 68.1561 -+ free (copy[i]); 68.1562 -+ 68.1563 - 68.1564 - if (diff) 68.1565 - return diff; 68.1566 -- return len1 < len2 ? -1 : len1 != len2; 68.1567 -+ return len[0] - len[1]; 68.1568 - } 68.1569 - 68.1570 - /* Check that successive input lines PREV and CURRENT from input file 68.1571 -@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep, 68.1572 - } 68.1573 - ++line_no[which - 1]; 68.1574 - 68.1575 -+#if HAVE_MBRTOWC 68.1576 -+ if (MB_CUR_MAX > 1) 68.1577 -+ xfields_multibyte (line); 68.1578 -+ else 68.1579 -+#endif 68.1580 - xfields (line); 68.1581 - 68.1582 - if (prevline[which - 1]) 68.1583 -@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *li 68.1584 - 68.1585 - /* Output all the fields in line, other than the join field. */ 68.1586 - 68.1587 -+#define PUT_TAB_CHAR \ 68.1588 -+ do \ 68.1589 -+ { \ 68.1590 -+ (tab != NULL) ? \ 68.1591 -+ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ 68.1592 -+ } \ 68.1593 -+ while (0) 68.1594 -+ 68.1595 - static void 68.1596 - prfields (struct line const *line, size_t join_field, size_t autocount) 68.1597 - { 68.1598 - size_t i; 68.1599 - size_t nfields = autoformat ? autocount : line->nfields; 68.1600 -- char output_separator = tab < 0 ? ' ' : tab; 68.1601 - 68.1602 - for (i = 0; i < join_field && i < nfields; ++i) 68.1603 - { 68.1604 -- putchar (output_separator); 68.1605 -+ PUT_TAB_CHAR; 68.1606 - prfield (i, line); 68.1607 - } 68.1608 - for (i = join_field + 1; i < nfields; ++i) 68.1609 - { 68.1610 -- putchar (output_separator); 68.1611 -+ PUT_TAB_CHAR; 68.1612 - prfield (i, line); 68.1613 - } 68.1614 - } 68.1615 -@@ -591,7 +838,6 @@ static void 68.1616 - prjoin (struct line const *line1, struct line const *line2) 68.1617 - { 68.1618 - const struct outlist *outlist; 68.1619 -- char output_separator = tab < 0 ? ' ' : tab; 68.1620 - size_t field; 68.1621 - struct line const *line; 68.1622 - 68.1623 -@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct 68.1624 - o = o->next; 68.1625 - if (o == NULL) 68.1626 - break; 68.1627 -- putchar (output_separator); 68.1628 -+ PUT_TAB_CHAR; 68.1629 - } 68.1630 - putchar (eolchar); 68.1631 - } 68.1632 -@@ -1103,21 +1349,46 @@ main (int argc, char **argv) 68.1633 - 68.1634 - case 't': 68.1635 - { 68.1636 -- unsigned char newtab = optarg[0]; 68.1637 -+ char *newtab = NULL; 68.1638 -+ size_t newtablen; 68.1639 -+ newtab = xstrdup (optarg); 68.1640 -+#if HAVE_MBRTOWC 68.1641 -+ if (MB_CUR_MAX > 1) 68.1642 -+ { 68.1643 -+ mbstate_t state; 68.1644 -+ 68.1645 -+ memset (&state, 0, sizeof (mbstate_t)); 68.1646 -+ newtablen = mbrtowc (NULL, newtab, 68.1647 -+ strnlen (newtab, MB_LEN_MAX), 68.1648 -+ &state); 68.1649 -+ if (newtablen == (size_t) 0 68.1650 -+ || newtablen == (size_t) -1 68.1651 -+ || newtablen == (size_t) -2) 68.1652 -+ newtablen = 1; 68.1653 -+ } 68.1654 -+ else 68.1655 -+#endif 68.1656 -+ newtablen = 1; 68.1657 - if (! newtab) 68.1658 -- newtab = '\n'; /* '' => process the whole line. */ 68.1659 -+ { 68.1660 -+ newtab = (char*)"\n"; /* '' => process the whole line. */ 68.1661 -+ } 68.1662 - else if (optarg[1]) 68.1663 - { 68.1664 -- if (STREQ (optarg, "\\0")) 68.1665 -- newtab = '\0'; 68.1666 -- else 68.1667 -- error (EXIT_FAILURE, 0, _("multi-character tab %s"), 68.1668 -- quote (optarg)); 68.1669 -+ if (newtablen == 1 && newtab[1]) 68.1670 -+ { 68.1671 -+ if (STREQ (newtab, "\\0")) 68.1672 -+ newtab[0] = '\0'; 68.1673 -+ } 68.1674 -+ } 68.1675 -+ if (tab != NULL && strcmp (tab, newtab)) 68.1676 -+ { 68.1677 -+ free (newtab); 68.1678 -+ error (EXIT_FAILURE, 0, _("incompatible tabs")); 68.1679 - } 68.1680 -- if (0 <= tab && tab != newtab) 68.1681 -- error (EXIT_FAILURE, 0, _("incompatible tabs")); 68.1682 - tab = newtab; 68.1683 -- } 68.1684 -+ tablen = newtablen; 68.1685 -+ } 68.1686 - break; 68.1687 - 68.1688 - case 'z': 68.1689 -diff -Naurp coreutils-8.25-orig/src/pr.c coreutils-8.25/src/pr.c 68.1690 ---- coreutils-8.25-orig/src/pr.c 2016-01-01 07:48:50.000000000 -0600 68.1691 -+++ coreutils-8.25/src/pr.c 2016-02-08 19:07:10.306944635 -0600 68.1692 -@@ -311,6 +311,24 @@ 68.1693 - 68.1694 - #include <getopt.h> 68.1695 - #include <sys/types.h> 68.1696 -+ 68.1697 -+/* Get MB_LEN_MAX. */ 68.1698 -+#include <limits.h> 68.1699 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 68.1700 -+ installation; work around this configuration error. */ 68.1701 -+#if !defined MB_LEN_MAX || MB_LEN_MAX == 1 68.1702 -+# define MB_LEN_MAX 16 68.1703 -+#endif 68.1704 -+ 68.1705 -+/* Get MB_CUR_MAX. */ 68.1706 -+#include <stdlib.h> 68.1707 -+ 68.1708 -+/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */ 68.1709 -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ 68.1710 -+#if HAVE_WCHAR_H 68.1711 -+# include <wchar.h> 68.1712 -+#endif 68.1713 -+ 68.1714 - #include "system.h" 68.1715 - #include "error.h" 68.1716 - #include "fadvise.h" 68.1717 -@@ -323,6 +341,18 @@ 68.1718 - #include "xstrtol.h" 68.1719 - #include "xdectoint.h" 68.1720 - 68.1721 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 68.1722 -+#if HAVE_MBRTOWC && defined mbstate_t 68.1723 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 68.1724 -+#endif 68.1725 -+ 68.1726 -+#ifndef HAVE_DECL_WCWIDTH 68.1727 -+"this configure-time declaration test was not run" 68.1728 -+#endif 68.1729 -+#if !HAVE_DECL_WCWIDTH 68.1730 -+extern int wcwidth (); 68.1731 -+#endif 68.1732 -+ 68.1733 - /* The official name of this program (e.g., no 'g' prefix). */ 68.1734 - #define PROGRAM_NAME "pr" 68.1735 - 68.1736 -@@ -415,7 +445,20 @@ struct COLUMN 68.1737 - 68.1738 - typedef struct COLUMN COLUMN; 68.1739 - 68.1740 --static int char_to_clump (char c); 68.1741 -+/* Funtion pointers to switch functions for single byte locale or for 68.1742 -+ multibyte locale. If multibyte functions do not exist in your sysytem, 68.1743 -+ these pointers always point the function for single byte locale. */ 68.1744 -+static void (*print_char) (char c); 68.1745 -+static int (*char_to_clump) (char c); 68.1746 -+ 68.1747 -+/* Functions for single byte locale. */ 68.1748 -+static void print_char_single (char c); 68.1749 -+static int char_to_clump_single (char c); 68.1750 -+ 68.1751 -+/* Functions for multibyte locale. */ 68.1752 -+static void print_char_multi (char c); 68.1753 -+static int char_to_clump_multi (char c); 68.1754 -+ 68.1755 - static bool read_line (COLUMN *p); 68.1756 - static bool print_page (void); 68.1757 - static bool print_stored (COLUMN *p); 68.1758 -@@ -427,6 +470,7 @@ static void add_line_number (COLUMN *p); 68.1759 - static void getoptnum (const char *n_str, int min, int *num, 68.1760 - const char *errfmt); 68.1761 - static void getoptarg (char *arg, char switch_char, char *character, 68.1762 -+ int *character_length, int *character_width, 68.1763 - int *number); 68.1764 - static void print_files (int number_of_files, char **av); 68.1765 - static void init_parameters (int number_of_files); 68.1766 -@@ -440,7 +484,6 @@ static void store_char (char c); 68.1767 - static void pad_down (unsigned int lines); 68.1768 - static void read_rest_of_line (COLUMN *p); 68.1769 - static void skip_read (COLUMN *p, int column_number); 68.1770 --static void print_char (char c); 68.1771 - static void cleanup (void); 68.1772 - static void print_sep_string (void); 68.1773 - static void separator_string (const char *optarg_S); 68.1774 -@@ -452,7 +495,7 @@ static COLUMN *column_vector; 68.1775 - we store the leftmost columns contiguously in buff. 68.1776 - To print a line from buff, get the index of the first character 68.1777 - from line_vector[i], and print up to line_vector[i + 1]. */ 68.1778 --static char *buff; 68.1779 -+static unsigned char *buff; 68.1780 - 68.1781 - /* Index of the position in buff where the next character 68.1782 - will be stored. */ 68.1783 -@@ -556,7 +599,7 @@ static int chars_per_column; 68.1784 - static bool untabify_input = false; 68.1785 - 68.1786 - /* (-e) The input tab character. */ 68.1787 --static char input_tab_char = '\t'; 68.1788 -+static char input_tab_char[MB_LEN_MAX] = "\t"; 68.1789 - 68.1790 - /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... 68.1791 - where the leftmost column is 1. */ 68.1792 -@@ -566,7 +609,10 @@ static int chars_per_input_tab = 8; 68.1793 - static bool tabify_output = false; 68.1794 - 68.1795 - /* (-i) The output tab character. */ 68.1796 --static char output_tab_char = '\t'; 68.1797 -+static char output_tab_char[MB_LEN_MAX] = "\t"; 68.1798 -+ 68.1799 -+/* (-i) The byte length of output tab character. */ 68.1800 -+static int output_tab_char_length = 1; 68.1801 - 68.1802 - /* (-i) The width of the output tab. */ 68.1803 - static int chars_per_output_tab = 8; 68.1804 -@@ -636,7 +682,13 @@ static int line_number; 68.1805 - static bool numbered_lines = false; 68.1806 - 68.1807 - /* (-n) Character which follows each line number. */ 68.1808 --static char number_separator = '\t'; 68.1809 -+static char number_separator[MB_LEN_MAX] = "\t"; 68.1810 -+ 68.1811 -+/* (-n) The byte length of the character which follows each line number. */ 68.1812 -+static int number_separator_length = 1; 68.1813 -+ 68.1814 -+/* (-n) The character width of the character which follows each line number. */ 68.1815 -+static int number_separator_width = 0; 68.1816 - 68.1817 - /* (-n) line counting starts with 1st line of input file (not with 1st 68.1818 - line of 1st page printed). */ 68.1819 -@@ -689,6 +741,7 @@ static bool use_col_separator = false; 68.1820 - -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ 68.1821 - static char *col_sep_string = (char *) ""; 68.1822 - static int col_sep_length = 0; 68.1823 -+static int col_sep_width = 0; 68.1824 - static char *column_separator = (char *) " "; 68.1825 - static char *line_separator = (char *) "\t"; 68.1826 - 68.1827 -@@ -839,6 +892,13 @@ separator_string (const char *optarg_S) 68.1828 - col_sep_length = (int) strlen (optarg_S); 68.1829 - col_sep_string = xmalloc (col_sep_length + 1); 68.1830 - strcpy (col_sep_string, optarg_S); 68.1831 -+ 68.1832 -+#if HAVE_MBRTOWC 68.1833 -+ if (MB_CUR_MAX > 1) 68.1834 -+ col_sep_width = mbswidth (col_sep_string, 0); 68.1835 -+ else 68.1836 -+#endif 68.1837 -+ col_sep_width = col_sep_length; 68.1838 - } 68.1839 - 68.1840 - int 68.1841 -@@ -863,6 +923,21 @@ main (int argc, char **argv) 68.1842 - 68.1843 - atexit (close_stdout); 68.1844 - 68.1845 -+/* Define which functions are used, the ones for single byte locale or the ones 68.1846 -+ for multibyte locale. */ 68.1847 -+#if HAVE_MBRTOWC 68.1848 -+ if (MB_CUR_MAX > 1) 68.1849 -+ { 68.1850 -+ print_char = print_char_multi; 68.1851 -+ char_to_clump = char_to_clump_multi; 68.1852 -+ } 68.1853 -+ else 68.1854 -+#endif 68.1855 -+ { 68.1856 -+ print_char = print_char_single; 68.1857 -+ char_to_clump = char_to_clump_single; 68.1858 -+ } 68.1859 -+ 68.1860 - n_files = 0; 68.1861 - file_names = (argc > 1 68.1862 - ? xmalloc ((argc - 1) * sizeof (char *)) 68.1863 -@@ -939,8 +1014,12 @@ main (int argc, char **argv) 68.1864 - break; 68.1865 - case 'e': 68.1866 - if (optarg) 68.1867 -- getoptarg (optarg, 'e', &input_tab_char, 68.1868 -- &chars_per_input_tab); 68.1869 -+ { 68.1870 -+ int dummy_length, dummy_width; 68.1871 -+ 68.1872 -+ getoptarg (optarg, 'e', input_tab_char, &dummy_length, 68.1873 -+ &dummy_width, &chars_per_input_tab); 68.1874 -+ } 68.1875 - /* Could check tab width > 0. */ 68.1876 - untabify_input = true; 68.1877 - break; 68.1878 -@@ -953,8 +1032,12 @@ main (int argc, char **argv) 68.1879 - break; 68.1880 - case 'i': 68.1881 - if (optarg) 68.1882 -- getoptarg (optarg, 'i', &output_tab_char, 68.1883 -- &chars_per_output_tab); 68.1884 -+ { 68.1885 -+ int dummy_width; 68.1886 -+ 68.1887 -+ getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length, 68.1888 -+ &dummy_width, &chars_per_output_tab); 68.1889 -+ } 68.1890 - /* Could check tab width > 0. */ 68.1891 - tabify_output = true; 68.1892 - break; 68.1893 -@@ -972,8 +1055,8 @@ main (int argc, char **argv) 68.1894 - case 'n': 68.1895 - numbered_lines = true; 68.1896 - if (optarg) 68.1897 -- getoptarg (optarg, 'n', &number_separator, 68.1898 -- &chars_per_number); 68.1899 -+ getoptarg (optarg, 'n', number_separator, &number_separator_length, 68.1900 -+ &number_separator_width, &chars_per_number); 68.1901 - break; 68.1902 - case 'N': 68.1903 - skip_count = false; 68.1904 -@@ -997,7 +1080,7 @@ main (int argc, char **argv) 68.1905 - old_s = false; 68.1906 - /* Reset an additional input of -s, -S dominates -s */ 68.1907 - col_sep_string = bad_cast (""); 68.1908 -- col_sep_length = 0; 68.1909 -+ col_sep_length = col_sep_width = 0; 68.1910 - use_col_separator = true; 68.1911 - if (optarg) 68.1912 - separator_string (optarg); 68.1913 -@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, i 68.1914 - a number. */ 68.1915 - 68.1916 - static void 68.1917 --getoptarg (char *arg, char switch_char, char *character, int *number) 68.1918 -+getoptarg (char *arg, char switch_char, char *character, int *character_length, 68.1919 -+ int *character_width, int *number) 68.1920 - { 68.1921 - if (!ISDIGIT (*arg)) 68.1922 -- *character = *arg++; 68.1923 -+ { 68.1924 -+#ifdef HAVE_MBRTOWC 68.1925 -+ if (MB_CUR_MAX > 1) /* for multibyte locale. */ 68.1926 -+ { 68.1927 -+ wchar_t wc; 68.1928 -+ size_t mblength; 68.1929 -+ int width; 68.1930 -+ mbstate_t state = {'\0'}; 68.1931 -+ 68.1932 -+ mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state); 68.1933 -+ 68.1934 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 68.1935 -+ { 68.1936 -+ *character_length = 1; 68.1937 -+ *character_width = 1; 68.1938 -+ } 68.1939 -+ else 68.1940 -+ { 68.1941 -+ *character_length = (mblength < 1) ? 1 : mblength; 68.1942 -+ width = wcwidth (wc); 68.1943 -+ *character_width = (width < 0) ? 0 : width; 68.1944 -+ } 68.1945 -+ 68.1946 -+ strncpy (character, arg, *character_length); 68.1947 -+ arg += *character_length; 68.1948 -+ } 68.1949 -+ else /* for single byte locale. */ 68.1950 -+#endif 68.1951 -+ { 68.1952 -+ *character = *arg++; 68.1953 -+ *character_length = 1; 68.1954 -+ *character_width = 1; 68.1955 -+ } 68.1956 -+ } 68.1957 -+ 68.1958 - if (*arg) 68.1959 - { 68.1960 - long int tmp_long; 68.1961 -@@ -1177,6 +1295,11 @@ static void 68.1962 - init_parameters (int number_of_files) 68.1963 - { 68.1964 - int chars_used_by_number = 0; 68.1965 -+ int mb_len = 1; 68.1966 -+#if HAVE_MBRTOWC 68.1967 -+ if (MB_CUR_MAX > 1) 68.1968 -+ mb_len = MB_LEN_MAX; 68.1969 -+#endif 68.1970 - 68.1971 - lines_per_body = lines_per_page - lines_per_header - lines_per_footer; 68.1972 - if (lines_per_body <= 0) 68.1973 -@@ -1214,7 +1337,7 @@ init_parameters (int number_of_files) 68.1974 - else 68.1975 - col_sep_string = column_separator; 68.1976 - 68.1977 -- col_sep_length = 1; 68.1978 -+ col_sep_length = col_sep_width = 1; 68.1979 - use_col_separator = true; 68.1980 - } 68.1981 - /* It's rather pointless to define a TAB separator with column 68.1982 -@@ -1244,11 +1367,11 @@ init_parameters (int number_of_files) 68.1983 - + TAB_WIDTH (chars_per_input_tab, chars_per_number); */ 68.1984 - 68.1985 - /* Estimate chars_per_text without any margin and keep it constant. */ 68.1986 -- if (number_separator == '\t') 68.1987 -+ if (number_separator[0] == '\t') 68.1988 - number_width = (chars_per_number 68.1989 - + TAB_WIDTH (chars_per_default_tab, chars_per_number)); 68.1990 - else 68.1991 -- number_width = chars_per_number + 1; 68.1992 -+ number_width = chars_per_number + number_separator_width; 68.1993 - 68.1994 - /* The number is part of the column width unless we are 68.1995 - printing files in parallel. */ 68.1996 -@@ -1257,7 +1380,7 @@ init_parameters (int number_of_files) 68.1997 - } 68.1998 - 68.1999 - chars_per_column = (chars_per_line - chars_used_by_number 68.2000 -- - (columns - 1) * col_sep_length) / columns; 68.2001 -+ - (columns - 1) * col_sep_width) / columns; 68.2002 - 68.2003 - if (chars_per_column < 1) 68.2004 - error (EXIT_FAILURE, 0, _("page width too narrow")); 68.2005 -@@ -1275,7 +1398,7 @@ init_parameters (int number_of_files) 68.2006 - We've to use 8 as the lower limit, if we use chars_per_default_tab = 8 68.2007 - to expand a tab which is not an input_tab-char. */ 68.2008 - free (clump_buff); 68.2009 -- clump_buff = xmalloc (MAX (8, chars_per_input_tab)); 68.2010 -+ clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab)); 68.2011 - } 68.2012 - 68.2013 - /* Open the necessary files, 68.2014 -@@ -1383,7 +1506,7 @@ init_funcs (void) 68.2015 - 68.2016 - /* Enlarge p->start_position of first column to use the same form of 68.2017 - padding_not_printed with all columns. */ 68.2018 -- h = h + col_sep_length; 68.2019 -+ h = h + col_sep_width; 68.2020 - 68.2021 - /* This loop takes care of all but the rightmost column. */ 68.2022 - 68.2023 -@@ -1417,7 +1540,7 @@ init_funcs (void) 68.2024 - } 68.2025 - else 68.2026 - { 68.2027 -- h = h_next + col_sep_length; 68.2028 -+ h = h_next + col_sep_width; 68.2029 - h_next = h + chars_per_column; 68.2030 - } 68.2031 - } 68.2032 -@@ -1708,9 +1831,9 @@ static void 68.2033 - align_column (COLUMN *p) 68.2034 - { 68.2035 - padding_not_printed = p->start_position; 68.2036 -- if (padding_not_printed - col_sep_length > 0) 68.2037 -+ if (padding_not_printed - col_sep_width > 0) 68.2038 - { 68.2039 -- pad_across_to (padding_not_printed - col_sep_length); 68.2040 -+ pad_across_to (padding_not_printed - col_sep_width); 68.2041 - padding_not_printed = ANYWHERE; 68.2042 - } 68.2043 - 68.2044 -@@ -1981,13 +2104,13 @@ store_char (char c) 68.2045 - /* May be too generous. */ 68.2046 - buff = X2REALLOC (buff, &buff_allocated); 68.2047 - } 68.2048 -- buff[buff_current++] = c; 68.2049 -+ buff[buff_current++] = (unsigned char) c; 68.2050 - } 68.2051 - 68.2052 - static void 68.2053 - add_line_number (COLUMN *p) 68.2054 - { 68.2055 -- int i; 68.2056 -+ int i, j; 68.2057 - char *s; 68.2058 - int num_width; 68.2059 - 68.2060 -@@ -2004,22 +2127,24 @@ add_line_number (COLUMN *p) 68.2061 - /* Tabification is assumed for multiple columns, also for n-separators, 68.2062 - but 'default n-separator = TAB' hasn't been given priority over 68.2063 - equal column_width also specified by POSIX. */ 68.2064 -- if (number_separator == '\t') 68.2065 -+ if (number_separator[0] == '\t') 68.2066 - { 68.2067 - i = number_width - chars_per_number; 68.2068 - while (i-- > 0) 68.2069 - (p->char_func) (' '); 68.2070 - } 68.2071 - else 68.2072 -- (p->char_func) (number_separator); 68.2073 -+ for (j = 0; j < number_separator_length; j++) 68.2074 -+ (p->char_func) (number_separator[j]); 68.2075 - } 68.2076 - else 68.2077 - /* To comply with POSIX, we avoid any expansion of default TAB 68.2078 - separator with a single column output. No column_width requirement 68.2079 - has to be considered. */ 68.2080 - { 68.2081 -- (p->char_func) (number_separator); 68.2082 -- if (number_separator == '\t') 68.2083 -+ for (j = 0; j < number_separator_length; j++) 68.2084 -+ (p->char_func) (number_separator[j]); 68.2085 -+ if (number_separator[0] == '\t') 68.2086 - output_position = POS_AFTER_TAB (chars_per_output_tab, 68.2087 - output_position); 68.2088 - } 68.2089 -@@ -2180,7 +2305,7 @@ print_white_space (void) 68.2090 - while (goal - h_old > 1 68.2091 - && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) 68.2092 - { 68.2093 -- putchar (output_tab_char); 68.2094 -+ fwrite (output_tab_char, sizeof(char), output_tab_char_length, stdout); 68.2095 - h_old = h_new; 68.2096 - } 68.2097 - while (++h_old <= goal) 68.2098 -@@ -2200,6 +2325,7 @@ print_sep_string (void) 68.2099 - { 68.2100 - char *s; 68.2101 - int l = col_sep_length; 68.2102 -+ int not_space_flag; 68.2103 - 68.2104 - s = col_sep_string; 68.2105 - 68.2106 -@@ -2213,6 +2339,7 @@ print_sep_string (void) 68.2107 - { 68.2108 - for (; separators_not_printed > 0; --separators_not_printed) 68.2109 - { 68.2110 -+ not_space_flag = 0; 68.2111 - while (l-- > 0) 68.2112 - { 68.2113 - /* 3 types of sep_strings: spaces only, spaces and chars, 68.2114 -@@ -2226,12 +2353,15 @@ print_sep_string (void) 68.2115 - } 68.2116 - else 68.2117 - { 68.2118 -+ not_space_flag = 1; 68.2119 - if (spaces_not_printed > 0) 68.2120 - print_white_space (); 68.2121 - putchar (*s++); 68.2122 -- ++output_position; 68.2123 - } 68.2124 - } 68.2125 -+ if (not_space_flag) 68.2126 -+ output_position += col_sep_width; 68.2127 -+ 68.2128 - /* sep_string ends with some spaces */ 68.2129 - if (spaces_not_printed > 0) 68.2130 - print_white_space (); 68.2131 -@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clu 68.2132 - required number of tabs and spaces. */ 68.2133 - 68.2134 - static void 68.2135 --print_char (char c) 68.2136 -+print_char_single (char c) 68.2137 - { 68.2138 - if (tabify_output) 68.2139 - { 68.2140 -@@ -2283,6 +2413,74 @@ print_char (char c) 68.2141 - putchar (c); 68.2142 - } 68.2143 - 68.2144 -+#ifdef HAVE_MBRTOWC 68.2145 -+static void 68.2146 -+print_char_multi (char c) 68.2147 -+{ 68.2148 -+ static size_t mbc_pos = 0; 68.2149 -+ static char mbc[MB_LEN_MAX] = {'\0'}; 68.2150 -+ static mbstate_t state = {'\0'}; 68.2151 -+ mbstate_t state_bak; 68.2152 -+ wchar_t wc; 68.2153 -+ size_t mblength; 68.2154 -+ int width; 68.2155 -+ 68.2156 -+ if (tabify_output) 68.2157 -+ { 68.2158 -+ state_bak = state; 68.2159 -+ mbc[mbc_pos++] = c; 68.2160 -+ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); 68.2161 -+ 68.2162 -+ while (mbc_pos > 0) 68.2163 -+ { 68.2164 -+ switch (mblength) 68.2165 -+ { 68.2166 -+ case (size_t)-2: 68.2167 -+ state = state_bak; 68.2168 -+ return; 68.2169 -+ 68.2170 -+ case (size_t)-1: 68.2171 -+ state = state_bak; 68.2172 -+ ++output_position; 68.2173 -+ putchar (mbc[0]); 68.2174 -+ memmove (mbc, mbc + 1, MB_CUR_MAX - 1); 68.2175 -+ --mbc_pos; 68.2176 -+ break; 68.2177 -+ 68.2178 -+ case 0: 68.2179 -+ mblength = 1; 68.2180 -+ 68.2181 -+ default: 68.2182 -+ if (wc == L' ') 68.2183 -+ { 68.2184 -+ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 68.2185 -+ --mbc_pos; 68.2186 -+ ++spaces_not_printed; 68.2187 -+ return; 68.2188 -+ } 68.2189 -+ else if (spaces_not_printed > 0) 68.2190 -+ print_white_space (); 68.2191 -+ 68.2192 -+ /* Nonprintables are assumed to have width 0, except L'\b'. */ 68.2193 -+ if ((width = wcwidth (wc)) < 1) 68.2194 -+ { 68.2195 -+ if (wc == L'\b') 68.2196 -+ --output_position; 68.2197 -+ } 68.2198 -+ else 68.2199 -+ output_position += width; 68.2200 -+ 68.2201 -+ fwrite (mbc, sizeof(char), mblength, stdout); 68.2202 -+ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 68.2203 -+ mbc_pos -= mblength; 68.2204 -+ } 68.2205 -+ } 68.2206 -+ return; 68.2207 -+ } 68.2208 -+ putchar (c); 68.2209 -+} 68.2210 -+#endif 68.2211 -+ 68.2212 - /* Skip to page PAGE before printing. 68.2213 - PAGE may be larger than total number of pages. */ 68.2214 - 68.2215 -@@ -2462,9 +2660,9 @@ read_line (COLUMN *p) 68.2216 - align_empty_cols = false; 68.2217 - } 68.2218 - 68.2219 -- if (padding_not_printed - col_sep_length > 0) 68.2220 -+ if (padding_not_printed - col_sep_width > 0) 68.2221 - { 68.2222 -- pad_across_to (padding_not_printed - col_sep_length); 68.2223 -+ pad_across_to (padding_not_printed - col_sep_width); 68.2224 - padding_not_printed = ANYWHERE; 68.2225 - } 68.2226 - 68.2227 -@@ -2534,7 +2732,7 @@ print_stored (COLUMN *p) 68.2228 - int i; 68.2229 - 68.2230 - int line = p->current_line++; 68.2231 -- char *first = &buff[line_vector[line]]; 68.2232 -+ unsigned char *first = &buff[line_vector[line]]; 68.2233 - /* FIXME 68.2234 - UMR: Uninitialized memory read: 68.2235 - * This is occurring while in: 68.2236 -@@ -2546,7 +2744,7 @@ print_stored (COLUMN *p) 68.2237 - xmalloc [xmalloc.c:94] 68.2238 - init_store_cols [pr.c:1648] 68.2239 - */ 68.2240 -- char *last = &buff[line_vector[line + 1]]; 68.2241 -+ unsigned char *last = &buff[line_vector[line + 1]]; 68.2242 - 68.2243 - pad_vertically = true; 68.2244 - 68.2245 -@@ -2565,9 +2763,9 @@ print_stored (COLUMN *p) 68.2246 - } 68.2247 - } 68.2248 - 68.2249 -- if (padding_not_printed - col_sep_length > 0) 68.2250 -+ if (padding_not_printed - col_sep_width > 0) 68.2251 - { 68.2252 -- pad_across_to (padding_not_printed - col_sep_length); 68.2253 -+ pad_across_to (padding_not_printed - col_sep_width); 68.2254 - padding_not_printed = ANYWHERE; 68.2255 - } 68.2256 - 68.2257 -@@ -2580,8 +2778,8 @@ print_stored (COLUMN *p) 68.2258 - if (spaces_not_printed == 0) 68.2259 - { 68.2260 - output_position = p->start_position + end_vector[line]; 68.2261 -- if (p->start_position - col_sep_length == chars_per_margin) 68.2262 -- output_position -= col_sep_length; 68.2263 -+ if (p->start_position - col_sep_width == chars_per_margin) 68.2264 -+ output_position -= col_sep_width; 68.2265 - } 68.2266 - 68.2267 - return true; 68.2268 -@@ -2600,7 +2798,7 @@ print_stored (COLUMN *p) 68.2269 - number of characters is 1.) */ 68.2270 - 68.2271 - static int 68.2272 --char_to_clump (char c) 68.2273 -+char_to_clump_single (char c) 68.2274 - { 68.2275 - unsigned char uc = c; 68.2276 - char *s = clump_buff; 68.2277 -@@ -2610,10 +2808,10 @@ char_to_clump (char c) 68.2278 - int chars; 68.2279 - int chars_per_c = 8; 68.2280 - 68.2281 -- if (c == input_tab_char) 68.2282 -+ if (c == input_tab_char[0]) 68.2283 - chars_per_c = chars_per_input_tab; 68.2284 - 68.2285 -- if (c == input_tab_char || c == '\t') 68.2286 -+ if (c == input_tab_char[0] || c == '\t') 68.2287 - { 68.2288 - width = TAB_WIDTH (chars_per_c, input_position); 68.2289 - 68.2290 -@@ -2694,6 +2892,164 @@ char_to_clump (char c) 68.2291 - return chars; 68.2292 - } 68.2293 - 68.2294 -+#ifdef HAVE_MBRTOWC 68.2295 -+static int 68.2296 -+char_to_clump_multi (char c) 68.2297 -+{ 68.2298 -+ static size_t mbc_pos = 0; 68.2299 -+ static char mbc[MB_LEN_MAX] = {'\0'}; 68.2300 -+ static mbstate_t state = {'\0'}; 68.2301 -+ mbstate_t state_bak; 68.2302 -+ wchar_t wc; 68.2303 -+ size_t mblength; 68.2304 -+ int wc_width; 68.2305 -+ register char *s = clump_buff; 68.2306 -+ register int i, j; 68.2307 -+ char esc_buff[4]; 68.2308 -+ int width; 68.2309 -+ int chars; 68.2310 -+ int chars_per_c = 8; 68.2311 -+ 68.2312 -+ state_bak = state; 68.2313 -+ mbc[mbc_pos++] = c; 68.2314 -+ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); 68.2315 -+ 68.2316 -+ width = 0; 68.2317 -+ chars = 0; 68.2318 -+ while (mbc_pos > 0) 68.2319 -+ { 68.2320 -+ switch (mblength) 68.2321 -+ { 68.2322 -+ case (size_t)-2: 68.2323 -+ state = state_bak; 68.2324 -+ return 0; 68.2325 -+ 68.2326 -+ case (size_t)-1: 68.2327 -+ state = state_bak; 68.2328 -+ mblength = 1; 68.2329 -+ 68.2330 -+ if (use_esc_sequence || use_cntrl_prefix) 68.2331 -+ { 68.2332 -+ width = +4; 68.2333 -+ chars = +4; 68.2334 -+ *s++ = '\\'; 68.2335 -+ sprintf (esc_buff, "%03o", (unsigned char) mbc[0]); 68.2336 -+ for (i = 0; i <= 2; ++i) 68.2337 -+ *s++ = (int) esc_buff[i]; 68.2338 -+ } 68.2339 -+ else 68.2340 -+ { 68.2341 -+ width += 1; 68.2342 -+ chars += 1; 68.2343 -+ *s++ = mbc[0]; 68.2344 -+ } 68.2345 -+ break; 68.2346 -+ 68.2347 -+ case 0: 68.2348 -+ mblength = 1; 68.2349 -+ /* Fall through */ 68.2350 -+ 68.2351 -+ default: 68.2352 -+ if (memcmp (mbc, input_tab_char, mblength) == 0) 68.2353 -+ chars_per_c = chars_per_input_tab; 68.2354 -+ 68.2355 -+ if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t') 68.2356 -+ { 68.2357 -+ int width_inc; 68.2358 -+ 68.2359 -+ width_inc = TAB_WIDTH (chars_per_c, input_position); 68.2360 -+ width += width_inc; 68.2361 -+ 68.2362 -+ if (untabify_input) 68.2363 -+ { 68.2364 -+ for (i = width_inc; i; --i) 68.2365 -+ *s++ = ' '; 68.2366 -+ chars += width_inc; 68.2367 -+ } 68.2368 -+ else 68.2369 -+ { 68.2370 -+ for (i = 0; i < mblength; i++) 68.2371 -+ *s++ = mbc[i]; 68.2372 -+ chars += mblength; 68.2373 -+ } 68.2374 -+ } 68.2375 -+ else if ((wc_width = wcwidth (wc)) < 1) 68.2376 -+ { 68.2377 -+ if (use_esc_sequence) 68.2378 -+ { 68.2379 -+ for (i = 0; i < mblength; i++) 68.2380 -+ { 68.2381 -+ width += 4; 68.2382 -+ chars += 4; 68.2383 -+ *s++ = '\\'; 68.2384 -+ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); 68.2385 -+ for (j = 0; j <= 2; ++j) 68.2386 -+ *s++ = (int) esc_buff[j]; 68.2387 -+ } 68.2388 -+ } 68.2389 -+ else if (use_cntrl_prefix) 68.2390 -+ { 68.2391 -+ if (wc < 0200) 68.2392 -+ { 68.2393 -+ width += 2; 68.2394 -+ chars += 2; 68.2395 -+ *s++ = '^'; 68.2396 -+ *s++ = wc ^ 0100; 68.2397 -+ } 68.2398 -+ else 68.2399 -+ { 68.2400 -+ for (i = 0; i < mblength; i++) 68.2401 -+ { 68.2402 -+ width += 4; 68.2403 -+ chars += 4; 68.2404 -+ *s++ = '\\'; 68.2405 -+ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); 68.2406 -+ for (j = 0; j <= 2; ++j) 68.2407 -+ *s++ = (int) esc_buff[j]; 68.2408 -+ } 68.2409 -+ } 68.2410 -+ } 68.2411 -+ else if (wc == L'\b') 68.2412 -+ { 68.2413 -+ width += -1; 68.2414 -+ chars += 1; 68.2415 -+ *s++ = c; 68.2416 -+ } 68.2417 -+ else 68.2418 -+ { 68.2419 -+ width += 0; 68.2420 -+ chars += mblength; 68.2421 -+ for (i = 0; i < mblength; i++) 68.2422 -+ *s++ = mbc[i]; 68.2423 -+ } 68.2424 -+ } 68.2425 -+ else 68.2426 -+ { 68.2427 -+ width += wc_width; 68.2428 -+ chars += mblength; 68.2429 -+ for (i = 0; i < mblength; i++) 68.2430 -+ *s++ = mbc[i]; 68.2431 -+ } 68.2432 -+ } 68.2433 -+ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 68.2434 -+ mbc_pos -= mblength; 68.2435 -+ } 68.2436 -+ 68.2437 -+ /* Too many backspaces must put us in position 0 -- never negative. */ 68.2438 -+ if (width < 0 && input_position == 0) 68.2439 -+ { 68.2440 -+ chars = 0; 68.2441 -+ input_position = 0; 68.2442 -+ } 68.2443 -+ else if (width < 0 && input_position <= -width) 68.2444 -+ input_position = 0; 68.2445 -+ else 68.2446 -+ input_position += width; 68.2447 -+ 68.2448 -+ return chars; 68.2449 -+} 68.2450 -+#endif 68.2451 -+ 68.2452 - /* We've just printed some files and need to clean up things before 68.2453 - looking for more options and printing the next batch of files. 68.2454 - 68.2455 -diff -Naurp coreutils-8.25-orig/src/sort.c coreutils-8.25/src/sort.c 68.2456 ---- coreutils-8.25-orig/src/sort.c 2016-01-16 13:09:33.000000000 -0600 68.2457 -+++ coreutils-8.25/src/sort.c 2016-02-08 19:07:10.310944648 -0600 68.2458 -@@ -29,6 +29,14 @@ 68.2459 - #include <sys/wait.h> 68.2460 - #include <signal.h> 68.2461 - #include <assert.h> 68.2462 -+#if HAVE_WCHAR_H 68.2463 -+# include <wchar.h> 68.2464 -+#endif 68.2465 -+/* Get isw* functions. */ 68.2466 -+#if HAVE_WCTYPE_H 68.2467 -+# include <wctype.h> 68.2468 -+#endif 68.2469 -+ 68.2470 - #include "system.h" 68.2471 - #include "argmatch.h" 68.2472 - #include "error.h" 68.2473 -@@ -163,14 +171,39 @@ static int decimal_point; 68.2474 - /* Thousands separator; if -1, then there isn't one. */ 68.2475 - static int thousands_sep; 68.2476 - 68.2477 -+/* True if -f is specified. */ 68.2478 -+static bool folding; 68.2479 -+ 68.2480 - /* Nonzero if the corresponding locales are hard. */ 68.2481 - static bool hard_LC_COLLATE; 68.2482 --#if HAVE_NL_LANGINFO 68.2483 -+#if HAVE_LANGINFO_CODESET 68.2484 - static bool hard_LC_TIME; 68.2485 - #endif 68.2486 - 68.2487 - #define NONZERO(x) ((x) != 0) 68.2488 - 68.2489 -+/* get a multibyte character's byte length. */ 68.2490 -+#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE) \ 68.2491 -+ do \ 68.2492 -+ { \ 68.2493 -+ wchar_t wc; \ 68.2494 -+ mbstate_t state_bak; \ 68.2495 -+ \ 68.2496 -+ state_bak = STATE; \ 68.2497 -+ mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE); \ 68.2498 -+ \ 68.2499 -+ switch (MBLENGTH) \ 68.2500 -+ { \ 68.2501 -+ case (size_t)-1: \ 68.2502 -+ case (size_t)-2: \ 68.2503 -+ STATE = state_bak; \ 68.2504 -+ /* Fall through. */ \ 68.2505 -+ case 0: \ 68.2506 -+ MBLENGTH = 1; \ 68.2507 -+ } \ 68.2508 -+ } \ 68.2509 -+ while (0) 68.2510 -+ 68.2511 - /* The kind of blanks for '-b' to skip in various options. */ 68.2512 - enum blanktype { bl_start, bl_end, bl_both }; 68.2513 - 68.2514 -@@ -344,13 +377,11 @@ static bool reverse; 68.2515 - they were read if all keys compare equal. */ 68.2516 - static bool stable; 68.2517 - 68.2518 --/* If TAB has this value, blanks separate fields. */ 68.2519 --enum { TAB_DEFAULT = CHAR_MAX + 1 }; 68.2520 -- 68.2521 --/* Tab character separating fields. If TAB_DEFAULT, then fields are 68.2522 -+/* Tab character separating fields. If tab_length is 0, then fields are 68.2523 - separated by the empty string between a non-blank character and a blank 68.2524 - character. */ 68.2525 --static int tab = TAB_DEFAULT; 68.2526 -+static char tab[MB_LEN_MAX + 1]; 68.2527 -+static size_t tab_length = 0; 68.2528 - 68.2529 - /* Flag to remove consecutive duplicate lines from the output. 68.2530 - Only the last of a sequence of equal lines will be output. */ 68.2531 -@@ -810,6 +841,46 @@ reap_all (void) 68.2532 - reap (-1); 68.2533 - } 68.2534 - 68.2535 -+/* Function pointers. */ 68.2536 -+static void 68.2537 -+(*inittables) (void); 68.2538 -+static char * 68.2539 -+(*begfield) (const struct line*, const struct keyfield *); 68.2540 -+static char * 68.2541 -+(*limfield) (const struct line*, const struct keyfield *); 68.2542 -+static void 68.2543 -+(*skipblanks) (char **ptr, char *lim); 68.2544 -+static int 68.2545 -+(*getmonth) (char const *, size_t, char **); 68.2546 -+static int 68.2547 -+(*keycompare) (const struct line *, const struct line *); 68.2548 -+static int 68.2549 -+(*numcompare) (const char *, const char *); 68.2550 -+ 68.2551 -+/* Test for white space multibyte character. 68.2552 -+ Set LENGTH the byte length of investigated multibyte character. */ 68.2553 -+#if HAVE_MBRTOWC 68.2554 -+static int 68.2555 -+ismbblank (const char *str, size_t len, size_t *length) 68.2556 -+{ 68.2557 -+ size_t mblength; 68.2558 -+ wchar_t wc; 68.2559 -+ mbstate_t state; 68.2560 -+ 68.2561 -+ memset (&state, '\0', sizeof(mbstate_t)); 68.2562 -+ mblength = mbrtowc (&wc, str, len, &state); 68.2563 -+ 68.2564 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 68.2565 -+ { 68.2566 -+ *length = 1; 68.2567 -+ return 0; 68.2568 -+ } 68.2569 -+ 68.2570 -+ *length = (mblength < 1) ? 1 : mblength; 68.2571 -+ return iswblank (wc) || wc == '\n'; 68.2572 -+} 68.2573 -+#endif 68.2574 -+ 68.2575 - /* Clean up any remaining temporary files. */ 68.2576 - 68.2577 - static void 68.2578 -@@ -1254,7 +1325,7 @@ zaptemp (char const *name) 68.2579 - free (node); 68.2580 - } 68.2581 - 68.2582 --#if HAVE_NL_LANGINFO 68.2583 -+#if HAVE_LANGINFO_CODESET 68.2584 - 68.2585 - static int 68.2586 - struct_month_cmp (void const *m1, void const *m2) 68.2587 -@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void c 68.2588 - /* Initialize the character class tables. */ 68.2589 - 68.2590 - static void 68.2591 --inittables (void) 68.2592 -+inittables_uni (void) 68.2593 - { 68.2594 - size_t i; 68.2595 - 68.2596 -@@ -1281,7 +1352,7 @@ inittables (void) 68.2597 - fold_toupper[i] = toupper (i); 68.2598 - } 68.2599 - 68.2600 --#if HAVE_NL_LANGINFO 68.2601 -+#if HAVE_LANGINFO_CODESET 68.2602 - /* If we're not in the "C" locale, read different names for months. */ 68.2603 - if (hard_LC_TIME) 68.2604 - { 68.2605 -@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char con 68.2606 - xstrtol_fatal (e, oi, c, long_options, s); 68.2607 - } 68.2608 - 68.2609 -+#if HAVE_MBRTOWC 68.2610 -+static void 68.2611 -+inittables_mb (void) 68.2612 -+{ 68.2613 -+ int i, j, k, l; 68.2614 -+ char *name, *s, *lc_time, *lc_ctype; 68.2615 -+ size_t s_len, mblength; 68.2616 -+ char mbc[MB_LEN_MAX]; 68.2617 -+ wchar_t wc, pwc; 68.2618 -+ mbstate_t state_mb, state_wc; 68.2619 -+ 68.2620 -+ lc_time = setlocale (LC_TIME, ""); 68.2621 -+ if (lc_time) 68.2622 -+ lc_time = xstrdup (lc_time); 68.2623 -+ 68.2624 -+ lc_ctype = setlocale (LC_CTYPE, ""); 68.2625 -+ if (lc_ctype) 68.2626 -+ lc_ctype = xstrdup (lc_ctype); 68.2627 -+ 68.2628 -+ if (lc_time && lc_ctype) 68.2629 -+ /* temporarily set LC_CTYPE to match LC_TIME, so that we can convert 68.2630 -+ * the names of months to upper case */ 68.2631 -+ setlocale (LC_CTYPE, lc_time); 68.2632 -+ 68.2633 -+ for (i = 0; i < MONTHS_PER_YEAR; i++) 68.2634 -+ { 68.2635 -+ s = (char *) nl_langinfo (ABMON_1 + i); 68.2636 -+ s_len = strlen (s); 68.2637 -+ monthtab[i].name = name = (char *) xmalloc (s_len + 1); 68.2638 -+ monthtab[i].val = i + 1; 68.2639 -+ 68.2640 -+ memset (&state_mb, '\0', sizeof (mbstate_t)); 68.2641 -+ memset (&state_wc, '\0', sizeof (mbstate_t)); 68.2642 -+ 68.2643 -+ for (j = 0; j < s_len;) 68.2644 -+ { 68.2645 -+ if (!ismbblank (s + j, s_len - j, &mblength)) 68.2646 -+ break; 68.2647 -+ j += mblength; 68.2648 -+ } 68.2649 -+ 68.2650 -+ for (k = 0; j < s_len;) 68.2651 -+ { 68.2652 -+ mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb); 68.2653 -+ assert (mblength != (size_t)-1 && mblength != (size_t)-2); 68.2654 -+ if (mblength == 0) 68.2655 -+ break; 68.2656 -+ 68.2657 -+ pwc = towupper (wc); 68.2658 -+ if (pwc == wc) 68.2659 -+ { 68.2660 -+ memcpy (mbc, s + j, mblength); 68.2661 -+ j += mblength; 68.2662 -+ } 68.2663 -+ else 68.2664 -+ { 68.2665 -+ j += mblength; 68.2666 -+ mblength = wcrtomb (mbc, pwc, &state_wc); 68.2667 -+ assert (mblength != (size_t)0 && mblength != (size_t)-1); 68.2668 -+ } 68.2669 -+ 68.2670 -+ for (l = 0; l < mblength; l++) 68.2671 -+ name[k++] = mbc[l]; 68.2672 -+ } 68.2673 -+ name[k] = '\0'; 68.2674 -+ } 68.2675 -+ qsort ((void *) monthtab, MONTHS_PER_YEAR, 68.2676 -+ sizeof (struct month), struct_month_cmp); 68.2677 -+ 68.2678 -+ if (lc_time && lc_ctype) 68.2679 -+ /* restore the original locales */ 68.2680 -+ setlocale (LC_CTYPE, lc_ctype); 68.2681 -+ 68.2682 -+ free (lc_ctype); 68.2683 -+ free (lc_time); 68.2684 -+} 68.2685 -+#endif 68.2686 -+ 68.2687 - /* Specify the amount of main memory to use when sorting. */ 68.2688 - static void 68.2689 - specify_sort_size (int oi, char c, char const *s) 68.2690 -@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf 68.2691 - by KEY in LINE. */ 68.2692 - 68.2693 - static char * 68.2694 --begfield (struct line const *line, struct keyfield const *key) 68.2695 -+begfield_uni (const struct line *line, const struct keyfield *key) 68.2696 - { 68.2697 - char *ptr = line->text, *lim = ptr + line->length - 1; 68.2698 - size_t sword = key->sword; 68.2699 -@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struc 68.2700 - /* The leading field separator itself is included in a field when -t 68.2701 - is absent. */ 68.2702 - 68.2703 -- if (tab != TAB_DEFAULT) 68.2704 -+ if (tab_length) 68.2705 - while (ptr < lim && sword--) 68.2706 - { 68.2707 -- while (ptr < lim && *ptr != tab) 68.2708 -+ while (ptr < lim && *ptr != tab[0]) 68.2709 - ++ptr; 68.2710 - if (ptr < lim) 68.2711 - ++ptr; 68.2712 -@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struc 68.2713 - return ptr; 68.2714 - } 68.2715 - 68.2716 -+#if HAVE_MBRTOWC 68.2717 -+static char * 68.2718 -+begfield_mb (const struct line *line, const struct keyfield *key) 68.2719 -+{ 68.2720 -+ int i; 68.2721 -+ char *ptr = line->text, *lim = ptr + line->length - 1; 68.2722 -+ size_t sword = key->sword; 68.2723 -+ size_t schar = key->schar; 68.2724 -+ size_t mblength; 68.2725 -+ mbstate_t state; 68.2726 -+ 68.2727 -+ memset (&state, '\0', sizeof(mbstate_t)); 68.2728 -+ 68.2729 -+ if (tab_length) 68.2730 -+ while (ptr < lim && sword--) 68.2731 -+ { 68.2732 -+ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) 68.2733 -+ { 68.2734 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 68.2735 -+ ptr += mblength; 68.2736 -+ } 68.2737 -+ if (ptr < lim) 68.2738 -+ { 68.2739 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 68.2740 -+ ptr += mblength; 68.2741 -+ } 68.2742 -+ } 68.2743 -+ else 68.2744 -+ while (ptr < lim && sword--) 68.2745 -+ { 68.2746 -+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 68.2747 -+ ptr += mblength; 68.2748 -+ if (ptr < lim) 68.2749 -+ { 68.2750 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 68.2751 -+ ptr += mblength; 68.2752 -+ } 68.2753 -+ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) 68.2754 -+ ptr += mblength; 68.2755 -+ } 68.2756 -+ 68.2757 -+ if (key->skipsblanks) 68.2758 -+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 68.2759 -+ ptr += mblength; 68.2760 -+ 68.2761 -+ for (i = 0; i < schar; i++) 68.2762 -+ { 68.2763 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 68.2764 -+ 68.2765 -+ if (ptr + mblength > lim) 68.2766 -+ break; 68.2767 -+ else 68.2768 -+ ptr += mblength; 68.2769 -+ } 68.2770 -+ 68.2771 -+ return ptr; 68.2772 -+} 68.2773 -+#endif 68.2774 -+ 68.2775 - /* Return the limit of (a pointer to the first character after) the field 68.2776 - in LINE specified by KEY. */ 68.2777 - 68.2778 - static char * 68.2779 --limfield (struct line const *line, struct keyfield const *key) 68.2780 -+limfield_uni (const struct line *line, const struct keyfield *key) 68.2781 - { 68.2782 - char *ptr = line->text, *lim = ptr + line->length - 1; 68.2783 - size_t eword = key->eword, echar = key->echar; 68.2784 -@@ -1653,10 +1861,10 @@ limfield (struct line const *line, struc 68.2785 - 'beginning' is the first character following the delimiting TAB. 68.2786 - Otherwise, leave PTR pointing at the first 'blank' character after 68.2787 - the preceding field. */ 68.2788 -- if (tab != TAB_DEFAULT) 68.2789 -+ if (tab_length) 68.2790 - while (ptr < lim && eword--) 68.2791 - { 68.2792 -- while (ptr < lim && *ptr != tab) 68.2793 -+ while (ptr < lim && *ptr != tab[0]) 68.2794 - ++ptr; 68.2795 - if (ptr < lim && (eword || echar)) 68.2796 - ++ptr; 68.2797 -@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struc 68.2798 - */ 68.2799 - 68.2800 - /* Make LIM point to the end of (one byte past) the current field. */ 68.2801 -- if (tab != TAB_DEFAULT) 68.2802 -+ if (tab_length) 68.2803 - { 68.2804 - char *newlim; 68.2805 -- newlim = memchr (ptr, tab, lim - ptr); 68.2806 -+ newlim = memchr (ptr, tab[0], lim - ptr); 68.2807 - if (newlim) 68.2808 - lim = newlim; 68.2809 - } 68.2810 -@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struc 68.2811 - return ptr; 68.2812 - } 68.2813 - 68.2814 -+#if HAVE_MBRTOWC 68.2815 -+static char * 68.2816 -+limfield_mb (const struct line *line, const struct keyfield *key) 68.2817 -+{ 68.2818 -+ char *ptr = line->text, *lim = ptr + line->length - 1; 68.2819 -+ size_t eword = key->eword, echar = key->echar; 68.2820 -+ int i; 68.2821 -+ size_t mblength; 68.2822 -+ mbstate_t state; 68.2823 -+ 68.2824 -+ if (echar == 0) 68.2825 -+ eword++; /* skip all of end field. */ 68.2826 -+ 68.2827 -+ memset (&state, '\0', sizeof(mbstate_t)); 68.2828 -+ 68.2829 -+ if (tab_length) 68.2830 -+ while (ptr < lim && eword--) 68.2831 -+ { 68.2832 -+ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) 68.2833 -+ { 68.2834 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 68.2835 -+ ptr += mblength; 68.2836 -+ } 68.2837 -+ if (ptr < lim && (eword | echar)) 68.2838 -+ { 68.2839 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 68.2840 -+ ptr += mblength; 68.2841 -+ } 68.2842 -+ } 68.2843 -+ else 68.2844 -+ while (ptr < lim && eword--) 68.2845 -+ { 68.2846 -+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 68.2847 -+ ptr += mblength; 68.2848 -+ if (ptr < lim) 68.2849 -+ { 68.2850 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 68.2851 -+ ptr += mblength; 68.2852 -+ } 68.2853 -+ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) 68.2854 -+ ptr += mblength; 68.2855 -+ } 68.2856 -+ 68.2857 -+ 68.2858 -+# ifdef POSIX_UNSPECIFIED 68.2859 -+ /* Make LIM point to the end of (one byte past) the current field. */ 68.2860 -+ if (tab_length) 68.2861 -+ { 68.2862 -+ char *newlim, *p; 68.2863 -+ 68.2864 -+ newlim = NULL; 68.2865 -+ for (p = ptr; p < lim;) 68.2866 -+ { 68.2867 -+ if (memcmp (p, tab, tab_length) == 0) 68.2868 -+ { 68.2869 -+ newlim = p; 68.2870 -+ break; 68.2871 -+ } 68.2872 -+ 68.2873 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 68.2874 -+ p += mblength; 68.2875 -+ } 68.2876 -+ } 68.2877 -+ else 68.2878 -+ { 68.2879 -+ char *newlim; 68.2880 -+ newlim = ptr; 68.2881 -+ 68.2882 -+ while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength)) 68.2883 -+ newlim += mblength; 68.2884 -+ if (ptr < lim) 68.2885 -+ { 68.2886 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 68.2887 -+ ptr += mblength; 68.2888 -+ } 68.2889 -+ while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength)) 68.2890 -+ newlim += mblength; 68.2891 -+ lim = newlim; 68.2892 -+ } 68.2893 -+# endif 68.2894 -+ 68.2895 -+ if (echar != 0) 68.2896 -+ { 68.2897 -+ /* If we're skipping leading blanks, don't start counting characters 68.2898 -+ * until after skipping past any leading blanks. */ 68.2899 -+ if (key->skipeblanks) 68.2900 -+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 68.2901 -+ ptr += mblength; 68.2902 -+ 68.2903 -+ memset (&state, '\0', sizeof(mbstate_t)); 68.2904 -+ 68.2905 -+ /* Advance PTR by ECHAR (if possible), but no further than LIM. */ 68.2906 -+ for (i = 0; i < echar; i++) 68.2907 -+ { 68.2908 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 68.2909 -+ 68.2910 -+ if (ptr + mblength > lim) 68.2911 -+ break; 68.2912 -+ else 68.2913 -+ ptr += mblength; 68.2914 -+ } 68.2915 -+ } 68.2916 -+ 68.2917 -+ return ptr; 68.2918 -+} 68.2919 -+#endif 68.2920 -+ 68.2921 -+static void 68.2922 -+skipblanks_uni (char **ptr, char *lim) 68.2923 -+{ 68.2924 -+ while (*ptr < lim && blanks[to_uchar (**ptr)]) 68.2925 -+ ++(*ptr); 68.2926 -+} 68.2927 -+ 68.2928 -+#if HAVE_MBRTOWC 68.2929 -+static void 68.2930 -+skipblanks_mb (char **ptr, char *lim) 68.2931 -+{ 68.2932 -+ size_t mblength; 68.2933 -+ while (*ptr < lim && ismbblank (*ptr, lim - *ptr, &mblength)) 68.2934 -+ (*ptr) += mblength; 68.2935 -+} 68.2936 -+#endif 68.2937 -+ 68.2938 - /* Fill BUF reading from FP, moving buf->left bytes from the end 68.2939 - of buf->buf to the beginning first. If EOF is reached and the 68.2940 - file wasn't terminated by a newline, supply one. Set up BUF's line 68.2941 -@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, c 68.2942 - else 68.2943 - { 68.2944 - if (key->skipsblanks) 68.2945 -- while (blanks[to_uchar (*line_start)]) 68.2946 -- line_start++; 68.2947 -+ { 68.2948 -+#if HAVE_MBRTOWC 68.2949 -+ if (MB_CUR_MAX > 1) 68.2950 -+ { 68.2951 -+ size_t mblength; 68.2952 -+ while (line_start < line->keylim && 68.2953 -+ ismbblank (line_start, 68.2954 -+ line->keylim - line_start, 68.2955 -+ &mblength)) 68.2956 -+ line_start += mblength; 68.2957 -+ } 68.2958 -+ else 68.2959 -+#endif 68.2960 -+ while (blanks[to_uchar (*line_start)]) 68.2961 -+ line_start++; 68.2962 -+ } 68.2963 - line->keybeg = line_start; 68.2964 - } 68.2965 - } 68.2966 -@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char co 68.2967 - hideously fast. */ 68.2968 - 68.2969 - static int 68.2970 --numcompare (char const *a, char const *b) 68.2971 -+numcompare_uni (const char *a, const char *b) 68.2972 - { 68.2973 - while (blanks[to_uchar (*a)]) 68.2974 - a++; 68.2975 -@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b 68.2976 - return strnumcmp (a, b, decimal_point, thousands_sep); 68.2977 - } 68.2978 - 68.2979 -+#if HAVE_MBRTOWC 68.2980 -+static int 68.2981 -+numcompare_mb (const char *a, const char *b) 68.2982 -+{ 68.2983 -+ size_t mblength, len; 68.2984 -+ len = strlen (a); /* okay for UTF-8 */ 68.2985 -+ while (*a && ismbblank (a, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) 68.2986 -+ { 68.2987 -+ a += mblength; 68.2988 -+ len -= mblength; 68.2989 -+ } 68.2990 -+ len = strlen (b); /* okay for UTF-8 */ 68.2991 -+ while (*b && ismbblank (b, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) 68.2992 -+ b += mblength; 68.2993 -+ 68.2994 -+ return strnumcmp (a, b, decimal_point, thousands_sep); 68.2995 -+} 68.2996 -+#endif /* HAV_EMBRTOWC */ 68.2997 -+ 68.2998 - /* Work around a problem whereby the long double value returned by glibc's 68.2999 - strtold ("NaN", ...) contains uninitialized bits: clear all bytes of 68.3000 - A and B before calling strtold. FIXME: remove this function once 68.3001 -@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char 68.3002 - Return 0 if the name in S is not recognized. */ 68.3003 - 68.3004 - static int 68.3005 --getmonth (char const *month, char **ea) 68.3006 -+getmonth_uni (char const *month, size_t len, char **ea) 68.3007 - { 68.3008 - size_t lo = 0; 68.3009 - size_t hi = MONTHS_PER_YEAR; 68.3010 -@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, stru 68.3011 - char saved = *lim; 68.3012 - *lim = '\0'; 68.3013 - 68.3014 -- while (blanks[to_uchar (*beg)]) 68.3015 -- beg++; 68.3016 -+ skipblanks (&beg, lim); 68.3017 - 68.3018 - char *tighter_lim = beg; 68.3019 - 68.3020 - if (lim < beg) 68.3021 - tighter_lim = lim; 68.3022 - else if (key->month) 68.3023 -- getmonth (beg, &tighter_lim); 68.3024 -+ getmonth (beg, lim-beg, &tighter_lim); 68.3025 - else if (key->general_numeric) 68.3026 - ignore_value (strtold (beg, &tighter_lim)); 68.3027 - else if (key->numeric || key->human_numeric) 68.3028 -@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gke 68.3029 - bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) 68.3030 - && !(key->schar || key->echar); 68.3031 - bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ 68.3032 -- if (!gkey_only && tab == TAB_DEFAULT && !line_offset 68.3033 -+ if (!gkey_only && !tab_length && !line_offset 68.3034 - && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) 68.3035 - || (!key->skipsblanks && key->schar) 68.3036 - || (!key->skipeblanks && key->echar))) 68.3037 -@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gke 68.3038 - error (0, 0, _("option '-r' only applies to last-resort comparison")); 68.3039 - } 68.3040 - 68.3041 -+#if HAVE_MBRTOWC 68.3042 -+static int 68.3043 -+getmonth_mb (const char *s, size_t len, char **ea) 68.3044 -+{ 68.3045 -+ char *month; 68.3046 -+ register size_t i; 68.3047 -+ register int lo = 0, hi = MONTHS_PER_YEAR, result; 68.3048 -+ char *tmp; 68.3049 -+ size_t wclength, mblength; 68.3050 -+ const char *pp; 68.3051 -+ const wchar_t *wpp; 68.3052 -+ wchar_t *month_wcs; 68.3053 -+ mbstate_t state; 68.3054 -+ 68.3055 -+ while (len > 0 && ismbblank (s, len, &mblength)) 68.3056 -+ { 68.3057 -+ s += mblength; 68.3058 -+ len -= mblength; 68.3059 -+ } 68.3060 -+ 68.3061 -+ if (len == 0) 68.3062 -+ return 0; 68.3063 -+ 68.3064 -+ if (SIZE_MAX - len < 1) 68.3065 -+ xalloc_die (); 68.3066 -+ 68.3067 -+ month = (char *) xnmalloc (len + 1, MB_CUR_MAX); 68.3068 -+ 68.3069 -+ pp = tmp = (char *) xnmalloc (len + 1, MB_CUR_MAX); 68.3070 -+ memcpy (tmp, s, len); 68.3071 -+ tmp[len] = '\0'; 68.3072 -+ wpp = month_wcs = (wchar_t *) xnmalloc (len + 1, sizeof (wchar_t)); 68.3073 -+ memset (&state, '\0', sizeof (mbstate_t)); 68.3074 -+ 68.3075 -+ wclength = mbsrtowcs (month_wcs, &pp, len + 1, &state); 68.3076 -+ if (wclength == (size_t)-1 || pp != NULL) 68.3077 -+ error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s)); 68.3078 -+ 68.3079 -+ for (i = 0; i < wclength; i++) 68.3080 -+ { 68.3081 -+ month_wcs[i] = towupper(month_wcs[i]); 68.3082 -+ if (iswblank (month_wcs[i])) 68.3083 -+ { 68.3084 -+ month_wcs[i] = L'\0'; 68.3085 -+ break; 68.3086 -+ } 68.3087 -+ } 68.3088 -+ 68.3089 -+ mblength = wcsrtombs (month, &wpp, (len + 1) * MB_CUR_MAX, &state); 68.3090 -+ assert (mblength != (-1) && wpp == NULL); 68.3091 -+ 68.3092 -+ do 68.3093 -+ { 68.3094 -+ int ix = (lo + hi) / 2; 68.3095 -+ 68.3096 -+ if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0) 68.3097 -+ hi = ix; 68.3098 -+ else 68.3099 -+ lo = ix; 68.3100 -+ } 68.3101 -+ while (hi - lo > 1); 68.3102 -+ 68.3103 -+ result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name)) 68.3104 -+ ? monthtab[lo].val : 0); 68.3105 -+ 68.3106 -+ if (ea && result) 68.3107 -+ *ea = (char*) s + strlen (monthtab[lo].name); 68.3108 -+ 68.3109 -+ free (month); 68.3110 -+ free (tmp); 68.3111 -+ free (month_wcs); 68.3112 -+ 68.3113 -+ return result; 68.3114 -+} 68.3115 -+#endif 68.3116 -+ 68.3117 - /* Compare two lines A and B trying every key in sequence until there 68.3118 - are no more keys or a difference is found. */ 68.3119 - 68.3120 - static int 68.3121 --keycompare (struct line const *a, struct line const *b) 68.3122 -+keycompare_uni (const struct line *a, const struct line *b) 68.3123 - { 68.3124 - struct keyfield *key = keylist; 68.3125 - 68.3126 -@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct 68.3127 - else if (key->human_numeric) 68.3128 - diff = human_numcompare (ta, tb); 68.3129 - else if (key->month) 68.3130 -- diff = getmonth (ta, NULL) - getmonth (tb, NULL); 68.3131 -+ diff = getmonth (ta, tlena, NULL) - getmonth (tb, tlenb, NULL); 68.3132 - else if (key->random) 68.3133 - diff = compare_random (ta, tlena, tb, tlenb); 68.3134 - else if (key->version) 68.3135 -@@ -2695,6 +3135,211 @@ keycompare (struct line const *a, struct 68.3136 - return key->reverse ? -diff : diff; 68.3137 - } 68.3138 - 68.3139 -+#if HAVE_MBRTOWC 68.3140 -+static int 68.3141 -+keycompare_mb (const struct line *a, const struct line *b) 68.3142 -+{ 68.3143 -+ struct keyfield *key = keylist; 68.3144 -+ 68.3145 -+ /* For the first iteration only, the key positions have been 68.3146 -+ precomputed for us. */ 68.3147 -+ char *texta = a->keybeg; 68.3148 -+ char *textb = b->keybeg; 68.3149 -+ char *lima = a->keylim; 68.3150 -+ char *limb = b->keylim; 68.3151 -+ 68.3152 -+ size_t mblength_a, mblength_b; 68.3153 -+ wchar_t wc_a, wc_b; 68.3154 -+ mbstate_t state_a, state_b; 68.3155 -+ 68.3156 -+ int diff = 0; 68.3157 -+ 68.3158 -+ memset (&state_a, '\0', sizeof(mbstate_t)); 68.3159 -+ memset (&state_b, '\0', sizeof(mbstate_t)); 68.3160 -+ /* Ignore keys with start after end. */ 68.3161 -+ if (a->keybeg - a->keylim > 0) 68.3162 -+ return 0; 68.3163 -+ 68.3164 -+ 68.3165 -+ /* Ignore and/or translate chars before comparing. */ 68.3166 -+# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \ 68.3167 -+ do \ 68.3168 -+ { \ 68.3169 -+ wchar_t uwc; \ 68.3170 -+ char mbc[MB_LEN_MAX]; \ 68.3171 -+ mbstate_t state_wc; \ 68.3172 -+ \ 68.3173 -+ for (NEW_LEN = i = 0; i < LEN;) \ 68.3174 -+ { \ 68.3175 -+ mbstate_t state_bak; \ 68.3176 -+ \ 68.3177 -+ state_bak = STATE; \ 68.3178 -+ MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE); \ 68.3179 -+ \ 68.3180 -+ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1 \ 68.3181 -+ || MBLENGTH == 0) \ 68.3182 -+ { \ 68.3183 -+ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \ 68.3184 -+ STATE = state_bak; \ 68.3185 -+ if (!ignore) \ 68.3186 -+ COPY[NEW_LEN++] = TEXT[i]; \ 68.3187 -+ i++; \ 68.3188 -+ continue; \ 68.3189 -+ } \ 68.3190 -+ \ 68.3191 -+ if (ignore) \ 68.3192 -+ { \ 68.3193 -+ if ((ignore == nonprinting && !iswprint (WC)) \ 68.3194 -+ || (ignore == nondictionary \ 68.3195 -+ && !iswalnum (WC) && !iswblank (WC))) \ 68.3196 -+ { \ 68.3197 -+ i += MBLENGTH; \ 68.3198 -+ continue; \ 68.3199 -+ } \ 68.3200 -+ } \ 68.3201 -+ \ 68.3202 -+ if (translate) \ 68.3203 -+ { \ 68.3204 -+ \ 68.3205 -+ uwc = towupper(WC); \ 68.3206 -+ if (WC == uwc) \ 68.3207 -+ { \ 68.3208 -+ memcpy (mbc, TEXT + i, MBLENGTH); \ 68.3209 -+ i += MBLENGTH; \ 68.3210 -+ } \ 68.3211 -+ else \ 68.3212 -+ { \ 68.3213 -+ i += MBLENGTH; \ 68.3214 -+ WC = uwc; \ 68.3215 -+ memset (&state_wc, '\0', sizeof (mbstate_t)); \ 68.3216 -+ \ 68.3217 -+ MBLENGTH = wcrtomb (mbc, WC, &state_wc); \ 68.3218 -+ assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0); \ 68.3219 -+ } \ 68.3220 -+ \ 68.3221 -+ for (j = 0; j < MBLENGTH; j++) \ 68.3222 -+ COPY[NEW_LEN++] = mbc[j]; \ 68.3223 -+ } \ 68.3224 -+ else \ 68.3225 -+ for (j = 0; j < MBLENGTH; j++) \ 68.3226 -+ COPY[NEW_LEN++] = TEXT[i++]; \ 68.3227 -+ } \ 68.3228 -+ COPY[NEW_LEN] = '\0'; \ 68.3229 -+ } \ 68.3230 -+ while (0) 68.3231 -+ 68.3232 -+ /* Actually compare the fields. */ 68.3233 -+ 68.3234 -+ for (;;) 68.3235 -+ { 68.3236 -+ /* Find the lengths. */ 68.3237 -+ size_t lena = lima <= texta ? 0 : lima - texta; 68.3238 -+ size_t lenb = limb <= textb ? 0 : limb - textb; 68.3239 -+ 68.3240 -+ char enda IF_LINT (= 0); 68.3241 -+ char endb IF_LINT (= 0); 68.3242 -+ 68.3243 -+ char const *translate = key->translate; 68.3244 -+ bool const *ignore = key->ignore; 68.3245 -+ 68.3246 -+ if (ignore || translate) 68.3247 -+ { 68.3248 -+ if (SIZE_MAX - lenb - 2 < lena) 68.3249 -+ xalloc_die (); 68.3250 -+ char *copy_a = (char *) xnmalloc (lena + lenb + 2, MB_CUR_MAX); 68.3251 -+ char *copy_b = copy_a + lena * MB_CUR_MAX + 1; 68.3252 -+ size_t new_len_a, new_len_b; 68.3253 -+ size_t i, j; 68.3254 -+ 68.3255 -+ IGNORE_CHARS (new_len_a, lena, texta, copy_a, 68.3256 -+ wc_a, mblength_a, state_a); 68.3257 -+ IGNORE_CHARS (new_len_b, lenb, textb, copy_b, 68.3258 -+ wc_b, mblength_b, state_b); 68.3259 -+ texta = copy_a; textb = copy_b; 68.3260 -+ lena = new_len_a; lenb = new_len_b; 68.3261 -+ } 68.3262 -+ else 68.3263 -+ { 68.3264 -+ /* Use the keys in-place, temporarily null-terminated. */ 68.3265 -+ enda = texta[lena]; texta[lena] = '\0'; 68.3266 -+ endb = textb[lenb]; textb[lenb] = '\0'; 68.3267 -+ } 68.3268 -+ 68.3269 -+ if (key->random) 68.3270 -+ diff = compare_random (texta, lena, textb, lenb); 68.3271 -+ else if (key->numeric | key->general_numeric | key->human_numeric) 68.3272 -+ { 68.3273 -+ char savea = *lima, saveb = *limb; 68.3274 -+ 68.3275 -+ *lima = *limb = '\0'; 68.3276 -+ diff = (key->numeric ? numcompare (texta, textb) 68.3277 -+ : key->general_numeric ? general_numcompare (texta, textb) 68.3278 -+ : human_numcompare (texta, textb)); 68.3279 -+ *lima = savea, *limb = saveb; 68.3280 -+ } 68.3281 -+ else if (key->version) 68.3282 -+ diff = filevercmp (texta, textb); 68.3283 -+ else if (key->month) 68.3284 -+ diff = getmonth (texta, lena, NULL) - getmonth (textb, lenb, NULL); 68.3285 -+ else if (lena == 0) 68.3286 -+ diff = - NONZERO (lenb); 68.3287 -+ else if (lenb == 0) 68.3288 -+ diff = 1; 68.3289 -+ else if (hard_LC_COLLATE && !folding) 68.3290 -+ { 68.3291 -+ diff = xmemcoll0 (texta, lena + 1, textb, lenb + 1); 68.3292 -+ } 68.3293 -+ else 68.3294 -+ { 68.3295 -+ diff = memcmp (texta, textb, MIN (lena, lenb)); 68.3296 -+ if (diff == 0) 68.3297 -+ diff = lena < lenb ? -1 : lena != lenb; 68.3298 -+ } 68.3299 -+ 68.3300 -+ if (ignore || translate) 68.3301 -+ free (texta); 68.3302 -+ else 68.3303 -+ { 68.3304 -+ texta[lena] = enda; 68.3305 -+ textb[lenb] = endb; 68.3306 -+ } 68.3307 -+ 68.3308 -+ if (diff) 68.3309 -+ goto not_equal; 68.3310 -+ 68.3311 -+ key = key->next; 68.3312 -+ if (! key) 68.3313 -+ break; 68.3314 -+ 68.3315 -+ /* Find the beginning and limit of the next field. */ 68.3316 -+ if (key->eword != -1) 68.3317 -+ lima = limfield (a, key), limb = limfield (b, key); 68.3318 -+ else 68.3319 -+ lima = a->text + a->length - 1, limb = b->text + b->length - 1; 68.3320 -+ 68.3321 -+ if (key->sword != -1) 68.3322 -+ texta = begfield (a, key), textb = begfield (b, key); 68.3323 -+ else 68.3324 -+ { 68.3325 -+ texta = a->text, textb = b->text; 68.3326 -+ if (key->skipsblanks) 68.3327 -+ { 68.3328 -+ while (texta < lima && ismbblank (texta, lima - texta, &mblength_a)) 68.3329 -+ texta += mblength_a; 68.3330 -+ while (textb < limb && ismbblank (textb, limb - textb, &mblength_b)) 68.3331 -+ textb += mblength_b; 68.3332 -+ } 68.3333 -+ } 68.3334 -+ } 68.3335 -+ 68.3336 -+not_equal: 68.3337 -+ if (key && key->reverse) 68.3338 -+ return -diff; 68.3339 -+ else 68.3340 -+ return diff; 68.3341 -+} 68.3342 -+#endif 68.3343 -+ 68.3344 - /* Compare two lines A and B, returning negative, zero, or positive 68.3345 - depending on whether A compares less than, equal to, or greater than B. */ 68.3346 - 68.3347 -@@ -2722,7 +3367,7 @@ compare (struct line const *a, struct li 68.3348 - diff = - NONZERO (blen); 68.3349 - else if (blen == 0) 68.3350 - diff = 1; 68.3351 -- else if (hard_LC_COLLATE) 68.3352 -+ else if (hard_LC_COLLATE && !folding) 68.3353 - { 68.3354 - /* Note xmemcoll0 is a performance enhancement as 68.3355 - it will not unconditionally write '\0' after the 68.3356 -@@ -4121,6 +4766,7 @@ set_ordering (char const *s, struct keyf 68.3357 - break; 68.3358 - case 'f': 68.3359 - key->translate = fold_toupper; 68.3360 -+ folding = true; 68.3361 - break; 68.3362 - case 'g': 68.3363 - key->general_numeric = true; 68.3364 -@@ -4199,7 +4845,7 @@ main (int argc, char **argv) 68.3365 - initialize_exit_failure (SORT_FAILURE); 68.3366 - 68.3367 - hard_LC_COLLATE = hard_locale (LC_COLLATE); 68.3368 --#if HAVE_NL_LANGINFO 68.3369 -+#if HAVE_LANGINFO_CODESET 68.3370 - hard_LC_TIME = hard_locale (LC_TIME); 68.3371 - #endif 68.3372 - 68.3373 -@@ -4220,6 +4866,29 @@ main (int argc, char **argv) 68.3374 - thousands_sep = -1; 68.3375 - } 68.3376 - 68.3377 -+#if HAVE_MBRTOWC 68.3378 -+ if (MB_CUR_MAX > 1) 68.3379 -+ { 68.3380 -+ inittables = inittables_mb; 68.3381 -+ begfield = begfield_mb; 68.3382 -+ limfield = limfield_mb; 68.3383 -+ skipblanks = skipblanks_mb; 68.3384 -+ getmonth = getmonth_mb; 68.3385 -+ keycompare = keycompare_mb; 68.3386 -+ numcompare = numcompare_mb; 68.3387 -+ } 68.3388 -+ else 68.3389 -+#endif 68.3390 -+ { 68.3391 -+ inittables = inittables_uni; 68.3392 -+ begfield = begfield_uni; 68.3393 -+ limfield = limfield_uni; 68.3394 -+ skipblanks = skipblanks_uni; 68.3395 -+ getmonth = getmonth_uni; 68.3396 -+ keycompare = keycompare_uni; 68.3397 -+ numcompare = numcompare_uni; 68.3398 -+ } 68.3399 -+ 68.3400 - have_read_stdin = false; 68.3401 - inittables (); 68.3402 - 68.3403 -@@ -4494,13 +5163,34 @@ main (int argc, char **argv) 68.3404 - 68.3405 - case 't': 68.3406 - { 68.3407 -- char newtab = optarg[0]; 68.3408 -- if (! newtab) 68.3409 -+ char newtab[MB_LEN_MAX + 1]; 68.3410 -+ size_t newtab_length = 1; 68.3411 -+ strncpy (newtab, optarg, MB_LEN_MAX); 68.3412 -+ if (! newtab[0]) 68.3413 - error (SORT_FAILURE, 0, _("empty tab")); 68.3414 -- if (optarg[1]) 68.3415 -+#if HAVE_MBRTOWC 68.3416 -+ if (MB_CUR_MAX > 1) 68.3417 -+ { 68.3418 -+ wchar_t wc; 68.3419 -+ mbstate_t state; 68.3420 -+ 68.3421 -+ memset (&state, '\0', sizeof (mbstate_t)); 68.3422 -+ newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, 68.3423 -+ MB_LEN_MAX), 68.3424 -+ &state); 68.3425 -+ switch (newtab_length) 68.3426 -+ { 68.3427 -+ case (size_t) -1: 68.3428 -+ case (size_t) -2: 68.3429 -+ case 0: 68.3430 -+ newtab_length = 1; 68.3431 -+ } 68.3432 -+ } 68.3433 -+#endif 68.3434 -+ if (newtab_length == 1 && optarg[1]) 68.3435 - { 68.3436 - if (STREQ (optarg, "\\0")) 68.3437 -- newtab = '\0'; 68.3438 -+ newtab[0] = '\0'; 68.3439 - else 68.3440 - { 68.3441 - /* Provoke with 'sort -txx'. Complain about 68.3442 -@@ -4511,9 +5201,12 @@ main (int argc, char **argv) 68.3443 - quote (optarg)); 68.3444 - } 68.3445 - } 68.3446 -- if (tab != TAB_DEFAULT && tab != newtab) 68.3447 -+ if (tab_length 68.3448 -+ && (tab_length != newtab_length 68.3449 -+ || memcmp (tab, newtab, tab_length) != 0)) 68.3450 - error (SORT_FAILURE, 0, _("incompatible tabs")); 68.3451 -- tab = newtab; 68.3452 -+ memcpy (tab, newtab, newtab_length); 68.3453 -+ tab_length = newtab_length; 68.3454 - } 68.3455 - break; 68.3456 - 68.3457 -@@ -4751,12 +5444,10 @@ main (int argc, char **argv) 68.3458 - sort (files, nfiles, outfile, nthreads); 68.3459 - } 68.3460 - 68.3461 --#ifdef lint 68.3462 - if (files_from) 68.3463 - readtokens0_free (&tok); 68.3464 - else 68.3465 - free (files); 68.3466 --#endif 68.3467 - 68.3468 - if (have_read_stdin && fclose (stdin) == EOF) 68.3469 - die (_("close failed"), "-"); 68.3470 -diff -Naurp coreutils-8.25-orig/src/unexpand.c coreutils-8.25/src/unexpand.c 68.3471 ---- coreutils-8.25-orig/src/unexpand.c 2016-01-01 07:48:50.000000000 -0600 68.3472 -+++ coreutils-8.25/src/unexpand.c 2016-02-08 19:07:10.311944651 -0600 68.3473 -@@ -38,12 +38,29 @@ 68.3474 - #include <stdio.h> 68.3475 - #include <getopt.h> 68.3476 - #include <sys/types.h> 68.3477 -+ 68.3478 -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ 68.3479 -+#if HAVE_WCHAR_H 68.3480 -+# include <wchar.h> 68.3481 -+#endif 68.3482 -+ 68.3483 - #include "system.h" 68.3484 - #include "error.h" 68.3485 - #include "fadvise.h" 68.3486 - #include "quote.h" 68.3487 - #include "xstrndup.h" 68.3488 - 68.3489 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 68.3490 -+ installation; work around this configuration error. */ 68.3491 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 68.3492 -+# define MB_LEN_MAX 16 68.3493 -+#endif 68.3494 -+ 68.3495 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 68.3496 -+#if HAVE_MBRTOWC && defined mbstate_t 68.3497 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 68.3498 -+#endif 68.3499 -+ 68.3500 - /* The official name of this program (e.g., no 'g' prefix). */ 68.3501 - #define PROGRAM_NAME "unexpand" 68.3502 - 68.3503 -@@ -103,6 +120,210 @@ static struct option const longopts[] = 68.3504 - {NULL, 0, NULL, 0} 68.3505 - }; 68.3506 - 68.3507 -+static FILE *next_file (FILE *fp); 68.3508 -+ 68.3509 -+#if HAVE_MBRTOWC 68.3510 -+static void 68.3511 -+unexpand_multibyte (void) 68.3512 -+{ 68.3513 -+ FILE *fp; /* Input stream. */ 68.3514 -+ mbstate_t i_state; /* Current shift state of the input stream. */ 68.3515 -+ mbstate_t i_state_bak; /* Back up the I_STATE. */ 68.3516 -+ mbstate_t o_state; /* Current shift state of the output stream. */ 68.3517 -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 68.3518 -+ char *bufpos = buf; /* Next read position of BUF. */ 68.3519 -+ size_t buflen = 0; /* The length of the byte sequence in buf. */ 68.3520 -+ wint_t wc; /* A gotten wide character. */ 68.3521 -+ size_t mblength; /* The byte size of a multibyte character 68.3522 -+ which shows as same character as WC. */ 68.3523 -+ bool prev_tab = false; 68.3524 -+ 68.3525 -+ /* Index in `tab_list' of next tabstop: */ 68.3526 -+ int tab_index = 0; /* For calculating width of pending tabs. */ 68.3527 -+ int print_tab_index = 0; /* For printing as many tabs as possible. */ 68.3528 -+ unsigned int column = 0; /* Column on screen of next char. */ 68.3529 -+ int next_tab_column; /* Column the next tab stop is on. */ 68.3530 -+ int convert = 1; /* If nonzero, perform translations. */ 68.3531 -+ unsigned int pending = 0; /* Pending columns of blanks. */ 68.3532 -+ 68.3533 -+ fp = next_file ((FILE *) NULL); 68.3534 -+ if (fp == NULL) 68.3535 -+ return; 68.3536 -+ 68.3537 -+ memset (&o_state, '\0', sizeof(mbstate_t)); 68.3538 -+ memset (&i_state, '\0', sizeof(mbstate_t)); 68.3539 -+ 68.3540 -+ for (;;) 68.3541 -+ { 68.3542 -+ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) 68.3543 -+ { 68.3544 -+ memmove (buf, bufpos, buflen); 68.3545 -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); 68.3546 -+ bufpos = buf; 68.3547 -+ } 68.3548 -+ 68.3549 -+ /* Get a wide character. */ 68.3550 -+ if (buflen < 1) 68.3551 -+ { 68.3552 -+ mblength = 1; 68.3553 -+ wc = WEOF; 68.3554 -+ } 68.3555 -+ else 68.3556 -+ { 68.3557 -+ i_state_bak = i_state; 68.3558 -+ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &i_state); 68.3559 -+ } 68.3560 -+ 68.3561 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 68.3562 -+ { 68.3563 -+ i_state = i_state_bak; 68.3564 -+ wc = L'\0'; 68.3565 -+ } 68.3566 -+ 68.3567 -+ if (wc == L' ' && convert && column < INT_MAX) 68.3568 -+ { 68.3569 -+ ++pending; 68.3570 -+ ++column; 68.3571 -+ } 68.3572 -+ else if (wc == L'\t' && convert) 68.3573 -+ { 68.3574 -+ if (tab_size == 0) 68.3575 -+ { 68.3576 -+ /* Do not let tab_index == first_free_tab; 68.3577 -+ stop when it is 1 less. */ 68.3578 -+ while (tab_index < first_free_tab - 1 68.3579 -+ && column >= tab_list[tab_index]) 68.3580 -+ tab_index++; 68.3581 -+ next_tab_column = tab_list[tab_index]; 68.3582 -+ if (tab_index < first_free_tab - 1) 68.3583 -+ tab_index++; 68.3584 -+ if (column >= next_tab_column) 68.3585 -+ { 68.3586 -+ convert = 0; /* Ran out of tab stops. */ 68.3587 -+ goto flush_pend_mb; 68.3588 -+ } 68.3589 -+ } 68.3590 -+ else 68.3591 -+ { 68.3592 -+ next_tab_column = column + tab_size - column % tab_size; 68.3593 -+ } 68.3594 -+ pending += next_tab_column - column; 68.3595 -+ column = next_tab_column; 68.3596 -+ } 68.3597 -+ else 68.3598 -+ { 68.3599 -+flush_pend_mb: 68.3600 -+ /* Flush pending spaces. Print as many tabs as possible, 68.3601 -+ then print the rest as spaces. */ 68.3602 -+ if (pending == 1 && column != 1 && !prev_tab) 68.3603 -+ { 68.3604 -+ putchar (' '); 68.3605 -+ pending = 0; 68.3606 -+ } 68.3607 -+ column -= pending; 68.3608 -+ while (pending > 0) 68.3609 -+ { 68.3610 -+ if (tab_size == 0) 68.3611 -+ { 68.3612 -+ /* Do not let print_tab_index == first_free_tab; 68.3613 -+ stop when it is 1 less. */ 68.3614 -+ while (print_tab_index < first_free_tab - 1 68.3615 -+ && column >= tab_list[print_tab_index]) 68.3616 -+ print_tab_index++; 68.3617 -+ next_tab_column = tab_list[print_tab_index]; 68.3618 -+ if (print_tab_index < first_free_tab - 1) 68.3619 -+ print_tab_index++; 68.3620 -+ } 68.3621 -+ else 68.3622 -+ { 68.3623 -+ next_tab_column = 68.3624 -+ column + tab_size - column % tab_size; 68.3625 -+ } 68.3626 -+ if (next_tab_column - column <= pending) 68.3627 -+ { 68.3628 -+ putchar ('\t'); 68.3629 -+ pending -= next_tab_column - column; 68.3630 -+ column = next_tab_column; 68.3631 -+ } 68.3632 -+ else 68.3633 -+ { 68.3634 -+ --print_tab_index; 68.3635 -+ column += pending; 68.3636 -+ while (pending != 0) 68.3637 -+ { 68.3638 -+ putchar (' '); 68.3639 -+ pending--; 68.3640 -+ } 68.3641 -+ } 68.3642 -+ } 68.3643 -+ 68.3644 -+ if (wc == WEOF) 68.3645 -+ { 68.3646 -+ fp = next_file (fp); 68.3647 -+ if (fp == NULL) 68.3648 -+ break; /* No more files. */ 68.3649 -+ else 68.3650 -+ { 68.3651 -+ memset (&i_state, '\0', sizeof(mbstate_t)); 68.3652 -+ continue; 68.3653 -+ } 68.3654 -+ } 68.3655 -+ 68.3656 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 68.3657 -+ { 68.3658 -+ if (convert) 68.3659 -+ { 68.3660 -+ ++column; 68.3661 -+ if (convert_entire_line == 0) 68.3662 -+ convert = 0; 68.3663 -+ } 68.3664 -+ mblength = 1; 68.3665 -+ putchar (buf[0]); 68.3666 -+ } 68.3667 -+ else if (mblength == 0) 68.3668 -+ { 68.3669 -+ if (convert && convert_entire_line == 0) 68.3670 -+ convert = 0; 68.3671 -+ mblength = 1; 68.3672 -+ putchar ('\0'); 68.3673 -+ } 68.3674 -+ else 68.3675 -+ { 68.3676 -+ if (convert) 68.3677 -+ { 68.3678 -+ if (wc == L'\b') 68.3679 -+ { 68.3680 -+ if (column > 0) 68.3681 -+ --column; 68.3682 -+ } 68.3683 -+ else 68.3684 -+ { 68.3685 -+ int width; /* The width of WC. */ 68.3686 -+ 68.3687 -+ width = wcwidth (wc); 68.3688 -+ column += (width > 0) ? width : 0; 68.3689 -+ if (convert_entire_line == 0) 68.3690 -+ convert = 0; 68.3691 -+ } 68.3692 -+ } 68.3693 -+ 68.3694 -+ if (wc == L'\n') 68.3695 -+ { 68.3696 -+ tab_index = print_tab_index = 0; 68.3697 -+ column = pending = 0; 68.3698 -+ convert = 1; 68.3699 -+ } 68.3700 -+ fwrite (bufpos, sizeof(char), mblength, stdout); 68.3701 -+ } 68.3702 -+ } 68.3703 -+ prev_tab = wc == L'\t'; 68.3704 -+ buflen -= mblength; 68.3705 -+ bufpos += mblength; 68.3706 -+ } 68.3707 -+} 68.3708 -+#endif 68.3709 -+ 68.3710 -+ 68.3711 - void 68.3712 - usage (int status) 68.3713 - { 68.3714 -@@ -523,7 +744,12 @@ main (int argc, char **argv) 68.3715 - 68.3716 - file_list = (optind < argc ? &argv[optind] : stdin_argv); 68.3717 - 68.3718 -- unexpand (); 68.3719 -+#if HAVE_MBRTOWC 68.3720 -+ if (MB_CUR_MAX > 1) 68.3721 -+ unexpand_multibyte (); 68.3722 -+ else 68.3723 -+#endif 68.3724 -+ unexpand (); 68.3725 - 68.3726 - if (have_read_stdin && fclose (stdin) != 0) 68.3727 - error (EXIT_FAILURE, errno, "-"); 68.3728 -diff -Naurp coreutils-8.25-orig/src/uniq.c coreutils-8.25/src/uniq.c 68.3729 ---- coreutils-8.25-orig/src/uniq.c 2016-01-13 05:08:59.000000000 -0600 68.3730 -+++ coreutils-8.25/src/uniq.c 2016-02-08 19:07:10.312944654 -0600 68.3731 -@@ -21,6 +21,17 @@ 68.3732 - #include <getopt.h> 68.3733 - #include <sys/types.h> 68.3734 - 68.3735 -+/* Get mbstate_t, mbrtowc(). */ 68.3736 -+#if HAVE_WCHAR_H 68.3737 -+# include <wchar.h> 68.3738 -+#endif 68.3739 -+ 68.3740 -+/* Get isw* functions. */ 68.3741 -+#if HAVE_WCTYPE_H 68.3742 -+# include <wctype.h> 68.3743 -+#endif 68.3744 -+#include <assert.h> 68.3745 -+ 68.3746 - #include "system.h" 68.3747 - #include "argmatch.h" 68.3748 - #include "linebuffer.h" 68.3749 -@@ -33,6 +44,18 @@ 68.3750 - #include "xstrtol.h" 68.3751 - #include "memcasecmp.h" 68.3752 - #include "quote.h" 68.3753 -+#include "xmemcoll.h" 68.3754 -+ 68.3755 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 68.3756 -+ installation; work around this configuration error. */ 68.3757 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 68.3758 -+# define MB_LEN_MAX 16 68.3759 -+#endif 68.3760 -+ 68.3761 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 68.3762 -+#if HAVE_MBRTOWC && defined mbstate_t 68.3763 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 68.3764 -+#endif 68.3765 - 68.3766 - /* The official name of this program (e.g., no 'g' prefix). */ 68.3767 - #define PROGRAM_NAME "uniq" 68.3768 -@@ -143,6 +166,10 @@ enum 68.3769 - GROUP_OPTION = CHAR_MAX + 1 68.3770 - }; 68.3771 - 68.3772 -+/* Function pointers. */ 68.3773 -+static char * 68.3774 -+(*find_field) (struct linebuffer *line); 68.3775 -+ 68.3776 - static struct option const longopts[] = 68.3777 - { 68.3778 - {"count", no_argument, NULL, 'c'}, 68.3779 -@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *m 68.3780 - return a pointer to the beginning of the line's field to be compared. */ 68.3781 - 68.3782 - static char * _GL_ATTRIBUTE_PURE 68.3783 --find_field (struct linebuffer const *line) 68.3784 -+find_field_uni (struct linebuffer *line) 68.3785 - { 68.3786 - size_t count; 68.3787 - char const *lp = line->buffer; 68.3788 -@@ -272,6 +299,83 @@ find_field (struct linebuffer const *lin 68.3789 - return line->buffer + i; 68.3790 - } 68.3791 - 68.3792 -+#if HAVE_MBRTOWC 68.3793 -+ 68.3794 -+# define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL) \ 68.3795 -+ do \ 68.3796 -+ { \ 68.3797 -+ mbstate_t state_bak; \ 68.3798 -+ \ 68.3799 -+ CONVFAIL = 0; \ 68.3800 -+ state_bak = *STATEP; \ 68.3801 -+ \ 68.3802 -+ MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP); \ 68.3803 -+ \ 68.3804 -+ switch (MBLENGTH) \ 68.3805 -+ { \ 68.3806 -+ case (size_t)-2: \ 68.3807 -+ case (size_t)-1: \ 68.3808 -+ *STATEP = state_bak; \ 68.3809 -+ CONVFAIL++; \ 68.3810 -+ /* Fall through */ \ 68.3811 -+ case 0: \ 68.3812 -+ MBLENGTH = 1; \ 68.3813 -+ } \ 68.3814 -+ } \ 68.3815 -+ while (0) 68.3816 -+ 68.3817 -+static char * 68.3818 -+find_field_multi (struct linebuffer *line) 68.3819 -+{ 68.3820 -+ size_t count; 68.3821 -+ char *lp = line->buffer; 68.3822 -+ size_t size = line->length - 1; 68.3823 -+ size_t pos; 68.3824 -+ size_t mblength; 68.3825 -+ wchar_t wc; 68.3826 -+ mbstate_t *statep; 68.3827 -+ int convfail = 0; 68.3828 -+ 68.3829 -+ pos = 0; 68.3830 -+ statep = &(line->state); 68.3831 -+ 68.3832 -+ /* skip fields. */ 68.3833 -+ for (count = 0; count < skip_fields && pos < size; count++) 68.3834 -+ { 68.3835 -+ while (pos < size) 68.3836 -+ { 68.3837 -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 68.3838 -+ 68.3839 -+ if (convfail || !(iswblank (wc) || wc == '\n')) 68.3840 -+ { 68.3841 -+ pos += mblength; 68.3842 -+ break; 68.3843 -+ } 68.3844 -+ pos += mblength; 68.3845 -+ } 68.3846 -+ 68.3847 -+ while (pos < size) 68.3848 -+ { 68.3849 -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 68.3850 -+ 68.3851 -+ if (!convfail && (iswblank (wc) || wc == '\n')) 68.3852 -+ break; 68.3853 -+ 68.3854 -+ pos += mblength; 68.3855 -+ } 68.3856 -+ } 68.3857 -+ 68.3858 -+ /* skip fields. */ 68.3859 -+ for (count = 0; count < skip_chars && pos < size; count++) 68.3860 -+ { 68.3861 -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 68.3862 -+ pos += mblength; 68.3863 -+ } 68.3864 -+ 68.3865 -+ return lp + pos; 68.3866 -+} 68.3867 -+#endif 68.3868 -+ 68.3869 - /* Return false if two strings OLD and NEW match, true if not. 68.3870 - OLD and NEW point not to the beginnings of the lines 68.3871 - but rather to the beginnings of the fields to compare. 68.3872 -@@ -280,6 +384,8 @@ find_field (struct linebuffer const *lin 68.3873 - static bool 68.3874 - different (char *old, char *new, size_t oldlen, size_t newlen) 68.3875 - { 68.3876 -+ char *copy_old, *copy_new; 68.3877 -+ 68.3878 - if (check_chars < oldlen) 68.3879 - oldlen = check_chars; 68.3880 - if (check_chars < newlen) 68.3881 -@@ -287,15 +393,104 @@ different (char *old, char *new, size_t 68.3882 - 68.3883 - if (ignore_case) 68.3884 - { 68.3885 -- /* FIXME: This should invoke strcoll somehow. */ 68.3886 -- return oldlen != newlen || memcasecmp (old, new, oldlen); 68.3887 -+ size_t i; 68.3888 -+ 68.3889 -+ copy_old = xmalloc (oldlen + 1); 68.3890 -+ copy_new = xmalloc (oldlen + 1); 68.3891 -+ 68.3892 -+ for (i = 0; i < oldlen; i++) 68.3893 -+ { 68.3894 -+ copy_old[i] = toupper (old[i]); 68.3895 -+ copy_new[i] = toupper (new[i]); 68.3896 -+ } 68.3897 -+ bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen); 68.3898 -+ free (copy_old); 68.3899 -+ free (copy_new); 68.3900 -+ return rc; 68.3901 - } 68.3902 -- else if (hard_LC_COLLATE) 68.3903 -- return xmemcoll (old, oldlen, new, newlen) != 0; 68.3904 - else 68.3905 -- return oldlen != newlen || memcmp (old, new, oldlen); 68.3906 -+ { 68.3907 -+ copy_old = (char *)old; 68.3908 -+ copy_new = (char *)new; 68.3909 -+ } 68.3910 -+ 68.3911 -+ return xmemcoll (copy_old, oldlen, copy_new, newlen); 68.3912 -+ 68.3913 - } 68.3914 - 68.3915 -+#if HAVE_MBRTOWC 68.3916 -+static int 68.3917 -+different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) 68.3918 -+{ 68.3919 -+ size_t i, j, chars; 68.3920 -+ const char *str[2]; 68.3921 -+ char *copy[2]; 68.3922 -+ size_t len[2]; 68.3923 -+ mbstate_t state[2]; 68.3924 -+ size_t mblength; 68.3925 -+ wchar_t wc, uwc; 68.3926 -+ mbstate_t state_bak; 68.3927 -+ 68.3928 -+ str[0] = old; 68.3929 -+ str[1] = new; 68.3930 -+ len[0] = oldlen; 68.3931 -+ len[1] = newlen; 68.3932 -+ state[0] = oldstate; 68.3933 -+ state[1] = newstate; 68.3934 -+ 68.3935 -+ for (i = 0; i < 2; i++) 68.3936 -+ { 68.3937 -+ copy[i] = xmalloc (len[i] + 1); 68.3938 -+ memset (copy[i], '\0', len[i] + 1); 68.3939 -+ 68.3940 -+ for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) 68.3941 -+ { 68.3942 -+ state_bak = state[i]; 68.3943 -+ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); 68.3944 -+ 68.3945 -+ switch (mblength) 68.3946 -+ { 68.3947 -+ case (size_t)-1: 68.3948 -+ case (size_t)-2: 68.3949 -+ state[i] = state_bak; 68.3950 -+ /* Fall through */ 68.3951 -+ case 0: 68.3952 -+ mblength = 1; 68.3953 -+ break; 68.3954 -+ 68.3955 -+ default: 68.3956 -+ if (ignore_case) 68.3957 -+ { 68.3958 -+ uwc = towupper (wc); 68.3959 -+ 68.3960 -+ if (uwc != wc) 68.3961 -+ { 68.3962 -+ mbstate_t state_wc; 68.3963 -+ size_t mblen; 68.3964 -+ 68.3965 -+ memset (&state_wc, '\0', sizeof(mbstate_t)); 68.3966 -+ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); 68.3967 -+ assert (mblen != (size_t)-1); 68.3968 -+ } 68.3969 -+ else 68.3970 -+ memcpy (copy[i] + j, str[i] + j, mblength); 68.3971 -+ } 68.3972 -+ else 68.3973 -+ memcpy (copy[i] + j, str[i] + j, mblength); 68.3974 -+ } 68.3975 -+ j += mblength; 68.3976 -+ } 68.3977 -+ copy[i][j] = '\0'; 68.3978 -+ len[i] = j; 68.3979 -+ } 68.3980 -+ int rc = xmemcoll (copy[0], len[0], copy[1], len[1]); 68.3981 -+ free (copy[0]); 68.3982 -+ free (copy[1]); 68.3983 -+ return rc; 68.3984 -+ 68.3985 -+} 68.3986 -+#endif 68.3987 -+ 68.3988 - /* Output the line in linebuffer LINE to standard output 68.3989 - provided that the switches say it should be output. 68.3990 - MATCH is true if the line matches the previous line. 68.3991 -@@ -359,19 +554,38 @@ check_file (const char *infile, const ch 68.3992 - char *prevfield IF_LINT ( = NULL); 68.3993 - size_t prevlen IF_LINT ( = 0); 68.3994 - bool first_group_printed = false; 68.3995 -+#if HAVE_MBRTOWC 68.3996 -+ mbstate_t prevstate; 68.3997 -+ 68.3998 -+ memset (&prevstate, '\0', sizeof (mbstate_t)); 68.3999 -+#endif 68.4000 - 68.4001 - while (!feof (stdin)) 68.4002 - { 68.4003 - char *thisfield; 68.4004 - size_t thislen; 68.4005 - bool new_group; 68.4006 -+#if HAVE_MBRTOWC 68.4007 -+ mbstate_t thisstate; 68.4008 -+#endif 68.4009 - 68.4010 - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) 68.4011 - break; 68.4012 - 68.4013 - thisfield = find_field (thisline); 68.4014 - thislen = thisline->length - 1 - (thisfield - thisline->buffer); 68.4015 -+#if HAVE_MBRTOWC 68.4016 -+ if (MB_CUR_MAX > 1) 68.4017 -+ { 68.4018 -+ thisstate = thisline->state; 68.4019 - 68.4020 -+ new_group = (prevline->length == 0 68.4021 -+ || different_multi (thisfield, prevfield, 68.4022 -+ thislen, prevlen, 68.4023 -+ thisstate, prevstate)); 68.4024 -+ } 68.4025 -+ else 68.4026 -+#endif 68.4027 - new_group = (prevline->length == 0 68.4028 - || different (thisfield, prevfield, thislen, prevlen)); 68.4029 - 68.4030 -@@ -389,6 +603,10 @@ check_file (const char *infile, const ch 68.4031 - SWAP_LINES (prevline, thisline); 68.4032 - prevfield = thisfield; 68.4033 - prevlen = thislen; 68.4034 -+#if HAVE_MBRTOWC 68.4035 -+ if (MB_CUR_MAX > 1) 68.4036 -+ prevstate = thisstate; 68.4037 -+#endif 68.4038 - first_group_printed = true; 68.4039 - } 68.4040 - } 68.4041 -@@ -401,17 +619,26 @@ check_file (const char *infile, const ch 68.4042 - size_t prevlen; 68.4043 - uintmax_t match_count = 0; 68.4044 - bool first_delimiter = true; 68.4045 -+#if HAVE_MBRTOWC 68.4046 -+ mbstate_t prevstate; 68.4047 -+#endif 68.4048 - 68.4049 - if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) 68.4050 - goto closefiles; 68.4051 - prevfield = find_field (prevline); 68.4052 - prevlen = prevline->length - 1 - (prevfield - prevline->buffer); 68.4053 -+#if HAVE_MBRTOWC 68.4054 -+ prevstate = prevline->state; 68.4055 -+#endif 68.4056 - 68.4057 - while (!feof (stdin)) 68.4058 - { 68.4059 - bool match; 68.4060 - char *thisfield; 68.4061 - size_t thislen; 68.4062 -+#if HAVE_MBRTOWC 68.4063 -+ mbstate_t thisstate = thisline->state; 68.4064 -+#endif 68.4065 - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) 68.4066 - { 68.4067 - if (ferror (stdin)) 68.4068 -@@ -420,6 +647,14 @@ check_file (const char *infile, const ch 68.4069 - } 68.4070 - thisfield = find_field (thisline); 68.4071 - thislen = thisline->length - 1 - (thisfield - thisline->buffer); 68.4072 -+#if HAVE_MBRTOWC 68.4073 -+ if (MB_CUR_MAX > 1) 68.4074 -+ { 68.4075 -+ match = !different_multi (thisfield, prevfield, 68.4076 -+ thislen, prevlen, thisstate, prevstate); 68.4077 -+ } 68.4078 -+ else 68.4079 -+#endif 68.4080 - match = !different (thisfield, prevfield, thislen, prevlen); 68.4081 - match_count += match; 68.4082 - 68.4083 -@@ -452,6 +687,9 @@ check_file (const char *infile, const ch 68.4084 - SWAP_LINES (prevline, thisline); 68.4085 - prevfield = thisfield; 68.4086 - prevlen = thislen; 68.4087 -+#if HAVE_MBRTOWC 68.4088 -+ prevstate = thisstate; 68.4089 -+#endif 68.4090 - if (!match) 68.4091 - match_count = 0; 68.4092 - } 68.4093 -@@ -498,6 +736,19 @@ main (int argc, char **argv) 68.4094 - 68.4095 - atexit (close_stdout); 68.4096 - 68.4097 -+#if HAVE_MBRTOWC 68.4098 -+ if (MB_CUR_MAX > 1) 68.4099 -+ { 68.4100 -+ find_field = find_field_multi; 68.4101 -+ } 68.4102 -+ else 68.4103 -+#endif 68.4104 -+ { 68.4105 -+ find_field = find_field_uni; 68.4106 -+ } 68.4107 -+ 68.4108 -+ 68.4109 -+ 68.4110 - skip_chars = 0; 68.4111 - skip_fields = 0; 68.4112 - check_chars = SIZE_MAX; 68.4113 -diff -Naurp coreutils-8.25-orig/tests/i18n/sort-month.sh coreutils-8.25/tests/i18n/sort-month.sh 68.4114 ---- coreutils-8.25-orig/tests/i18n/sort-month.sh 1969-12-31 18:00:00.000000000 -0600 68.4115 -+++ coreutils-8.25/tests/i18n/sort-month.sh 2016-02-08 19:07:10.312944654 -0600 68.4116 -@@ -0,0 +1,34 @@ 68.4117 -+#!/bin/sh 68.4118 -+# Verify sort -M multi-byte support. 68.4119 -+ 68.4120 -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 68.4121 -+print_ver_ sort 68.4122 -+require_valgrind_ 68.4123 -+ 68.4124 -+# Skip this test if some deallocations are 68.4125 -+# avoided at process end. 68.4126 -+grep '^#define lint 1' $CONFIG_HEADER > /dev/null || 68.4127 -+ skip_ 'Allocation checks only work reliably in "lint" mode' 68.4128 -+ 68.4129 -+export LC_ALL=en_US.UTF-8 68.4130 -+locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 68.4131 -+ || skip_ "No UTF-8 locale available" 68.4132 -+ 68.4133 -+# Note the use of ɑ here which expands to 68.4134 -+# a wider representation upon case conversion 68.4135 -+# which triggered an assertion in sort -M 68.4136 -+cat <<EOF > exp 68.4137 -+. 68.4138 -+ɑ 68.4139 -+EOF 68.4140 -+ 68.4141 -+ 68.4142 -+# check large mem leak with --month-sort 68.4143 -+# https://bugzilla.redhat.com/show_bug.cgi?id=1259942 68.4144 -+valgrind --leak-check=full \ 68.4145 -+ --error-exitcode=1 --errors-for-leak-kinds=definite \ 68.4146 -+ sort -M < exp > out || fail=1 68.4147 -+compare exp out || { fail=1; cat out; } 68.4148 -+ 68.4149 -+ 68.4150 -+Exit $fail 68.4151 -diff -Naurp coreutils-8.25-orig/tests/i18n/sort.sh coreutils-8.25/tests/i18n/sort.sh 68.4152 ---- coreutils-8.25-orig/tests/i18n/sort.sh 1969-12-31 18:00:00.000000000 -0600 68.4153 -+++ coreutils-8.25/tests/i18n/sort.sh 2016-02-08 19:07:10.312944654 -0600 68.4154 -@@ -0,0 +1,29 @@ 68.4155 -+#!/bin/sh 68.4156 -+# Verify sort's multi-byte support. 68.4157 -+ 68.4158 -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 68.4159 -+print_ver_ sort 68.4160 -+ 68.4161 -+export LC_ALL=en_US.UTF-8 68.4162 -+locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 68.4163 -+ || skip_ "No UTF-8 locale available" 68.4164 -+ 68.4165 -+# Enable heap consistency checkng on older systems 68.4166 -+export MALLOC_CHECK_=2 68.4167 -+ 68.4168 -+ 68.4169 -+# check buffer overflow issue due to 68.4170 -+# expanding multi-byte representation due to case conversion 68.4171 -+# https://bugzilla.suse.com/show_bug.cgi?id=928749 68.4172 -+cat <<EOF > exp 68.4173 -+. 68.4174 -+ɑ 68.4175 -+EOF 68.4176 -+cat <<EOF | sort -f > out || fail=1 68.4177 -+. 68.4178 -+ɑ 68.4179 -+EOF 68.4180 -+compare exp out || { fail=1; cat out; } 68.4181 -+ 68.4182 -+ 68.4183 -+Exit $fail 68.4184 -diff -Naurp coreutils-8.25-orig/tests/local.mk coreutils-8.25/tests/local.mk 68.4185 ---- coreutils-8.25-orig/tests/local.mk 2016-01-16 12:18:13.000000000 -0600 68.4186 -+++ coreutils-8.25/tests/local.mk 2016-02-08 19:07:10.313944658 -0600 68.4187 -@@ -344,6 +344,9 @@ all_tests = \ 68.4188 - tests/misc/sort-discrim.sh \ 68.4189 - tests/misc/sort-files0-from.pl \ 68.4190 - tests/misc/sort-float.sh \ 68.4191 -+ tests/misc/sort-mb-tests.sh \ 68.4192 -+ tests/i18n/sort.sh \ 68.4193 -+ tests/i18n/sort-month.sh \ 68.4194 - tests/misc/sort-merge.pl \ 68.4195 - tests/misc/sort-merge-fdlimit.sh \ 68.4196 - tests/misc/sort-month.sh \ 68.4197 -diff -Naurp coreutils-8.25-orig/tests/misc/cut.pl coreutils-8.25/tests/misc/cut.pl 68.4198 ---- coreutils-8.25-orig/tests/misc/cut.pl 2016-01-16 12:18:13.000000000 -0600 68.4199 -+++ coreutils-8.25/tests/misc/cut.pl 2016-02-08 19:07:10.314944661 -0600 68.4200 -@@ -23,9 +23,11 @@ use strict; 68.4201 - # Turn off localization of executable's output. 68.4202 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 68.4203 - 68.4204 --my $mb_locale = $ENV{LOCALE_FR_UTF8}; 68.4205 -+my $mb_locale; 68.4206 -+# uncommented enable multibyte paths 68.4207 -+$mb_locale = $ENV{LOCALE_FR_UTF8}; 68.4208 - ! defined $mb_locale || $mb_locale eq 'none' 68.4209 -- and $mb_locale = 'C'; 68.4210 -+ and $mb_locale = 'C'; 68.4211 - 68.4212 - my $prog = 'cut'; 68.4213 - my $try = "Try '$prog --help' for more information.\n"; 68.4214 -@@ -240,6 +242,7 @@ if ($mb_locale ne 'C') 68.4215 - my @new_t = @$t; 68.4216 - my $test_name = shift @new_t; 68.4217 - 68.4218 -+ next if ($test_name =~ "newline-[12][0-9]"); 68.4219 - push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 68.4220 - } 68.4221 - push @Tests, @new; 68.4222 -diff -Naurp coreutils-8.25-orig/tests/misc/expand.pl coreutils-8.25/tests/misc/expand.pl 68.4223 ---- coreutils-8.25-orig/tests/misc/expand.pl 2016-01-16 12:18:13.000000000 -0600 68.4224 -+++ coreutils-8.25/tests/misc/expand.pl 2016-02-08 19:07:10.314944661 -0600 68.4225 -@@ -23,6 +23,15 @@ use strict; 68.4226 - # Turn off localization of executable's output. 68.4227 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 68.4228 - 68.4229 -+#comment out next line to disable multibyte tests 68.4230 -+my $mb_locale = $ENV{LOCALE_FR_UTF8}; 68.4231 -+! defined $mb_locale || $mb_locale eq 'none' 68.4232 -+ and $mb_locale = 'C'; 68.4233 -+ 68.4234 -+my $prog = 'expand'; 68.4235 -+my $try = "Try \`$prog --help' for more information.\n"; 68.4236 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 68.4237 -+ 68.4238 - my @Tests = 68.4239 - ( 68.4240 - ['t1', '--tabs=3', {IN=>"a\tb"}, {OUT=>"a b"}], 68.4241 -@@ -31,6 +40,37 @@ my @Tests = 68.4242 - ['i2', '--tabs=3 -i', {IN=>" \ta\tb"}, {OUT=>" a\tb"}], 68.4243 - ); 68.4244 - 68.4245 -+if ($mb_locale ne 'C') 68.4246 -+ { 68.4247 -+ # Duplicate each test vector, appending "-mb" to the test name and 68.4248 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 68.4249 -+ # provide coverage for the distro-added multi-byte code paths. 68.4250 -+ my @new; 68.4251 -+ foreach my $t (@Tests) 68.4252 -+ { 68.4253 -+ my @new_t = @$t; 68.4254 -+ my $test_name = shift @new_t; 68.4255 -+ 68.4256 -+ # Depending on whether expand is multi-byte-patched, 68.4257 -+ # it emits different diagnostics: 68.4258 -+ # non-MB: invalid byte or field list 68.4259 -+ # MB: invalid byte, character or field list 68.4260 -+ # Adjust the expected error output accordingly. 68.4261 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 68.4262 -+ (@new_t)) 68.4263 -+ { 68.4264 -+ my $sub = {ERR_SUBST => 's/, character//'}; 68.4265 -+ push @new_t, $sub; 68.4266 -+ push @$t, $sub; 68.4267 -+ } 68.4268 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 68.4269 -+ } 68.4270 -+ push @Tests, @new; 68.4271 -+ } 68.4272 -+ 68.4273 -+ 68.4274 -+@Tests = triple_test \@Tests; 68.4275 -+ 68.4276 - my $save_temps = $ENV{DEBUG}; 68.4277 - my $verbose = $ENV{VERBOSE}; 68.4278 - 68.4279 -diff -Naurp coreutils-8.25-orig/tests/misc/fold.pl coreutils-8.25/tests/misc/fold.pl 68.4280 ---- coreutils-8.25-orig/tests/misc/fold.pl 2016-01-16 12:18:13.000000000 -0600 68.4281 -+++ coreutils-8.25/tests/misc/fold.pl 2016-02-08 19:07:10.314944661 -0600 68.4282 -@@ -20,9 +20,18 @@ use strict; 68.4283 - 68.4284 - (my $program_name = $0) =~ s|.*/||; 68.4285 - 68.4286 -+my $prog = 'fold'; 68.4287 -+my $try = "Try \`$prog --help' for more information.\n"; 68.4288 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 68.4289 -+ 68.4290 - # Turn off localization of executable's output. 68.4291 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 68.4292 - 68.4293 -+# uncommented to enable multibyte paths 68.4294 -+my $mb_locale = $ENV{LOCALE_FR_UTF8}; 68.4295 -+! defined $mb_locale || $mb_locale eq 'none' 68.4296 -+ and $mb_locale = 'C'; 68.4297 -+ 68.4298 - my @Tests = 68.4299 - ( 68.4300 - ['s1', '-w2 -s', {IN=>"a\t"}, {OUT=>"a\n\t"}], 68.4301 -@@ -31,9 +40,48 @@ my @Tests = 68.4302 - ['s4', '-w4 -s', {IN=>"abc ef\n"}, {OUT=>"abc \nef\n"}], 68.4303 - ); 68.4304 - 68.4305 -+# Add _POSIX2_VERSION=199209 to the environment of each test 68.4306 -+# that uses an old-style option like +1. 68.4307 -+if ($mb_locale ne 'C') 68.4308 -+ { 68.4309 -+ # Duplicate each test vector, appending "-mb" to the test name and 68.4310 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 68.4311 -+ # provide coverage for the distro-added multi-byte code paths. 68.4312 -+ my @new; 68.4313 -+ foreach my $t (@Tests) 68.4314 -+ { 68.4315 -+ my @new_t = @$t; 68.4316 -+ my $test_name = shift @new_t; 68.4317 -+ 68.4318 -+ # Depending on whether fold is multi-byte-patched, 68.4319 -+ # it emits different diagnostics: 68.4320 -+ # non-MB: invalid byte or field list 68.4321 -+ # MB: invalid byte, character or field list 68.4322 -+ # Adjust the expected error output accordingly. 68.4323 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 68.4324 -+ (@new_t)) 68.4325 -+ { 68.4326 -+ my $sub = {ERR_SUBST => 's/, character//'}; 68.4327 -+ push @new_t, $sub; 68.4328 -+ push @$t, $sub; 68.4329 -+ } 68.4330 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 68.4331 -+ } 68.4332 -+ push @Tests, @new; 68.4333 -+ } 68.4334 -+ 68.4335 -+@Tests = triple_test \@Tests; 68.4336 -+ 68.4337 -+# Remember that triple_test creates from each test with exactly one "IN" 68.4338 -+# file two more tests (.p and .r suffix on name) corresponding to reading 68.4339 -+# input from a file and from a pipe. The pipe-reading test would fail 68.4340 -+# due to a race condition about 1 in 20 times. 68.4341 -+# Remove the IN_PIPE version of the "output-is-input" test above. 68.4342 -+# The others aren't susceptible because they have three inputs each. 68.4343 -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 68.4344 -+ 68.4345 - my $save_temps = $ENV{DEBUG}; 68.4346 - my $verbose = $ENV{VERBOSE}; 68.4347 - 68.4348 --my $prog = 'fold'; 68.4349 - my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); 68.4350 - exit $fail; 68.4351 -diff -Naurp coreutils-8.25-orig/tests/misc/join.pl coreutils-8.25/tests/misc/join.pl 68.4352 ---- coreutils-8.25-orig/tests/misc/join.pl 2016-01-16 12:18:13.000000000 -0600 68.4353 -+++ coreutils-8.25/tests/misc/join.pl 2016-02-08 19:07:10.315944664 -0600 68.4354 -@@ -25,6 +25,15 @@ my $limits = getlimits (); 68.4355 - 68.4356 - my $prog = 'join'; 68.4357 - 68.4358 -+my $try = "Try \`$prog --help' for more information.\n"; 68.4359 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 68.4360 -+ 68.4361 -+my $mb_locale; 68.4362 -+#Comment out next line to disable multibyte tests 68.4363 -+$mb_locale = $ENV{LOCALE_FR_UTF8}; 68.4364 -+! defined $mb_locale || $mb_locale eq 'none' 68.4365 -+ and $mb_locale = 'C'; 68.4366 -+ 68.4367 - my $delim = chr 0247; 68.4368 - sub t_subst ($) 68.4369 - { 68.4370 -@@ -329,8 +338,49 @@ foreach my $t (@tv) 68.4371 - push @Tests, $new_ent; 68.4372 - } 68.4373 - 68.4374 -+# Add _POSIX2_VERSION=199209 to the environment of each test 68.4375 -+# that uses an old-style option like +1. 68.4376 -+if ($mb_locale ne 'C') 68.4377 -+ { 68.4378 -+ # Duplicate each test vector, appending "-mb" to the test name and 68.4379 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 68.4380 -+ # provide coverage for the distro-added multi-byte code paths. 68.4381 -+ my @new; 68.4382 -+ foreach my $t (@Tests) 68.4383 -+ { 68.4384 -+ my @new_t = @$t; 68.4385 -+ my $test_name = shift @new_t; 68.4386 -+ 68.4387 -+ # Depending on whether join is multi-byte-patched, 68.4388 -+ # it emits different diagnostics: 68.4389 -+ # non-MB: invalid byte or field list 68.4390 -+ # MB: invalid byte, character or field list 68.4391 -+ # Adjust the expected error output accordingly. 68.4392 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 68.4393 -+ (@new_t)) 68.4394 -+ { 68.4395 -+ my $sub = {ERR_SUBST => 's/, character//'}; 68.4396 -+ push @new_t, $sub; 68.4397 -+ push @$t, $sub; 68.4398 -+ } 68.4399 -+ #Adjust the output some error messages including test_name for mb 68.4400 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR}} 68.4401 -+ (@new_t)) 68.4402 -+ { 68.4403 -+ my $sub2 = {ERR_SUBST => "s/$test_name-mb/$test_name/"}; 68.4404 -+ push @new_t, $sub2; 68.4405 -+ push @$t, $sub2; 68.4406 -+ } 68.4407 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 68.4408 -+ } 68.4409 -+ push @Tests, @new; 68.4410 -+ } 68.4411 -+ 68.4412 - @Tests = triple_test \@Tests; 68.4413 - 68.4414 -+#skip invalid-j-mb test, it is failing because of the format 68.4415 -+@Tests = grep {$_->[0] ne 'invalid-j-mb'} @Tests; 68.4416 -+ 68.4417 - my $save_temps = $ENV{DEBUG}; 68.4418 - my $verbose = $ENV{VERBOSE}; 68.4419 - 68.4420 -diff -Naurp coreutils-8.25-orig/tests/misc/sort-mb-tests.sh coreutils-8.25/tests/misc/sort-mb-tests.sh 68.4421 ---- coreutils-8.25-orig/tests/misc/sort-mb-tests.sh 1969-12-31 18:00:00.000000000 -0600 68.4422 -+++ coreutils-8.25/tests/misc/sort-mb-tests.sh 2016-02-08 19:07:10.315944664 -0600 68.4423 -@@ -0,0 +1,45 @@ 68.4424 -+#!/bin/sh 68.4425 -+# Verify sort's multi-byte support. 68.4426 -+ 68.4427 -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 68.4428 -+print_ver_ sort 68.4429 -+ 68.4430 -+export LC_ALL=en_US.UTF-8 68.4431 -+locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 68.4432 -+ || skip_ "No UTF-8 locale available" 68.4433 -+ 68.4434 -+ 68.4435 -+cat <<EOF > exp 68.4436 -+Banana@5 68.4437 -+Apple@10 68.4438 -+Citrus@20 68.4439 -+Cherry@30 68.4440 -+EOF 68.4441 -+ 68.4442 -+cat <<EOF | sort -t @ -k2 -n > out || fail=1 68.4443 -+Apple@10 68.4444 -+Banana@5 68.4445 -+Citrus@20 68.4446 -+Cherry@30 68.4447 -+EOF 68.4448 -+ 68.4449 -+compare exp out || { fail=1; cat out; } 68.4450 -+ 68.4451 -+ 68.4452 -+cat <<EOF > exp 68.4453 -+Citrus@AA20@@5 68.4454 -+Cherry@AA30@@10 68.4455 -+Apple@AA10@@20 68.4456 -+Banana@AA5@@30 68.4457 -+EOF 68.4458 -+ 68.4459 -+cat <<EOF | sort -t @ -k4 -n > out || fail=1 68.4460 -+Apple@AA10@@20 68.4461 -+Banana@AA5@@30 68.4462 -+Citrus@AA20@@5 68.4463 -+Cherry@AA30@@10 68.4464 -+EOF 68.4465 -+ 68.4466 -+compare exp out || { fail=1; cat out; } 68.4467 -+ 68.4468 -+Exit $fail 68.4469 -diff -Naurp coreutils-8.25-orig/tests/misc/sort-merge.pl coreutils-8.25/tests/misc/sort-merge.pl 68.4470 ---- coreutils-8.25-orig/tests/misc/sort-merge.pl 2016-01-16 12:18:14.000000000 -0600 68.4471 -+++ coreutils-8.25/tests/misc/sort-merge.pl 2016-02-08 19:07:10.316944667 -0600 68.4472 -@@ -26,6 +26,15 @@ my $prog = 'sort'; 68.4473 - # Turn off localization of executable's output. 68.4474 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 68.4475 - 68.4476 -+my $mb_locale; 68.4477 -+# uncommented according to upstream commit enabling multibyte paths 68.4478 -+$mb_locale = $ENV{LOCALE_FR_UTF8}; 68.4479 -+! defined $mb_locale || $mb_locale eq 'none' 68.4480 -+ and $mb_locale = 'C'; 68.4481 -+ 68.4482 -+my $try = "Try \`$prog --help' for more information.\n"; 68.4483 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 68.4484 -+ 68.4485 - # three empty files and one that says 'foo' 68.4486 - my @inputs = (+(map{{IN=> {"empty$_"=> ''}}}1..3), {IN=> {foo=> "foo\n"}}); 68.4487 - 68.4488 -@@ -77,6 +86,39 @@ my @Tests = 68.4489 - {OUT=>$big_input}], 68.4490 - ); 68.4491 - 68.4492 -+# Add _POSIX2_VERSION=199209 to the environment of each test 68.4493 -+# that uses an old-style option like +1. 68.4494 -+if ($mb_locale ne 'C') 68.4495 -+ { 68.4496 -+ # Duplicate each test vector, appending "-mb" to the test name and 68.4497 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 68.4498 -+ # provide coverage for the distro-added multi-byte code paths. 68.4499 -+ my @new; 68.4500 -+ foreach my $t (@Tests) 68.4501 -+ { 68.4502 -+ my @new_t = @$t; 68.4503 -+ my $test_name = shift @new_t; 68.4504 -+ 68.4505 -+ # Depending on whether sort is multi-byte-patched, 68.4506 -+ # it emits different diagnostics: 68.4507 -+ # non-MB: invalid byte or field list 68.4508 -+ # MB: invalid byte, character or field list 68.4509 -+ # Adjust the expected error output accordingly. 68.4510 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 68.4511 -+ (@new_t)) 68.4512 -+ { 68.4513 -+ my $sub = {ERR_SUBST => 's/, character//'}; 68.4514 -+ push @new_t, $sub; 68.4515 -+ push @$t, $sub; 68.4516 -+ } 68.4517 -+ next if ($test_name =~ "nmerge-."); 68.4518 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 68.4519 -+ } 68.4520 -+ push @Tests, @new; 68.4521 -+ } 68.4522 -+ 68.4523 -+@Tests = triple_test \@Tests; 68.4524 -+ 68.4525 - my $save_temps = $ENV{DEBUG}; 68.4526 - my $verbose = $ENV{VERBOSE}; 68.4527 - 68.4528 -diff -Naurp coreutils-8.25-orig/tests/misc/sort.pl coreutils-8.25/tests/misc/sort.pl 68.4529 ---- coreutils-8.25-orig/tests/misc/sort.pl 2016-01-16 12:18:14.000000000 -0600 68.4530 -+++ coreutils-8.25/tests/misc/sort.pl 2016-02-08 19:07:10.316944667 -0600 68.4531 -@@ -24,10 +24,15 @@ my $prog = 'sort'; 68.4532 - # Turn off localization of executable's output. 68.4533 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 68.4534 - 68.4535 --my $mb_locale = $ENV{LOCALE_FR_UTF8}; 68.4536 -+my $mb_locale; 68.4537 -+#Comment out next line to disable multibyte tests 68.4538 -+$mb_locale = $ENV{LOCALE_FR_UTF8}; 68.4539 - ! defined $mb_locale || $mb_locale eq 'none' 68.4540 - and $mb_locale = 'C'; 68.4541 - 68.4542 -+my $try = "Try \`$prog --help' for more information.\n"; 68.4543 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 68.4544 -+ 68.4545 - # Since each test is run with a file name and with redirected stdin, 68.4546 - # the name in the diagnostic is either the file name or "-". 68.4547 - # Normalize each diagnostic to use '-'. 68.4548 -@@ -424,6 +429,38 @@ foreach my $t (@Tests) 68.4549 - } 68.4550 - } 68.4551 - 68.4552 -+if ($mb_locale ne 'C') 68.4553 -+ { 68.4554 -+ # Duplicate each test vector, appending "-mb" to the test name and 68.4555 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 68.4556 -+ # provide coverage for the distro-added multi-byte code paths. 68.4557 -+ my @new; 68.4558 -+ foreach my $t (@Tests) 68.4559 -+ { 68.4560 -+ my @new_t = @$t; 68.4561 -+ my $test_name = shift @new_t; 68.4562 -+ 68.4563 -+ # Depending on whether sort is multi-byte-patched, 68.4564 -+ # it emits different diagnostics: 68.4565 -+ # non-MB: invalid byte or field list 68.4566 -+ # MB: invalid byte, character or field list 68.4567 -+ # Adjust the expected error output accordingly. 68.4568 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 68.4569 -+ (@new_t)) 68.4570 -+ { 68.4571 -+ my $sub = {ERR_SUBST => 's/, character//'}; 68.4572 -+ push @new_t, $sub; 68.4573 -+ push @$t, $sub; 68.4574 -+ } 68.4575 -+ #disable several failing tests until investigation, disable all tests with envvars set 68.4576 -+ next if (grep {ref $_ eq 'HASH' && exists $_->{ENV}} (@new_t)); 68.4577 -+ next if ($test_name =~ "18g" or $test_name =~ "sort-numeric" or $test_name =~ "08[ab]" or $test_name =~ "03[def]" or $test_name =~ "h4" or $test_name =~ "n1" or $test_name =~ "2[01]a"); 68.4578 -+ next if ($test_name =~ "11[ab]"); # avoid FP: expected result differs to MB result due to collation rules. 68.4579 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 68.4580 -+ } 68.4581 -+ push @Tests, @new; 68.4582 -+ } 68.4583 -+ 68.4584 - @Tests = triple_test \@Tests; 68.4585 - 68.4586 - # Remember that triple_test creates from each test with exactly one "IN" 68.4587 -@@ -433,6 +470,7 @@ foreach my $t (@Tests) 68.4588 - # Remove the IN_PIPE version of the "output-is-input" test above. 68.4589 - # The others aren't susceptible because they have three inputs each. 68.4590 - @Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 68.4591 -+@Tests = grep {$_->[0] ne 'output-is-input-mb.p'} @Tests; 68.4592 - 68.4593 - my $save_temps = $ENV{DEBUG}; 68.4594 - my $verbose = $ENV{VERBOSE}; 68.4595 -diff -Naurp coreutils-8.25-orig/tests/misc/unexpand.pl coreutils-8.25/tests/misc/unexpand.pl 68.4596 ---- coreutils-8.25-orig/tests/misc/unexpand.pl 2016-01-16 12:18:14.000000000 -0600 68.4597 -+++ coreutils-8.25/tests/misc/unexpand.pl 2016-02-08 19:07:10.317944671 -0600 68.4598 -@@ -27,6 +27,14 @@ my $limits = getlimits (); 68.4599 - 68.4600 - my $prog = 'unexpand'; 68.4601 - 68.4602 -+# comment out next line to disable multibyte tests 68.4603 -+my $mb_locale = $ENV{LOCALE_FR_UTF8}; 68.4604 -+! defined $mb_locale || $mb_locale eq 'none' 68.4605 -+ and $mb_locale = 'C'; 68.4606 -+ 68.4607 -+my $try = "Try \`$prog --help' for more information.\n"; 68.4608 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 68.4609 -+ 68.4610 - my @Tests = 68.4611 - ( 68.4612 - ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], 68.4613 -@@ -92,6 +100,37 @@ my @Tests = 68.4614 - {EXIT => 1}, {ERR => "$prog: tab stop value is too large\n"}], 68.4615 - ); 68.4616 - 68.4617 -+if ($mb_locale ne 'C') 68.4618 -+ { 68.4619 -+ # Duplicate each test vector, appending "-mb" to the test name and 68.4620 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 68.4621 -+ # provide coverage for the distro-added multi-byte code paths. 68.4622 -+ my @new; 68.4623 -+ foreach my $t (@Tests) 68.4624 -+ { 68.4625 -+ my @new_t = @$t; 68.4626 -+ my $test_name = shift @new_t; 68.4627 -+ 68.4628 -+ # Depending on whether unexpand is multi-byte-patched, 68.4629 -+ # it emits different diagnostics: 68.4630 -+ # non-MB: invalid byte or field list 68.4631 -+ # MB: invalid byte, character or field list 68.4632 -+ # Adjust the expected error output accordingly. 68.4633 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 68.4634 -+ (@new_t)) 68.4635 -+ { 68.4636 -+ my $sub = {ERR_SUBST => 's/, character//'}; 68.4637 -+ push @new_t, $sub; 68.4638 -+ push @$t, $sub; 68.4639 -+ } 68.4640 -+ next if ($test_name =~ 'b-1'); 68.4641 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 68.4642 -+ } 68.4643 -+ push @Tests, @new; 68.4644 -+ } 68.4645 -+ 68.4646 -+@Tests = triple_test \@Tests; 68.4647 -+ 68.4648 - my $save_temps = $ENV{DEBUG}; 68.4649 - my $verbose = $ENV{VERBOSE}; 68.4650 - 68.4651 -diff -Naurp coreutils-8.25-orig/tests/misc/uniq.pl coreutils-8.25/tests/misc/uniq.pl 68.4652 ---- coreutils-8.25-orig/tests/misc/uniq.pl 2016-01-16 12:18:14.000000000 -0600 68.4653 -+++ coreutils-8.25/tests/misc/uniq.pl 2016-02-08 19:07:10.317944671 -0600 68.4654 -@@ -23,9 +23,17 @@ my $limits = getlimits (); 68.4655 - my $prog = 'uniq'; 68.4656 - my $try = "Try '$prog --help' for more information.\n"; 68.4657 - 68.4658 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 68.4659 -+ 68.4660 - # Turn off localization of executable's output. 68.4661 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 68.4662 - 68.4663 -+my $mb_locale; 68.4664 -+#Comment out next line to disable multibyte tests 68.4665 -+$mb_locale = $ENV{LOCALE_FR_UTF8}; 68.4666 -+! defined $mb_locale || $mb_locale eq 'none' 68.4667 -+ and $mb_locale = 'C'; 68.4668 -+ 68.4669 - # When possible, create a "-z"-testing variant of each test. 68.4670 - sub add_z_variants($) 68.4671 - { 68.4672 -@@ -262,6 +270,53 @@ foreach my $t (@Tests) 68.4673 - and push @$t, {ENV=>'_POSIX2_VERSION=199209'}; 68.4674 - } 68.4675 - 68.4676 -+if ($mb_locale ne 'C') 68.4677 -+ { 68.4678 -+ # Duplicate each test vector, appending "-mb" to the test name and 68.4679 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 68.4680 -+ # provide coverage for the distro-added multi-byte code paths. 68.4681 -+ my @new; 68.4682 -+ foreach my $t (@Tests) 68.4683 -+ { 68.4684 -+ my @new_t = @$t; 68.4685 -+ my $test_name = shift @new_t; 68.4686 -+ 68.4687 -+ # Depending on whether uniq is multi-byte-patched, 68.4688 -+ # it emits different diagnostics: 68.4689 -+ # non-MB: invalid byte or field list 68.4690 -+ # MB: invalid byte, character or field list 68.4691 -+ # Adjust the expected error output accordingly. 68.4692 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 68.4693 -+ (@new_t)) 68.4694 -+ { 68.4695 -+ my $sub = {ERR_SUBST => 's/, character//'}; 68.4696 -+ push @new_t, $sub; 68.4697 -+ push @$t, $sub; 68.4698 -+ } 68.4699 -+ # In test #145, replace the each ‘...’ by '...'. 68.4700 -+ if ($test_name =~ "145") 68.4701 -+ { 68.4702 -+ my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"}; 68.4703 -+ push @new_t, $sub; 68.4704 -+ push @$t, $sub; 68.4705 -+ } 68.4706 -+ next if ( $test_name =~ "schar" 68.4707 -+ or $test_name =~ "^obs-plus" 68.4708 -+ or $test_name =~ "119"); 68.4709 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 68.4710 -+ } 68.4711 -+ push @Tests, @new; 68.4712 -+ } 68.4713 -+ 68.4714 -+# Remember that triple_test creates from each test with exactly one "IN" 68.4715 -+# file two more tests (.p and .r suffix on name) corresponding to reading 68.4716 -+# input from a file and from a pipe. The pipe-reading test would fail 68.4717 -+# due to a race condition about 1 in 20 times. 68.4718 -+# Remove the IN_PIPE version of the "output-is-input" test above. 68.4719 -+# The others aren't susceptible because they have three inputs each. 68.4720 -+ 68.4721 -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 68.4722 -+ 68.4723 - @Tests = add_z_variants \@Tests; 68.4724 - @Tests = triple_test \@Tests; 68.4725 - 68.4726 -diff -Naurp coreutils-8.25-orig/tests/pr/pr-tests.pl coreutils-8.25/tests/pr/pr-tests.pl 68.4727 ---- coreutils-8.25-orig/tests/pr/pr-tests.pl 2016-01-16 12:18:14.000000000 -0600 68.4728 -+++ coreutils-8.25/tests/pr/pr-tests.pl 2016-02-08 19:07:10.318944674 -0600 68.4729 -@@ -24,6 +24,15 @@ use strict; 68.4730 - my $prog = 'pr'; 68.4731 - my $normalize_strerror = "s/': .*/'/"; 68.4732 - 68.4733 -+my $mb_locale; 68.4734 -+#Uncomment the following line to enable multibyte tests 68.4735 -+$mb_locale = $ENV{LOCALE_FR_UTF8}; 68.4736 -+! defined $mb_locale || $mb_locale eq 'none' 68.4737 -+ and $mb_locale = 'C'; 68.4738 -+ 68.4739 -+my $try = "Try \`$prog --help' for more information.\n"; 68.4740 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 68.4741 -+ 68.4742 - my @tv = ( 68.4743 - 68.4744 - # -b option is no longer an official option. But it's still working to 68.4745 -@@ -467,8 +476,48 @@ push @Tests, 68.4746 - {IN=>{3=>"x\ty\tz\n"}}, 68.4747 - {OUT=>join("\t", qw(a b c m n o x y z)) . "\n"} ]; 68.4748 - 68.4749 -+# Add _POSIX2_VERSION=199209 to the environment of each test 68.4750 -+# that uses an old-style option like +1. 68.4751 -+if ($mb_locale ne 'C') 68.4752 -+ { 68.4753 -+ # Duplicate each test vector, appending "-mb" to the test name and 68.4754 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 68.4755 -+ # provide coverage for the distro-added multi-byte code paths. 68.4756 -+ my @new; 68.4757 -+ foreach my $t (@Tests) 68.4758 -+ { 68.4759 -+ my @new_t = @$t; 68.4760 -+ my $test_name = shift @new_t; 68.4761 -+ 68.4762 -+ # Depending on whether pr is multi-byte-patched, 68.4763 -+ # it emits different diagnostics: 68.4764 -+ # non-MB: invalid byte or field list 68.4765 -+ # MB: invalid byte, character or field list 68.4766 -+ # Adjust the expected error output accordingly. 68.4767 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 68.4768 -+ (@new_t)) 68.4769 -+ { 68.4770 -+ my $sub = {ERR_SUBST => 's/, character//'}; 68.4771 -+ push @new_t, $sub; 68.4772 -+ push @$t, $sub; 68.4773 -+ } 68.4774 -+ #temporarily skip some failing tests 68.4775 -+ next if ($test_name =~ "col-0" or $test_name =~ "col-inval"); 68.4776 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 68.4777 -+ } 68.4778 -+ push @Tests, @new; 68.4779 -+ } 68.4780 -+ 68.4781 - @Tests = triple_test \@Tests; 68.4782 - 68.4783 -+# Remember that triple_test creates from each test with exactly one "IN" 68.4784 -+# file two more tests (.p and .r suffix on name) corresponding to reading 68.4785 -+# input from a file and from a pipe. The pipe-reading test would fail 68.4786 -+# due to a race condition about 1 in 20 times. 68.4787 -+# Remove the IN_PIPE version of the "output-is-input" test above. 68.4788 -+# The others aren't susceptible because they have three inputs each. 68.4789 -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 68.4790 -+ 68.4791 - my $save_temps = $ENV{DEBUG}; 68.4792 - my $verbose = $ENV{VERBOSE}; 68.4793 -
69.1 --- a/coreutils/stuff/coreutils-fix-po.patch Sat May 27 16:29:45 2017 +0300 69.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 69.3 @@ -1,84 +0,0 @@ 69.4 ---- a/po/nb.po 69.5 -+++ b/po/nb.po 69.6 -@@ -2721,7 +2721,7 @@ 69.7 - "A line OFFSET is a required '+' or '-' followed by a positive integer.\n" 69.8 - msgstr "" 69.9 - "\n" 69.10 --"\vMØNSTER må utformes slik:\n" 69.11 -+"MØNSTER må utformes slik:\n" 69.12 - " INTEGER kopier frem til - men ikke inkludert - angitt " 69.13 - "linjenummer\n" 69.14 - " /REGEXP/[OFFSET] kopier frem til - men ikke inkludert - en samsvarende " 69.15 -@@ -7132,7 +7132,7 @@ 69.16 - "Multiple fields/ranges can be separated with commas\n" 69.17 - msgstr "" 69.18 - "\n" 69.19 --"\vFELT støtter feltrekkevidder i cut(1)-stil:\n" 69.20 -+"FELT støtter feltrekkevidder i cut(1)-stil:\n" 69.21 - " N N'te byte, tegn eller felt, talt fra 1\n" 69.22 - " N- fra N'te byte, tegn eller felt, til slutten av linja\n" 69.23 - " N-M fra N'te til M'te (inklusive) byte, tegn eller felt\n" 69.24 ---- a/po/sl.po 69.25 -+++ b/po/sl.po 69.26 -@@ -2641,7 +2641,7 @@ 69.27 - #: src/csplit.c:1299 69.28 - #, c-format 69.29 - msgid "invalid conversion specifier in suffix: \\%.3o" 69.30 --msgstr "neveljavno določilo pretvorbe v priponi: \\\\%.3o" 69.31 -+msgstr "neveljavno določilo pretvorbe v priponi: \\%.3o" 69.32 - 69.33 - #: src/csplit.c:1304 69.34 - #, c-format 69.35 -@@ -6711,7 +6711,7 @@ 69.36 - "ločitvena\n" 69.37 - "znaka za ločevanje logičnih strani; če je drugi znak izpuščen, se " 69.38 - "privzame :.\n" 69.39 --"Uporabite \\\\\\\\ za \\\\. SLOG je nekaj od naštetega:\n" 69.40 -+"Uporabite \\\\ za \\. SLOG je nekaj od naštetega:\n" 69.41 - 69.42 - #: src/nl.c:211 69.43 - msgid "" 69.44 -@@ -7951,8 +7951,8 @@ 69.45 - msgstr "" 69.46 - " -h, --header=ZGLAVJE\n" 69.47 - " uporabimo navedeno osredinjeno ZGLAVJE namesto imena\n" 69.48 --" datoteke; -h \\\"\\\" izpiše prazno vrstica; ne " 69.49 --"uporabljajte -h\\\"\\\"\n" 69.50 -+" datoteke; -h \"\" izpiše prazno vrstica; ne " 69.51 -+"uporabljajte -h\"\"\n" 69.52 - " -i[ZNAK[ŠIRINA]], --output-tabs[=ZNAK[ŠIRINA]]\n" 69.53 - " presledke skrčimo v ZNAK (privzeto TAB) do ŠIRINE\n" 69.54 - " tabulatorja (privzeto 8)\n" 69.55 -@@ -12078,15 +12078,15 @@ 69.56 - "MNOŽICE določajo nizi znakov. Večinoma predstavljajo sebe, posebej pa se\n" 69.57 - "tolmačijo naslednja zaporedja:\n" 69.58 - "\n" 69.59 --" \\\\NNN znak z osmiško kodo NNN (dolžina 1, 2 ali 3 osmiške " 69.60 -+" \\NNN znak z osmiško kodo NNN (dolžina 1, 2 ali 3 osmiške " 69.61 - "števke)\n" 69.62 --" \\\\\\\\ obratna poševnica\n" 69.63 --" \\\\a zvonček\n" 69.64 --" \\\\b pomik za en znak v levo\n" 69.65 --" \\\\f skok na novo stran\n" 69.66 --" \\\\n skok v novo vrstico\n" 69.67 --" \\\\r pomik na levi rob\n" 69.68 --" \\\\t vodoravni tabulator\n" 69.69 -+" \\\\ obratna poševnica\n" 69.70 -+" \\a zvonček\n" 69.71 -+" \\b pomik za en znak v levo\n" 69.72 -+" \\f skok na novo stran\n" 69.73 -+" \\n skok v novo vrstico\n" 69.74 -+" \\r pomik na levi rob\n" 69.75 -+" \\t vodoravni tabulator\n" 69.76 - 69.77 - #: src/tr.c:317 69.78 - msgid "" 69.79 -@@ -12100,7 +12100,7 @@ 69.80 - " [:cntrl:] all control characters\n" 69.81 - " [:digit:] all digits\n" 69.82 - msgstr "" 69.83 --" \\\\v navpični tabulator\n" 69.84 -+" \\v navpični tabulator\n" 69.85 - " ZNAK1-ZNAK2 naraščajoče zaporedje znakov od ZNAKA1 do ZNAKA2\n" 69.86 - " [ZNAK1-ZNAK2] isto kot ZNAK1-ZNAK2, če to uporabljata obe množici\n" 69.87 - " [ZNAK*] v MNOŽICI 2; toliko ponovitev ZNAKA kot v MNOŽICI 1\n"
70.1 --- a/coreutils/stuff/ls.u Sat May 27 16:29:45 2017 +0300 70.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 70.3 @@ -1,10 +0,0 @@ 70.4 ---- coreutils-7.4/src/ls.c 70.5 -+++ coreutils-7.4/src/ls.c 70.6 -@@ -63,6 +63,7 @@ 70.7 - #include <grp.h> 70.8 - #include <pwd.h> 70.9 - #include <getopt.h> 70.10 -+#include <asm/types.h> 70.11 - #include <signal.h> 70.12 - #include <selinux/selinux.h> 70.13 - #include <wchar.h>
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 71.2 +++ b/coreutils/stuff/patches/README Sat May 27 16:55:17 2017 +0300 71.3 @@ -0,0 +1,3 @@ 71.4 +coreutils-8.25-i18n-2.patch: LFS: Coreutils Internationalization Fixes Patch 71.5 +uname.u: SliTaz: show extended info touching CPU via uname 71.6 +coreutils-fix-po.patch: SliTaz: fix translations, especially deprecated symbol '\v'
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 72.2 +++ b/coreutils/stuff/patches/coreutils-8.25-i18n-2.patch Sat May 27 16:55:17 2017 +0300 72.3 @@ -0,0 +1,4790 @@ 72.4 +Submitted by: DJ Lucas (dj_AT_linuxfromscratch_DOT_org) 72.5 +Date: 2016-02-09 72.6 +Initial Package Version: 8.25 72.7 +Upstream Status: Rejected 72.8 +Origin: Based on Suse's i18n patches at https://build.opensuse.org/package/view_file/Base:System/coreutils/coreutils-i18n.patch 72.9 +Description: Fixes several i18n issues with various Coreutils programs 72.10 + 72.11 +diff -Naurp coreutils-8.25-orig/lib/linebuffer.h coreutils-8.25/lib/linebuffer.h 72.12 +--- coreutils-8.25-orig/lib/linebuffer.h 2016-01-01 07:45:55.000000000 -0600 72.13 ++++ coreutils-8.25/lib/linebuffer.h 2016-02-08 19:07:10.298944609 -0600 72.14 +@@ -21,6 +21,11 @@ 72.15 + 72.16 + # include <stdio.h> 72.17 + 72.18 ++/* Get mbstate_t. */ 72.19 ++# if HAVE_WCHAR_H 72.20 ++# include <wchar.h> 72.21 ++# endif 72.22 ++ 72.23 + /* A 'struct linebuffer' holds a line of text. */ 72.24 + 72.25 + struct linebuffer 72.26 +@@ -28,6 +33,9 @@ struct linebuffer 72.27 + size_t size; /* Allocated. */ 72.28 + size_t length; /* Used. */ 72.29 + char *buffer; 72.30 ++# if HAVE_WCHAR_H 72.31 ++ mbstate_t state; 72.32 ++# endif 72.33 + }; 72.34 + 72.35 + /* Initialize linebuffer LINEBUFFER for use. */ 72.36 +diff -Naurp coreutils-8.25-orig/src/cut.c coreutils-8.25/src/cut.c 72.37 +--- coreutils-8.25-orig/src/cut.c 2016-01-13 05:08:59.000000000 -0600 72.38 ++++ coreutils-8.25/src/cut.c 2016-02-08 19:07:10.300944616 -0600 72.39 +@@ -28,6 +28,11 @@ 72.40 + #include <assert.h> 72.41 + #include <getopt.h> 72.42 + #include <sys/types.h> 72.43 ++ 72.44 ++/* Get mbstate_t, mbrtowc(). */ 72.45 ++#if HAVE_WCHAR_H 72.46 ++# include <wchar.h> 72.47 ++#endif 72.48 + #include "system.h" 72.49 + 72.50 + #include "error.h" 72.51 +@@ -38,6 +43,18 @@ 72.52 + 72.53 + #include "set-fields.h" 72.54 + 72.55 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 72.56 ++ installation; work around this configuration error. */ 72.57 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 72.58 ++# undef MB_LEN_MAX 72.59 ++# define MB_LEN_MAX 16 72.60 ++#endif 72.61 ++ 72.62 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 72.63 ++#if HAVE_MBRTOWC && defined mbstate_t 72.64 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 72.65 ++#endif 72.66 ++ 72.67 + /* The official name of this program (e.g., no 'g' prefix). */ 72.68 + #define PROGRAM_NAME "cut" 72.69 + 72.70 +@@ -54,6 +71,52 @@ 72.71 + } \ 72.72 + while (0) 72.73 + 72.74 ++/* Refill the buffer BUF to get a multibyte character. */ 72.75 ++#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM) \ 72.76 ++ do \ 72.77 ++ { \ 72.78 ++ if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM)) \ 72.79 ++ { \ 72.80 ++ memmove (BUF, BUFPOS, BUFLEN); \ 72.81 ++ BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \ 72.82 ++ BUFPOS = BUF; \ 72.83 ++ } \ 72.84 ++ } \ 72.85 ++ while (0) 72.86 ++ 72.87 ++/* Get wide character on BUFPOS. BUFPOS is not included after that. 72.88 ++ If byte sequence is not valid as a character, CONVFAIL is true. Otherwise false. */ 72.89 ++#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ 72.90 ++ do \ 72.91 ++ { \ 72.92 ++ mbstate_t state_bak; \ 72.93 ++ \ 72.94 ++ if (BUFLEN < 1) \ 72.95 ++ { \ 72.96 ++ WC = WEOF; \ 72.97 ++ break; \ 72.98 ++ } \ 72.99 ++ \ 72.100 ++ /* Get a wide character. */ \ 72.101 ++ CONVFAIL = false; \ 72.102 ++ state_bak = STATE; \ 72.103 ++ MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \ 72.104 ++ \ 72.105 ++ switch (MBLENGTH) \ 72.106 ++ { \ 72.107 ++ case (size_t)-1: \ 72.108 ++ case (size_t)-2: \ 72.109 ++ CONVFAIL = true; \ 72.110 ++ STATE = state_bak; \ 72.111 ++ /* Fall througn. */ \ 72.112 ++ \ 72.113 ++ case 0: \ 72.114 ++ MBLENGTH = 1; \ 72.115 ++ break; \ 72.116 ++ } \ 72.117 ++ } \ 72.118 ++ while (0) 72.119 ++ 72.120 + 72.121 + /* Pointer inside RP. When checking if a byte or field is selected 72.122 + by a finite range, we check if it is between CURRENT_RP.LO 72.123 +@@ -61,6 +124,9 @@ 72.124 + CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ 72.125 + static struct field_range_pair *current_rp; 72.126 + 72.127 ++/* Length of the delimiter given as argument to -d. */ 72.128 ++size_t delimlen; 72.129 ++ 72.130 + /* This buffer is used to support the semantics of the -s option 72.131 + (or lack of same) when the specified field list includes (does 72.132 + not include) the first field. In both of those cases, the entire 72.133 +@@ -77,15 +143,25 @@ enum operating_mode 72.134 + { 72.135 + undefined_mode, 72.136 + 72.137 +- /* Output characters that are in the given bytes. */ 72.138 ++ /* Output bytes that are at the given positions. */ 72.139 + byte_mode, 72.140 + 72.141 ++ /* Output characters that are at the given positions. */ 72.142 ++ character_mode, 72.143 ++ 72.144 + /* Output the given delimiter-separated fields. */ 72.145 + field_mode 72.146 + }; 72.147 + 72.148 + static enum operating_mode operating_mode; 72.149 + 72.150 ++/* If nonzero, when in byte mode, don't split multibyte characters. */ 72.151 ++static int byte_mode_character_aware; 72.152 ++ 72.153 ++/* If nonzero, the function for single byte locale is work 72.154 ++ if this program runs on multibyte locale. */ 72.155 ++static int force_singlebyte_mode; 72.156 ++ 72.157 + /* If true do not output lines containing no delimiter characters. 72.158 + Otherwise, all such lines are printed. This option is valid only 72.159 + with field mode. */ 72.160 +@@ -97,6 +173,9 @@ static bool complement; 72.161 + 72.162 + /* The delimiter character for field mode. */ 72.163 + static unsigned char delim; 72.164 ++#if HAVE_WCHAR_H 72.165 ++static wchar_t wcdelim; 72.166 ++#endif 72.167 + 72.168 + /* The delimiter for each line/record. */ 72.169 + static unsigned char line_delim = '\n'; 72.170 +@@ -164,7 +243,7 @@ Print selected parts of lines from each 72.171 + -f, --fields=LIST select only these fields; also print any line\n\ 72.172 + that contains no delimiter character, unless\n\ 72.173 + the -s option is specified\n\ 72.174 +- -n (ignored)\n\ 72.175 ++ -n with -b: don't split multibyte characters\n\ 72.176 + "), stdout); 72.177 + fputs (_("\ 72.178 + --complement complement the set of selected bytes, characters\n\ 72.179 +@@ -280,6 +359,82 @@ cut_bytes (FILE *stream) 72.180 + } 72.181 + } 72.182 + 72.183 ++#if HAVE_MBRTOWC 72.184 ++/* This function is in use for the following case. 72.185 ++ 72.186 ++ 1. Read from the stream STREAM, printing to standard output any selected 72.187 ++ characters. 72.188 ++ 72.189 ++ 2. Read from stream STREAM, printing to standard output any selected bytes, 72.190 ++ without splitting multibyte characters. */ 72.191 ++ 72.192 ++static void 72.193 ++cut_characters_or_cut_bytes_no_split (FILE *stream) 72.194 ++{ 72.195 ++ size_t idx; /* number of bytes or characters in the line so far. */ 72.196 ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 72.197 ++ char *bufpos; /* Next read position of BUF. */ 72.198 ++ size_t buflen; /* The length of the byte sequence in buf. */ 72.199 ++ wint_t wc; /* A gotten wide character. */ 72.200 ++ size_t mblength; /* The byte size of a multibyte character which shows 72.201 ++ as same character as WC. */ 72.202 ++ mbstate_t state; /* State of the stream. */ 72.203 ++ bool convfail = false; /* true, when conversion failed. Otherwise false. */ 72.204 ++ /* Whether to begin printing delimiters between ranges for the current line. 72.205 ++ Set after we've begun printing data corresponding to the first range. */ 72.206 ++ bool print_delimiter = false; 72.207 ++ 72.208 ++ idx = 0; 72.209 ++ buflen = 0; 72.210 ++ bufpos = buf; 72.211 ++ memset (&state, '\0', sizeof(mbstate_t)); 72.212 ++ 72.213 ++ current_rp = frp; 72.214 ++ 72.215 ++ while (1) 72.216 ++ { 72.217 ++ REFILL_BUFFER (buf, bufpos, buflen, stream); 72.218 ++ 72.219 ++ GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); 72.220 ++ (void) convfail; /* ignore unused */ 72.221 ++ 72.222 ++ if (wc == WEOF) 72.223 ++ { 72.224 ++ if (idx > 0) 72.225 ++ putchar (line_delim); 72.226 ++ break; 72.227 ++ } 72.228 ++ else if (wc == line_delim) 72.229 ++ { 72.230 ++ putchar (line_delim); 72.231 ++ idx = 0; 72.232 ++ print_delimiter = false; 72.233 ++ current_rp = frp; 72.234 ++ } 72.235 ++ else 72.236 ++ { 72.237 ++ next_item (&idx); 72.238 ++ if (print_kth (idx)) 72.239 ++ { 72.240 ++ if (output_delimiter_specified) 72.241 ++ { 72.242 ++ if (print_delimiter && is_range_start_index (idx)) 72.243 ++ { 72.244 ++ fwrite (output_delimiter_string, sizeof (char), 72.245 ++ output_delimiter_length, stdout); 72.246 ++ } 72.247 ++ print_delimiter = true; 72.248 ++ } 72.249 ++ fwrite (bufpos, mblength, sizeof(char), stdout); 72.250 ++ } 72.251 ++ } 72.252 ++ 72.253 ++ buflen -= mblength; 72.254 ++ bufpos += mblength; 72.255 ++ } 72.256 ++} 72.257 ++#endif 72.258 ++ 72.259 + /* Read from stream STREAM, printing to standard output any selected fields. */ 72.260 + 72.261 + static void 72.262 +@@ -425,13 +580,211 @@ cut_fields (FILE *stream) 72.263 + } 72.264 + } 72.265 + 72.266 ++#if HAVE_MBRTOWC 72.267 ++static void 72.268 ++cut_fields_mb (FILE *stream) 72.269 ++{ 72.270 ++ int c; 72.271 ++ size_t field_idx; 72.272 ++ int found_any_selected_field; 72.273 ++ int buffer_first_field; 72.274 ++ int empty_input; 72.275 ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 72.276 ++ char *bufpos; /* Next read position of BUF. */ 72.277 ++ size_t buflen; /* The length of the byte sequence in buf. */ 72.278 ++ wint_t wc = 0; /* A gotten wide character. */ 72.279 ++ size_t mblength; /* The byte size of a multibyte character which shows 72.280 ++ as same character as WC. */ 72.281 ++ mbstate_t state; /* State of the stream. */ 72.282 ++ bool convfail = false; /* true, when conversion failed. Otherwise false. */ 72.283 ++ 72.284 ++ current_rp = frp; 72.285 ++ 72.286 ++ found_any_selected_field = 0; 72.287 ++ field_idx = 1; 72.288 ++ bufpos = buf; 72.289 ++ buflen = 0; 72.290 ++ memset (&state, '\0', sizeof(mbstate_t)); 72.291 ++ 72.292 ++ c = getc (stream); 72.293 ++ empty_input = (c == EOF); 72.294 ++ if (c != EOF) 72.295 ++ { 72.296 ++ ungetc (c, stream); 72.297 ++ wc = 0; 72.298 ++ } 72.299 ++ else 72.300 ++ wc = WEOF; 72.301 ++ 72.302 ++ /* To support the semantics of the -s flag, we may have to buffer 72.303 ++ all of the first field to determine whether it is `delimited.' 72.304 ++ But that is unnecessary if all non-delimited lines must be printed 72.305 ++ and the first field has been selected, or if non-delimited lines 72.306 ++ must be suppressed and the first field has *not* been selected. 72.307 ++ That is because a non-delimited line has exactly one field. */ 72.308 ++ buffer_first_field = (suppress_non_delimited ^ !print_kth (1)); 72.309 ++ 72.310 ++ while (1) 72.311 ++ { 72.312 ++ if (field_idx == 1 && buffer_first_field) 72.313 ++ { 72.314 ++ int len = 0; 72.315 ++ 72.316 ++ while (1) 72.317 ++ { 72.318 ++ REFILL_BUFFER (buf, bufpos, buflen, stream); 72.319 ++ 72.320 ++ GET_NEXT_WC_FROM_BUFFER 72.321 ++ (wc, bufpos, buflen, mblength, state, convfail); 72.322 ++ 72.323 ++ if (wc == WEOF) 72.324 ++ break; 72.325 ++ 72.326 ++ field_1_buffer = xrealloc (field_1_buffer, len + mblength); 72.327 ++ memcpy (field_1_buffer + len, bufpos, mblength); 72.328 ++ len += mblength; 72.329 ++ buflen -= mblength; 72.330 ++ bufpos += mblength; 72.331 ++ 72.332 ++ if (!convfail && (wc == line_delim || wc == wcdelim)) 72.333 ++ break; 72.334 ++ } 72.335 ++ 72.336 ++ if (len <= 0 && wc == WEOF) 72.337 ++ break; 72.338 ++ 72.339 ++ /* If the first field extends to the end of line (it is not 72.340 ++ delimited) and we are printing all non-delimited lines, 72.341 ++ print this one. */ 72.342 ++ if (convfail || (!convfail && wc != wcdelim)) 72.343 ++ { 72.344 ++ if (suppress_non_delimited) 72.345 ++ { 72.346 ++ /* Empty. */ 72.347 ++ } 72.348 ++ else 72.349 ++ { 72.350 ++ fwrite (field_1_buffer, sizeof (char), len, stdout); 72.351 ++ /* Make sure the output line is newline terminated. */ 72.352 ++ if (convfail || (!convfail && wc != line_delim)) 72.353 ++ putchar (line_delim); 72.354 ++ } 72.355 ++ continue; 72.356 ++ } 72.357 ++ 72.358 ++ if (print_kth (1)) 72.359 ++ { 72.360 ++ /* Print the field, but not the trailing delimiter. */ 72.361 ++ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); 72.362 ++ found_any_selected_field = 1; 72.363 ++ } 72.364 ++ next_item (&field_idx); 72.365 ++ } 72.366 ++ 72.367 ++ if (wc != WEOF) 72.368 ++ { 72.369 ++ if (print_kth (field_idx)) 72.370 ++ { 72.371 ++ if (found_any_selected_field) 72.372 ++ { 72.373 ++ fwrite (output_delimiter_string, sizeof (char), 72.374 ++ output_delimiter_length, stdout); 72.375 ++ } 72.376 ++ found_any_selected_field = 1; 72.377 ++ } 72.378 ++ 72.379 ++ while (1) 72.380 ++ { 72.381 ++ REFILL_BUFFER (buf, bufpos, buflen, stream); 72.382 ++ 72.383 ++ GET_NEXT_WC_FROM_BUFFER 72.384 ++ (wc, bufpos, buflen, mblength, state, convfail); 72.385 ++ 72.386 ++ if (wc == WEOF) 72.387 ++ break; 72.388 ++ else if (!convfail && (wc == wcdelim || wc == line_delim)) 72.389 ++ { 72.390 ++ buflen -= mblength; 72.391 ++ bufpos += mblength; 72.392 ++ break; 72.393 ++ } 72.394 ++ 72.395 ++ if (print_kth (field_idx)) 72.396 ++ fwrite (bufpos, mblength, sizeof(char), stdout); 72.397 ++ 72.398 ++ buflen -= mblength; 72.399 ++ bufpos += mblength; 72.400 ++ } 72.401 ++ } 72.402 ++ 72.403 ++ if ((!convfail || wc == line_delim) && buflen < 1) 72.404 ++ wc = WEOF; 72.405 ++ 72.406 ++ if (!convfail && wc == wcdelim) 72.407 ++ next_item (&field_idx); 72.408 ++ else if (wc == WEOF || (!convfail && wc == line_delim)) 72.409 ++ { 72.410 ++ if (found_any_selected_field 72.411 ++ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) 72.412 ++ putchar (line_delim); 72.413 ++ if (wc == WEOF) 72.414 ++ break; 72.415 ++ field_idx = 1; 72.416 ++ current_rp = frp; 72.417 ++ found_any_selected_field = 0; 72.418 ++ } 72.419 ++ } 72.420 ++} 72.421 ++#endif 72.422 ++ 72.423 + static void 72.424 + cut_stream (FILE *stream) 72.425 + { 72.426 +- if (operating_mode == byte_mode) 72.427 +- cut_bytes (stream); 72.428 ++#if HAVE_MBRTOWC 72.429 ++ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) 72.430 ++ { 72.431 ++ switch (operating_mode) 72.432 ++ { 72.433 ++ case byte_mode: 72.434 ++ if (byte_mode_character_aware) 72.435 ++ cut_characters_or_cut_bytes_no_split (stream); 72.436 ++ else 72.437 ++ cut_bytes (stream); 72.438 ++ break; 72.439 ++ 72.440 ++ case character_mode: 72.441 ++ cut_characters_or_cut_bytes_no_split (stream); 72.442 ++ break; 72.443 ++ 72.444 ++ case field_mode: 72.445 ++ if (delimlen == 1) 72.446 ++ { 72.447 ++ /* Check if we have utf8 multibyte locale, so we can use this 72.448 ++ optimization because of uniqueness of characters, which is 72.449 ++ not true for e.g. SJIS */ 72.450 ++ char * loc = setlocale(LC_CTYPE, NULL); 72.451 ++ if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") || 72.452 ++ strstr (loc, "UTF8") || strstr (loc, "utf8"))) 72.453 ++ { 72.454 ++ cut_fields (stream); 72.455 ++ break; 72.456 ++ } 72.457 ++ } 72.458 ++ cut_fields_mb (stream); 72.459 ++ break; 72.460 ++ 72.461 ++ default: 72.462 ++ abort (); 72.463 ++ } 72.464 ++ } 72.465 + else 72.466 +- cut_fields (stream); 72.467 ++#endif 72.468 ++ { 72.469 ++ if (operating_mode == field_mode) 72.470 ++ cut_fields (stream); 72.471 ++ else 72.472 ++ cut_bytes (stream); 72.473 ++ } 72.474 + } 72.475 + 72.476 + /* Process file FILE to standard output. 72.477 +@@ -483,6 +836,7 @@ main (int argc, char **argv) 72.478 + bool ok; 72.479 + bool delim_specified = false; 72.480 + char *spec_list_string IF_LINT ( = NULL); 72.481 ++ char mbdelim[MB_LEN_MAX + 1]; 72.482 + 72.483 + initialize_main (&argc, &argv); 72.484 + set_program_name (argv[0]); 72.485 +@@ -505,7 +859,6 @@ main (int argc, char **argv) 72.486 + switch (optc) 72.487 + { 72.488 + case 'b': 72.489 +- case 'c': 72.490 + /* Build the byte list. */ 72.491 + if (operating_mode != undefined_mode) 72.492 + FATAL_ERROR (_("only one type of list may be specified")); 72.493 +@@ -513,6 +866,14 @@ main (int argc, char **argv) 72.494 + spec_list_string = optarg; 72.495 + break; 72.496 + 72.497 ++ case 'c': 72.498 ++ /* Build the character list. */ 72.499 ++ if (operating_mode != undefined_mode) 72.500 ++ FATAL_ERROR (_("only one type of list may be specified")); 72.501 ++ operating_mode = character_mode; 72.502 ++ spec_list_string = optarg; 72.503 ++ break; 72.504 ++ 72.505 + case 'f': 72.506 + /* Build the field list. */ 72.507 + if (operating_mode != undefined_mode) 72.508 +@@ -524,10 +885,38 @@ main (int argc, char **argv) 72.509 + case 'd': 72.510 + /* New delimiter. */ 72.511 + /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ 72.512 +- if (optarg[0] != '\0' && optarg[1] != '\0') 72.513 +- FATAL_ERROR (_("the delimiter must be a single character")); 72.514 +- delim = optarg[0]; 72.515 +- delim_specified = true; 72.516 ++ { 72.517 ++#if HAVE_MBRTOWC 72.518 ++ if(MB_CUR_MAX > 1) 72.519 ++ { 72.520 ++ mbstate_t state; 72.521 ++ 72.522 ++ memset (&state, '\0', sizeof(mbstate_t)); 72.523 ++ delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state); 72.524 ++ 72.525 ++ if (delimlen == (size_t)-1 || delimlen == (size_t)-2) 72.526 ++ ++force_singlebyte_mode; 72.527 ++ else 72.528 ++ { 72.529 ++ delimlen = (delimlen < 1) ? 1 : delimlen; 72.530 ++ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') 72.531 ++ FATAL_ERROR (_("the delimiter must be a single character")); 72.532 ++ memcpy (mbdelim, optarg, delimlen); 72.533 ++ mbdelim[delimlen] = '\0'; 72.534 ++ if (delimlen == 1) 72.535 ++ delim = *optarg; 72.536 ++ } 72.537 ++ } 72.538 ++ 72.539 ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) 72.540 ++#endif 72.541 ++ { 72.542 ++ if (optarg[0] != '\0' && optarg[1] != '\0') 72.543 ++ FATAL_ERROR (_("the delimiter must be a single character")); 72.544 ++ delim = (unsigned char) optarg[0]; 72.545 ++ } 72.546 ++ delim_specified = true; 72.547 ++ } 72.548 + break; 72.549 + 72.550 + case OUTPUT_DELIMITER_OPTION: 72.551 +@@ -540,6 +929,7 @@ main (int argc, char **argv) 72.552 + break; 72.553 + 72.554 + case 'n': 72.555 ++ byte_mode_character_aware = 1; 72.556 + break; 72.557 + 72.558 + case 's': 72.559 +@@ -579,15 +969,34 @@ main (int argc, char **argv) 72.560 + | (complement ? SETFLD_COMPLEMENT : 0) ); 72.561 + 72.562 + if (!delim_specified) 72.563 +- delim = '\t'; 72.564 ++ { 72.565 ++ delim = '\t'; 72.566 ++#ifdef HAVE_MBRTOWC 72.567 ++ wcdelim = L'\t'; 72.568 ++ mbdelim[0] = '\t'; 72.569 ++ mbdelim[1] = '\0'; 72.570 ++ delimlen = 1; 72.571 ++#endif 72.572 ++ } 72.573 + 72.574 + if (output_delimiter_string == NULL) 72.575 + { 72.576 +- static char dummy[2]; 72.577 +- dummy[0] = delim; 72.578 +- dummy[1] = '\0'; 72.579 +- output_delimiter_string = dummy; 72.580 +- output_delimiter_length = 1; 72.581 ++#ifdef HAVE_MBRTOWC 72.582 ++ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) 72.583 ++ { 72.584 ++ output_delimiter_string = xstrdup(mbdelim); 72.585 ++ output_delimiter_length = delimlen; 72.586 ++ } 72.587 ++ 72.588 ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) 72.589 ++#endif 72.590 ++ { 72.591 ++ static char dummy[2]; 72.592 ++ dummy[0] = delim; 72.593 ++ dummy[1] = '\0'; 72.594 ++ output_delimiter_string = dummy; 72.595 ++ output_delimiter_length = 1; 72.596 ++ } 72.597 + } 72.598 + 72.599 + if (optind == argc) 72.600 +diff -Naurp coreutils-8.25-orig/src/expand.c coreutils-8.25/src/expand.c 72.601 +--- coreutils-8.25-orig/src/expand.c 2016-01-01 07:48:50.000000000 -0600 72.602 ++++ coreutils-8.25/src/expand.c 2016-02-08 19:07:10.301944619 -0600 72.603 +@@ -37,12 +37,34 @@ 72.604 + #include <stdio.h> 72.605 + #include <getopt.h> 72.606 + #include <sys/types.h> 72.607 ++ 72.608 ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ 72.609 ++#if HAVE_WCHAR_H 72.610 ++# include <wchar.h> 72.611 ++#endif 72.612 ++ 72.613 ++/* Get iswblank(). */ 72.614 ++#if HAVE_WCTYPE_H 72.615 ++# include <wctype.h> 72.616 ++#endif 72.617 ++ 72.618 + #include "system.h" 72.619 + #include "error.h" 72.620 + #include "fadvise.h" 72.621 + #include "quote.h" 72.622 + #include "xstrndup.h" 72.623 + 72.624 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 72.625 ++ installation; work around this configuration error. */ 72.626 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 72.627 ++# define MB_LEN_MAX 16 72.628 ++#endif 72.629 ++ 72.630 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 72.631 ++#if HAVE_MBRTOWC && defined mbstate_t 72.632 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 72.633 ++#endif 72.634 ++ 72.635 + /* The official name of this program (e.g., no 'g' prefix). */ 72.636 + #define PROGRAM_NAME "expand" 72.637 + 72.638 +@@ -357,6 +379,142 @@ expand (void) 72.639 + } 72.640 + } 72.641 + 72.642 ++#if HAVE_MBRTOWC 72.643 ++static void 72.644 ++expand_multibyte (void) 72.645 ++{ 72.646 ++ FILE *fp; /* Input strem. */ 72.647 ++ mbstate_t i_state; /* Current shift state of the input stream. */ 72.648 ++ mbstate_t i_state_bak; /* Back up the I_STATE. */ 72.649 ++ mbstate_t o_state; /* Current shift state of the output stream. */ 72.650 ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 72.651 ++ char *bufpos = buf; /* Next read position of BUF. */ 72.652 ++ size_t buflen = 0; /* The length of the byte sequence in buf. */ 72.653 ++ wchar_t wc; /* A gotten wide character. */ 72.654 ++ size_t mblength; /* The byte size of a multibyte character 72.655 ++ which shows as same character as WC. */ 72.656 ++ int tab_index = 0; /* Index in `tab_list' of next tabstop. */ 72.657 ++ int column = 0; /* Column on screen of the next char. */ 72.658 ++ int next_tab_column; /* Column the next tab stop is on. */ 72.659 ++ int convert = 1; /* If nonzero, perform translations. */ 72.660 ++ 72.661 ++ fp = next_file ((FILE *) NULL); 72.662 ++ if (fp == NULL) 72.663 ++ return; 72.664 ++ 72.665 ++ memset (&o_state, '\0', sizeof(mbstate_t)); 72.666 ++ memset (&i_state, '\0', sizeof(mbstate_t)); 72.667 ++ 72.668 ++ for (;;) 72.669 ++ { 72.670 ++ /* Refill the buffer BUF. */ 72.671 ++ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) 72.672 ++ { 72.673 ++ memmove (buf, bufpos, buflen); 72.674 ++ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); 72.675 ++ bufpos = buf; 72.676 ++ } 72.677 ++ 72.678 ++ /* No character is left in BUF. */ 72.679 ++ if (buflen < 1) 72.680 ++ { 72.681 ++ fp = next_file (fp); 72.682 ++ 72.683 ++ if (fp == NULL) 72.684 ++ break; /* No more files. */ 72.685 ++ else 72.686 ++ { 72.687 ++ memset (&i_state, '\0', sizeof(mbstate_t)); 72.688 ++ continue; 72.689 ++ } 72.690 ++ } 72.691 ++ 72.692 ++ /* Get a wide character. */ 72.693 ++ i_state_bak = i_state; 72.694 ++ mblength = mbrtowc (&wc, bufpos, buflen, &i_state); 72.695 ++ 72.696 ++ switch (mblength) 72.697 ++ { 72.698 ++ case (size_t)-1: /* illegal byte sequence. */ 72.699 ++ case (size_t)-2: 72.700 ++ mblength = 1; 72.701 ++ i_state = i_state_bak; 72.702 ++ if (convert) 72.703 ++ { 72.704 ++ ++column; 72.705 ++ if (convert_entire_line == 0 && !isblank(*bufpos)) 72.706 ++ convert = 0; 72.707 ++ } 72.708 ++ putchar (*bufpos); 72.709 ++ break; 72.710 ++ 72.711 ++ case 0: /* null. */ 72.712 ++ mblength = 1; 72.713 ++ if (convert && convert_entire_line == 0) 72.714 ++ convert = 0; 72.715 ++ putchar ('\0'); 72.716 ++ break; 72.717 ++ 72.718 ++ default: 72.719 ++ if (wc == L'\n') /* LF. */ 72.720 ++ { 72.721 ++ tab_index = 0; 72.722 ++ column = 0; 72.723 ++ convert = 1; 72.724 ++ putchar ('\n'); 72.725 ++ } 72.726 ++ else if (wc == L'\t' && convert) /* Tab. */ 72.727 ++ { 72.728 ++ if (tab_size == 0) 72.729 ++ { 72.730 ++ /* Do not let tab_index == first_free_tab; 72.731 ++ stop when it is 1 less. */ 72.732 ++ while (tab_index < first_free_tab - 1 72.733 ++ && column >= tab_list[tab_index]) 72.734 ++ tab_index++; 72.735 ++ next_tab_column = tab_list[tab_index]; 72.736 ++ if (tab_index < first_free_tab - 1) 72.737 ++ tab_index++; 72.738 ++ if (column >= next_tab_column) 72.739 ++ next_tab_column = column + 1; 72.740 ++ } 72.741 ++ else 72.742 ++ next_tab_column = column + tab_size - column % tab_size; 72.743 ++ 72.744 ++ while (column < next_tab_column) 72.745 ++ { 72.746 ++ putchar (' '); 72.747 ++ ++column; 72.748 ++ } 72.749 ++ } 72.750 ++ else /* Others. */ 72.751 ++ { 72.752 ++ if (convert) 72.753 ++ { 72.754 ++ if (wc == L'\b') 72.755 ++ { 72.756 ++ if (column > 0) 72.757 ++ --column; 72.758 ++ } 72.759 ++ else 72.760 ++ { 72.761 ++ int width; /* The width of WC. */ 72.762 ++ 72.763 ++ width = wcwidth (wc); 72.764 ++ column += (width > 0) ? width : 0; 72.765 ++ if (convert_entire_line == 0 && !iswblank(wc)) 72.766 ++ convert = 0; 72.767 ++ } 72.768 ++ } 72.769 ++ fwrite (bufpos, sizeof(char), mblength, stdout); 72.770 ++ } 72.771 ++ } 72.772 ++ buflen -= mblength; 72.773 ++ bufpos += mblength; 72.774 ++ } 72.775 ++} 72.776 ++#endif 72.777 ++ 72.778 + int 72.779 + main (int argc, char **argv) 72.780 + { 72.781 +@@ -421,7 +579,12 @@ main (int argc, char **argv) 72.782 + 72.783 + file_list = (optind < argc ? &argv[optind] : stdin_argv); 72.784 + 72.785 +- expand (); 72.786 ++#if HAVE_MBRTOWC 72.787 ++ if (MB_CUR_MAX > 1) 72.788 ++ expand_multibyte (); 72.789 ++ else 72.790 ++#endif 72.791 ++ expand (); 72.792 + 72.793 + if (have_read_stdin && fclose (stdin) != 0) 72.794 + error (EXIT_FAILURE, errno, "-"); 72.795 +diff -Naurp coreutils-8.25-orig/src/fold.c coreutils-8.25/src/fold.c 72.796 +--- coreutils-8.25-orig/src/fold.c 2016-01-01 07:48:50.000000000 -0600 72.797 ++++ coreutils-8.25/src/fold.c 2016-02-08 19:07:10.302944622 -0600 72.798 +@@ -22,11 +22,33 @@ 72.799 + #include <getopt.h> 72.800 + #include <sys/types.h> 72.801 + 72.802 ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ 72.803 ++#if HAVE_WCHAR_H 72.804 ++# include <wchar.h> 72.805 ++#endif 72.806 ++ 72.807 ++/* Get iswprint(), iswblank(), wcwidth(). */ 72.808 ++#if HAVE_WCTYPE_H 72.809 ++# include <wctype.h> 72.810 ++#endif 72.811 ++ 72.812 + #include "system.h" 72.813 + #include "error.h" 72.814 + #include "fadvise.h" 72.815 + #include "xdectoint.h" 72.816 + 72.817 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 72.818 ++ installation; work around this configuration error. */ 72.819 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 72.820 ++# undef MB_LEN_MAX 72.821 ++# define MB_LEN_MAX 16 72.822 ++#endif 72.823 ++ 72.824 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 72.825 ++#if HAVE_MBRTOWC && defined mbstate_t 72.826 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 72.827 ++#endif 72.828 ++ 72.829 + #define TAB_WIDTH 8 72.830 + 72.831 + /* The official name of this program (e.g., no 'g' prefix). */ 72.832 +@@ -34,20 +56,41 @@ 72.833 + 72.834 + #define AUTHORS proper_name ("David MacKenzie") 72.835 + 72.836 ++#define FATAL_ERROR(Message) \ 72.837 ++ do \ 72.838 ++ { \ 72.839 ++ error (0, 0, (Message)); \ 72.840 ++ usage (2); \ 72.841 ++ } \ 72.842 ++ while (0) 72.843 ++ 72.844 ++enum operating_mode 72.845 ++{ 72.846 ++ /* Fold texts by columns that are at the given positions. */ 72.847 ++ column_mode, 72.848 ++ 72.849 ++ /* Fold texts by bytes that are at the given positions. */ 72.850 ++ byte_mode, 72.851 ++ 72.852 ++ /* Fold texts by characters that are at the given positions. */ 72.853 ++ character_mode, 72.854 ++}; 72.855 ++ 72.856 ++/* The argument shows current mode. (Default: column_mode) */ 72.857 ++static enum operating_mode operating_mode; 72.858 ++ 72.859 + /* If nonzero, try to break on whitespace. */ 72.860 + static bool break_spaces; 72.861 + 72.862 +-/* If nonzero, count bytes, not column positions. */ 72.863 +-static bool count_bytes; 72.864 +- 72.865 + /* If nonzero, at least one of the files we read was standard input. */ 72.866 + static bool have_read_stdin; 72.867 + 72.868 +-static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::"; 72.869 ++static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::"; 72.870 + 72.871 + static struct option const longopts[] = 72.872 + { 72.873 + {"bytes", no_argument, NULL, 'b'}, 72.874 ++ {"characters", no_argument, NULL, 'c'}, 72.875 + {"spaces", no_argument, NULL, 's'}, 72.876 + {"width", required_argument, NULL, 'w'}, 72.877 + {GETOPT_HELP_OPTION_DECL}, 72.878 +@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing t 72.879 + 72.880 + fputs (_("\ 72.881 + -b, --bytes count bytes rather than columns\n\ 72.882 ++ -c, --characters count characters rather than columns\n\ 72.883 + -s, --spaces break at spaces\n\ 72.884 + -w, --width=WIDTH use WIDTH columns instead of 80\n\ 72.885 + "), stdout); 72.886 +@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing t 72.887 + static size_t 72.888 + adjust_column (size_t column, char c) 72.889 + { 72.890 +- if (!count_bytes) 72.891 ++ if (operating_mode != byte_mode) 72.892 + { 72.893 + if (c == '\b') 72.894 + { 72.895 +@@ -115,30 +159,14 @@ adjust_column (size_t column, char c) 72.896 + to stdout, with maximum line length WIDTH. 72.897 + Return true if successful. */ 72.898 + 72.899 +-static bool 72.900 +-fold_file (char const *filename, size_t width) 72.901 ++static void 72.902 ++fold_text (FILE *istream, size_t width, int *saved_errno) 72.903 + { 72.904 +- FILE *istream; 72.905 + int c; 72.906 + size_t column = 0; /* Screen column where next char will go. */ 72.907 + size_t offset_out = 0; /* Index in 'line_out' for next char. */ 72.908 + static char *line_out = NULL; 72.909 + static size_t allocated_out = 0; 72.910 +- int saved_errno; 72.911 +- 72.912 +- if (STREQ (filename, "-")) 72.913 +- { 72.914 +- istream = stdin; 72.915 +- have_read_stdin = true; 72.916 +- } 72.917 +- else 72.918 +- istream = fopen (filename, "r"); 72.919 +- 72.920 +- if (istream == NULL) 72.921 +- { 72.922 +- error (0, errno, "%s", quotef (filename)); 72.923 +- return false; 72.924 +- } 72.925 + 72.926 + fadvise (istream, FADVISE_SEQUENTIAL); 72.927 + 72.928 +@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t 72.929 + bool found_blank = false; 72.930 + size_t logical_end = offset_out; 72.931 + 72.932 ++ /* If LINE_OUT has no wide character, 72.933 ++ put a new wide character in LINE_OUT 72.934 ++ if column is bigger than width. */ 72.935 ++ if (offset_out == 0) 72.936 ++ { 72.937 ++ line_out[offset_out++] = c; 72.938 ++ continue; 72.939 ++ } 72.940 ++ 72.941 + /* Look for the last blank. */ 72.942 + while (logical_end) 72.943 + { 72.944 +@@ -214,11 +251,221 @@ fold_file (char const *filename, size_t 72.945 + line_out[offset_out++] = c; 72.946 + } 72.947 + 72.948 +- saved_errno = errno; 72.949 ++ *saved_errno = errno; 72.950 ++ 72.951 ++ if (offset_out) 72.952 ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); 72.953 ++ 72.954 ++} 72.955 ++ 72.956 ++#if HAVE_MBRTOWC 72.957 ++static void 72.958 ++fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) 72.959 ++{ 72.960 ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 72.961 ++ size_t buflen = 0; /* The length of the byte sequence in buf. */ 72.962 ++ char *bufpos = buf; /* Next read position of BUF. */ 72.963 ++ wint_t wc; /* A gotten wide character. */ 72.964 ++ size_t mblength; /* The byte size of a multibyte character which shows 72.965 ++ as same character as WC. */ 72.966 ++ mbstate_t state, state_bak; /* State of the stream. */ 72.967 ++ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ 72.968 ++ 72.969 ++ static char *line_out = NULL; 72.970 ++ size_t offset_out = 0; /* Index in `line_out' for next char. */ 72.971 ++ static size_t allocated_out = 0; 72.972 ++ 72.973 ++ int increment; 72.974 ++ size_t column = 0; 72.975 ++ 72.976 ++ size_t last_blank_pos; 72.977 ++ size_t last_blank_column; 72.978 ++ int is_blank_seen; 72.979 ++ int last_blank_increment = 0; 72.980 ++ int is_bs_following_last_blank; 72.981 ++ size_t bs_following_last_blank_num; 72.982 ++ int is_cr_after_last_blank; 72.983 ++ 72.984 ++#define CLEAR_FLAGS \ 72.985 ++ do \ 72.986 ++ { \ 72.987 ++ last_blank_pos = 0; \ 72.988 ++ last_blank_column = 0; \ 72.989 ++ is_blank_seen = 0; \ 72.990 ++ is_bs_following_last_blank = 0; \ 72.991 ++ bs_following_last_blank_num = 0; \ 72.992 ++ is_cr_after_last_blank = 0; \ 72.993 ++ } \ 72.994 ++ while (0) 72.995 ++ 72.996 ++#define START_NEW_LINE \ 72.997 ++ do \ 72.998 ++ { \ 72.999 ++ putchar ('\n'); \ 72.1000 ++ column = 0; \ 72.1001 ++ offset_out = 0; \ 72.1002 ++ CLEAR_FLAGS; \ 72.1003 ++ } \ 72.1004 ++ while (0) 72.1005 ++ 72.1006 ++ CLEAR_FLAGS; 72.1007 ++ memset (&state, '\0', sizeof(mbstate_t)); 72.1008 ++ 72.1009 ++ for (;; bufpos += mblength, buflen -= mblength) 72.1010 ++ { 72.1011 ++ if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream)) 72.1012 ++ { 72.1013 ++ memmove (buf, bufpos, buflen); 72.1014 ++ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream); 72.1015 ++ bufpos = buf; 72.1016 ++ } 72.1017 ++ 72.1018 ++ if (buflen < 1) 72.1019 ++ break; 72.1020 ++ 72.1021 ++ /* Get a wide character. */ 72.1022 ++ state_bak = state; 72.1023 ++ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state); 72.1024 ++ 72.1025 ++ switch (mblength) 72.1026 ++ { 72.1027 ++ case (size_t)-1: 72.1028 ++ case (size_t)-2: 72.1029 ++ convfail++; 72.1030 ++ state = state_bak; 72.1031 ++ /* Fall through. */ 72.1032 ++ 72.1033 ++ case 0: 72.1034 ++ mblength = 1; 72.1035 ++ break; 72.1036 ++ } 72.1037 ++ 72.1038 ++rescan: 72.1039 ++ if (operating_mode == byte_mode) /* byte mode */ 72.1040 ++ increment = mblength; 72.1041 ++ else if (operating_mode == character_mode) /* character mode */ 72.1042 ++ increment = 1; 72.1043 ++ else /* column mode */ 72.1044 ++ { 72.1045 ++ if (convfail) 72.1046 ++ increment = 1; 72.1047 ++ else 72.1048 ++ { 72.1049 ++ switch (wc) 72.1050 ++ { 72.1051 ++ case L'\n': 72.1052 ++ fwrite (line_out, sizeof(char), offset_out, stdout); 72.1053 ++ START_NEW_LINE; 72.1054 ++ continue; 72.1055 ++ 72.1056 ++ case L'\b': 72.1057 ++ increment = (column > 0) ? -1 : 0; 72.1058 ++ break; 72.1059 ++ 72.1060 ++ case L'\r': 72.1061 ++ increment = -1 * column; 72.1062 ++ break; 72.1063 ++ 72.1064 ++ case L'\t': 72.1065 ++ increment = 8 - column % 8; 72.1066 ++ break; 72.1067 ++ 72.1068 ++ default: 72.1069 ++ increment = wcwidth (wc); 72.1070 ++ increment = (increment < 0) ? 0 : increment; 72.1071 ++ } 72.1072 ++ } 72.1073 ++ } 72.1074 ++ 72.1075 ++ if (column + increment > width && break_spaces && last_blank_pos) 72.1076 ++ { 72.1077 ++ fwrite (line_out, sizeof(char), last_blank_pos, stdout); 72.1078 ++ putchar ('\n'); 72.1079 ++ 72.1080 ++ offset_out = offset_out - last_blank_pos; 72.1081 ++ column = column - last_blank_column + ((is_cr_after_last_blank) 72.1082 ++ ? last_blank_increment : bs_following_last_blank_num); 72.1083 ++ memmove (line_out, line_out + last_blank_pos, offset_out); 72.1084 ++ CLEAR_FLAGS; 72.1085 ++ goto rescan; 72.1086 ++ } 72.1087 ++ 72.1088 ++ if (column + increment > width && column != 0) 72.1089 ++ { 72.1090 ++ fwrite (line_out, sizeof(char), offset_out, stdout); 72.1091 ++ START_NEW_LINE; 72.1092 ++ goto rescan; 72.1093 ++ } 72.1094 ++ 72.1095 ++ if (allocated_out < offset_out + mblength) 72.1096 ++ { 72.1097 ++ line_out = X2REALLOC (line_out, &allocated_out); 72.1098 ++ } 72.1099 ++ 72.1100 ++ memcpy (line_out + offset_out, bufpos, mblength); 72.1101 ++ offset_out += mblength; 72.1102 ++ column += increment; 72.1103 ++ 72.1104 ++ if (is_blank_seen && !convfail && wc == L'\r') 72.1105 ++ is_cr_after_last_blank = 1; 72.1106 ++ 72.1107 ++ if (is_bs_following_last_blank && !convfail && wc == L'\b') 72.1108 ++ ++bs_following_last_blank_num; 72.1109 ++ else 72.1110 ++ is_bs_following_last_blank = 0; 72.1111 ++ 72.1112 ++ if (break_spaces && !convfail && iswblank (wc)) 72.1113 ++ { 72.1114 ++ last_blank_pos = offset_out; 72.1115 ++ last_blank_column = column; 72.1116 ++ is_blank_seen = 1; 72.1117 ++ last_blank_increment = increment; 72.1118 ++ is_bs_following_last_blank = 1; 72.1119 ++ bs_following_last_blank_num = 0; 72.1120 ++ is_cr_after_last_blank = 0; 72.1121 ++ } 72.1122 ++ } 72.1123 ++ 72.1124 ++ *saved_errno = errno; 72.1125 + 72.1126 + if (offset_out) 72.1127 + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); 72.1128 + 72.1129 ++} 72.1130 ++#endif 72.1131 ++ 72.1132 ++/* Fold file FILENAME, or standard input if FILENAME is "-", 72.1133 ++ to stdout, with maximum line length WIDTH. 72.1134 ++ Return 0 if successful, 1 if an error occurs. */ 72.1135 ++ 72.1136 ++static bool 72.1137 ++fold_file (char const *filename, size_t width) 72.1138 ++{ 72.1139 ++ FILE *istream; 72.1140 ++ int saved_errno; 72.1141 ++ 72.1142 ++ if (STREQ (filename, "-")) 72.1143 ++ { 72.1144 ++ istream = stdin; 72.1145 ++ have_read_stdin = 1; 72.1146 ++ } 72.1147 ++ else 72.1148 ++ istream = fopen (filename, "r"); 72.1149 ++ 72.1150 ++ if (istream == NULL) 72.1151 ++ { 72.1152 ++ error (0, errno, "%s", quotef (filename)); 72.1153 ++ return 1; 72.1154 ++ } 72.1155 ++ 72.1156 ++ /* Define how ISTREAM is being folded. */ 72.1157 ++#if HAVE_MBRTOWC 72.1158 ++ if (MB_CUR_MAX > 1) 72.1159 ++ fold_multibyte_text (istream, width, &saved_errno); 72.1160 ++ else 72.1161 ++#endif 72.1162 ++ fold_text (istream, width, &saved_errno); 72.1163 ++ 72.1164 + if (ferror (istream)) 72.1165 + { 72.1166 + error (0, saved_errno, "%s", quotef (filename)); 72.1167 +@@ -251,7 +498,8 @@ main (int argc, char **argv) 72.1168 + 72.1169 + atexit (close_stdout); 72.1170 + 72.1171 +- break_spaces = count_bytes = have_read_stdin = false; 72.1172 ++ operating_mode = column_mode; 72.1173 ++ break_spaces = have_read_stdin = false; 72.1174 + 72.1175 + while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) 72.1176 + { 72.1177 +@@ -260,7 +508,15 @@ main (int argc, char **argv) 72.1178 + switch (optc) 72.1179 + { 72.1180 + case 'b': /* Count bytes rather than columns. */ 72.1181 +- count_bytes = true; 72.1182 ++ if (operating_mode != column_mode) 72.1183 ++ FATAL_ERROR (_("only one way of folding may be specified")); 72.1184 ++ operating_mode = byte_mode; 72.1185 ++ break; 72.1186 ++ 72.1187 ++ case 'c': 72.1188 ++ if (operating_mode != column_mode) 72.1189 ++ FATAL_ERROR (_("only one way of folding may be specified")); 72.1190 ++ operating_mode = character_mode; 72.1191 + break; 72.1192 + 72.1193 + case 's': /* Break at word boundaries. */ 72.1194 +diff -Naurp coreutils-8.25-orig/src/join.c coreutils-8.25/src/join.c 72.1195 +--- coreutils-8.25-orig/src/join.c 2016-01-13 05:08:59.000000000 -0600 72.1196 ++++ coreutils-8.25/src/join.c 2016-02-08 19:07:10.303944625 -0600 72.1197 +@@ -22,18 +22,32 @@ 72.1198 + #include <sys/types.h> 72.1199 + #include <getopt.h> 72.1200 + 72.1201 ++/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth(). */ 72.1202 ++#if HAVE_WCHAR_H 72.1203 ++# include <wchar.h> 72.1204 ++#endif 72.1205 ++ 72.1206 ++/* Get iswblank(), towupper. */ 72.1207 ++#if HAVE_WCTYPE_H 72.1208 ++# include <wctype.h> 72.1209 ++#endif 72.1210 ++ 72.1211 + #include "system.h" 72.1212 + #include "error.h" 72.1213 + #include "fadvise.h" 72.1214 + #include "hard-locale.h" 72.1215 + #include "linebuffer.h" 72.1216 +-#include "memcasecmp.h" 72.1217 + #include "quote.h" 72.1218 + #include "stdio--.h" 72.1219 + #include "xmemcoll.h" 72.1220 + #include "xstrtol.h" 72.1221 + #include "argmatch.h" 72.1222 + 72.1223 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 72.1224 ++#if HAVE_MBRTOWC && defined mbstate_t 72.1225 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 72.1226 ++#endif 72.1227 ++ 72.1228 + /* The official name of this program (e.g., no 'g' prefix). */ 72.1229 + #define PROGRAM_NAME "join" 72.1230 + 72.1231 +@@ -135,10 +149,12 @@ static struct outlist outlist_head; 72.1232 + /* Last element in 'outlist', where a new element can be added. */ 72.1233 + static struct outlist *outlist_end = &outlist_head; 72.1234 + 72.1235 +-/* Tab character separating fields. If negative, fields are separated 72.1236 +- by any nonempty string of blanks, otherwise by exactly one 72.1237 +- tab character whose value (when cast to unsigned char) equals TAB. */ 72.1238 +-static int tab = -1; 72.1239 ++/* Tab character separating fields. If NULL, fields are separated 72.1240 ++ by any nonempty string of blanks. */ 72.1241 ++static char *tab = NULL; 72.1242 ++ 72.1243 ++/* The number of bytes used for tab. */ 72.1244 ++static size_t tablen = 0; 72.1245 + 72.1246 + /* If nonzero, check that the input is correctly ordered. */ 72.1247 + static enum 72.1248 +@@ -275,13 +291,14 @@ xfields (struct line *line) 72.1249 + if (ptr == lim) 72.1250 + return; 72.1251 + 72.1252 +- if (0 <= tab && tab != '\n') 72.1253 ++ if (tab != NULL) 72.1254 + { 72.1255 ++ unsigned char t = tab[0]; 72.1256 + char *sep; 72.1257 +- for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1) 72.1258 ++ for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1) 72.1259 + extract_field (line, ptr, sep - ptr); 72.1260 + } 72.1261 +- else if (tab < 0) 72.1262 ++ else 72.1263 + { 72.1264 + /* Skip leading blanks before the first field. */ 72.1265 + while (field_sep (*ptr)) 72.1266 +@@ -305,6 +322,147 @@ xfields (struct line *line) 72.1267 + extract_field (line, ptr, lim - ptr); 72.1268 + } 72.1269 + 72.1270 ++#if HAVE_MBRTOWC 72.1271 ++static void 72.1272 ++xfields_multibyte (struct line *line) 72.1273 ++{ 72.1274 ++ char *ptr = line->buf.buffer; 72.1275 ++ char const *lim = ptr + line->buf.length - 1; 72.1276 ++ wchar_t wc = 0; 72.1277 ++ size_t mblength = 1; 72.1278 ++ mbstate_t state, state_bak; 72.1279 ++ 72.1280 ++ memset (&state, 0, sizeof (mbstate_t)); 72.1281 ++ 72.1282 ++ if (ptr >= lim) 72.1283 ++ return; 72.1284 ++ 72.1285 ++ if (tab != NULL) 72.1286 ++ { 72.1287 ++ char *sep = ptr; 72.1288 ++ for (; ptr < lim; ptr = sep + mblength) 72.1289 ++ { 72.1290 ++ sep = ptr; 72.1291 ++ while (sep < lim) 72.1292 ++ { 72.1293 ++ state_bak = state; 72.1294 ++ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 72.1295 ++ 72.1296 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 72.1297 ++ { 72.1298 ++ mblength = 1; 72.1299 ++ state = state_bak; 72.1300 ++ } 72.1301 ++ mblength = (mblength < 1) ? 1 : mblength; 72.1302 ++ 72.1303 ++ if (mblength == tablen && !memcmp (sep, tab, mblength)) 72.1304 ++ break; 72.1305 ++ else 72.1306 ++ { 72.1307 ++ sep += mblength; 72.1308 ++ continue; 72.1309 ++ } 72.1310 ++ } 72.1311 ++ 72.1312 ++ if (sep >= lim) 72.1313 ++ break; 72.1314 ++ 72.1315 ++ extract_field (line, ptr, sep - ptr); 72.1316 ++ } 72.1317 ++ } 72.1318 ++ else 72.1319 ++ { 72.1320 ++ /* Skip leading blanks before the first field. */ 72.1321 ++ while(ptr < lim) 72.1322 ++ { 72.1323 ++ state_bak = state; 72.1324 ++ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 72.1325 ++ 72.1326 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 72.1327 ++ { 72.1328 ++ mblength = 1; 72.1329 ++ state = state_bak; 72.1330 ++ break; 72.1331 ++ } 72.1332 ++ mblength = (mblength < 1) ? 1 : mblength; 72.1333 ++ 72.1334 ++ if (!iswblank(wc) && wc != '\n') 72.1335 ++ break; 72.1336 ++ ptr += mblength; 72.1337 ++ } 72.1338 ++ 72.1339 ++ do 72.1340 ++ { 72.1341 ++ char *sep; 72.1342 ++ state_bak = state; 72.1343 ++ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 72.1344 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 72.1345 ++ { 72.1346 ++ mblength = 1; 72.1347 ++ state = state_bak; 72.1348 ++ break; 72.1349 ++ } 72.1350 ++ mblength = (mblength < 1) ? 1 : mblength; 72.1351 ++ 72.1352 ++ sep = ptr + mblength; 72.1353 ++ while (sep < lim) 72.1354 ++ { 72.1355 ++ state_bak = state; 72.1356 ++ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 72.1357 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 72.1358 ++ { 72.1359 ++ mblength = 1; 72.1360 ++ state = state_bak; 72.1361 ++ break; 72.1362 ++ } 72.1363 ++ mblength = (mblength < 1) ? 1 : mblength; 72.1364 ++ 72.1365 ++ if (iswblank (wc) || wc == '\n') 72.1366 ++ break; 72.1367 ++ 72.1368 ++ sep += mblength; 72.1369 ++ } 72.1370 ++ 72.1371 ++ extract_field (line, ptr, sep - ptr); 72.1372 ++ if (sep >= lim) 72.1373 ++ return; 72.1374 ++ 72.1375 ++ state_bak = state; 72.1376 ++ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 72.1377 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 72.1378 ++ { 72.1379 ++ mblength = 1; 72.1380 ++ state = state_bak; 72.1381 ++ break; 72.1382 ++ } 72.1383 ++ mblength = (mblength < 1) ? 1 : mblength; 72.1384 ++ 72.1385 ++ ptr = sep + mblength; 72.1386 ++ while (ptr < lim) 72.1387 ++ { 72.1388 ++ state_bak = state; 72.1389 ++ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 72.1390 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 72.1391 ++ { 72.1392 ++ mblength = 1; 72.1393 ++ state = state_bak; 72.1394 ++ break; 72.1395 ++ } 72.1396 ++ mblength = (mblength < 1) ? 1 : mblength; 72.1397 ++ 72.1398 ++ if (!iswblank (wc) && wc != '\n') 72.1399 ++ break; 72.1400 ++ 72.1401 ++ ptr += mblength; 72.1402 ++ } 72.1403 ++ } 72.1404 ++ while (ptr < lim); 72.1405 ++ } 72.1406 ++ 72.1407 ++ extract_field (line, ptr, lim - ptr); 72.1408 ++} 72.1409 ++#endif 72.1410 ++ 72.1411 + static void 72.1412 + freeline (struct line *line) 72.1413 + { 72.1414 +@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct 72.1415 + size_t jf_1, size_t jf_2) 72.1416 + { 72.1417 + /* Start of field to compare in each file. */ 72.1418 +- char *beg1; 72.1419 +- char *beg2; 72.1420 +- 72.1421 +- size_t len1; 72.1422 +- size_t len2; /* Length of fields to compare. */ 72.1423 ++ char *beg[2]; 72.1424 ++ char *copy[2]; 72.1425 ++ size_t len[2]; /* Length of fields to compare. */ 72.1426 + int diff; 72.1427 ++ int i, j; 72.1428 ++ int mallocd = 0; 72.1429 + 72.1430 + if (jf_1 < line1->nfields) 72.1431 + { 72.1432 +- beg1 = line1->fields[jf_1].beg; 72.1433 +- len1 = line1->fields[jf_1].len; 72.1434 ++ beg[0] = line1->fields[jf_1].beg; 72.1435 ++ len[0] = line1->fields[jf_1].len; 72.1436 + } 72.1437 + else 72.1438 + { 72.1439 +- beg1 = NULL; 72.1440 +- len1 = 0; 72.1441 ++ beg[0] = NULL; 72.1442 ++ len[0] = 0; 72.1443 + } 72.1444 + 72.1445 + if (jf_2 < line2->nfields) 72.1446 + { 72.1447 +- beg2 = line2->fields[jf_2].beg; 72.1448 +- len2 = line2->fields[jf_2].len; 72.1449 ++ beg[1] = line2->fields[jf_2].beg; 72.1450 ++ len[1] = line2->fields[jf_2].len; 72.1451 + } 72.1452 + else 72.1453 + { 72.1454 +- beg2 = NULL; 72.1455 +- len2 = 0; 72.1456 ++ beg[1] = NULL; 72.1457 ++ len[1] = 0; 72.1458 + } 72.1459 + 72.1460 +- if (len1 == 0) 72.1461 +- return len2 == 0 ? 0 : -1; 72.1462 +- if (len2 == 0) 72.1463 ++ if (len[0] == 0) 72.1464 ++ return len[1] == 0 ? 0 : -1; 72.1465 ++ if (len[1] == 0) 72.1466 + return 1; 72.1467 + 72.1468 + if (ignore_case) 72.1469 + { 72.1470 +- /* FIXME: ignore_case does not work with NLS (in particular, 72.1471 +- with multibyte chars). */ 72.1472 +- diff = memcasecmp (beg1, beg2, MIN (len1, len2)); 72.1473 ++#ifdef HAVE_MBRTOWC 72.1474 ++ if (MB_CUR_MAX > 1) 72.1475 ++ { 72.1476 ++ size_t mblength; 72.1477 ++ wchar_t wc, uwc; 72.1478 ++ mbstate_t state, state_bak; 72.1479 ++ 72.1480 ++ memset (&state, '\0', sizeof (mbstate_t)); 72.1481 ++ 72.1482 ++ for (i = 0; i < 2; i++) 72.1483 ++ { 72.1484 ++ mallocd = 1; 72.1485 ++ copy[i] = xmalloc (len[i] + 1); 72.1486 ++ memset (copy[i], '\0',len[i] + 1); 72.1487 ++ 72.1488 ++ for (j = 0; j < MIN (len[0], len[1]);) 72.1489 ++ { 72.1490 ++ state_bak = state; 72.1491 ++ mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state); 72.1492 ++ 72.1493 ++ switch (mblength) 72.1494 ++ { 72.1495 ++ case (size_t) -1: 72.1496 ++ case (size_t) -2: 72.1497 ++ state = state_bak; 72.1498 ++ /* Fall through */ 72.1499 ++ case 0: 72.1500 ++ mblength = 1; 72.1501 ++ break; 72.1502 ++ 72.1503 ++ default: 72.1504 ++ uwc = towupper (wc); 72.1505 ++ 72.1506 ++ if (uwc != wc) 72.1507 ++ { 72.1508 ++ mbstate_t state_wc; 72.1509 ++ size_t mblen; 72.1510 ++ 72.1511 ++ memset (&state_wc, '\0', sizeof (mbstate_t)); 72.1512 ++ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); 72.1513 ++ assert (mblen != (size_t)-1); 72.1514 ++ } 72.1515 ++ else 72.1516 ++ memcpy (copy[i] + j, beg[i] + j, mblength); 72.1517 ++ } 72.1518 ++ j += mblength; 72.1519 ++ } 72.1520 ++ copy[i][j] = '\0'; 72.1521 ++ } 72.1522 ++ } 72.1523 ++ else 72.1524 ++#endif 72.1525 ++ { 72.1526 ++ for (i = 0; i < 2; i++) 72.1527 ++ { 72.1528 ++ mallocd = 1; 72.1529 ++ copy[i] = xmalloc (len[i] + 1); 72.1530 ++ 72.1531 ++ for (j = 0; j < MIN (len[0], len[1]); j++) 72.1532 ++ copy[i][j] = toupper (beg[i][j]); 72.1533 ++ 72.1534 ++ copy[i][j] = '\0'; 72.1535 ++ } 72.1536 ++ } 72.1537 + } 72.1538 + else 72.1539 + { 72.1540 +- if (hard_LC_COLLATE) 72.1541 +- return xmemcoll (beg1, len1, beg2, len2); 72.1542 +- diff = memcmp (beg1, beg2, MIN (len1, len2)); 72.1543 ++ copy[0] = beg[0]; 72.1544 ++ copy[1] = beg[1]; 72.1545 ++ } 72.1546 ++ 72.1547 ++ if (hard_LC_COLLATE) 72.1548 ++ { 72.1549 ++ diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); 72.1550 ++ 72.1551 ++ if (mallocd) 72.1552 ++ for (i = 0; i < 2; i++) 72.1553 ++ free (copy[i]); 72.1554 ++ 72.1555 ++ return diff; 72.1556 + } 72.1557 ++ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); 72.1558 ++ 72.1559 ++ if (mallocd) 72.1560 ++ for (i = 0; i < 2; i++) 72.1561 ++ free (copy[i]); 72.1562 ++ 72.1563 + 72.1564 + if (diff) 72.1565 + return diff; 72.1566 +- return len1 < len2 ? -1 : len1 != len2; 72.1567 ++ return len[0] - len[1]; 72.1568 + } 72.1569 + 72.1570 + /* Check that successive input lines PREV and CURRENT from input file 72.1571 +@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep, 72.1572 + } 72.1573 + ++line_no[which - 1]; 72.1574 + 72.1575 ++#if HAVE_MBRTOWC 72.1576 ++ if (MB_CUR_MAX > 1) 72.1577 ++ xfields_multibyte (line); 72.1578 ++ else 72.1579 ++#endif 72.1580 + xfields (line); 72.1581 + 72.1582 + if (prevline[which - 1]) 72.1583 +@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *li 72.1584 + 72.1585 + /* Output all the fields in line, other than the join field. */ 72.1586 + 72.1587 ++#define PUT_TAB_CHAR \ 72.1588 ++ do \ 72.1589 ++ { \ 72.1590 ++ (tab != NULL) ? \ 72.1591 ++ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ 72.1592 ++ } \ 72.1593 ++ while (0) 72.1594 ++ 72.1595 + static void 72.1596 + prfields (struct line const *line, size_t join_field, size_t autocount) 72.1597 + { 72.1598 + size_t i; 72.1599 + size_t nfields = autoformat ? autocount : line->nfields; 72.1600 +- char output_separator = tab < 0 ? ' ' : tab; 72.1601 + 72.1602 + for (i = 0; i < join_field && i < nfields; ++i) 72.1603 + { 72.1604 +- putchar (output_separator); 72.1605 ++ PUT_TAB_CHAR; 72.1606 + prfield (i, line); 72.1607 + } 72.1608 + for (i = join_field + 1; i < nfields; ++i) 72.1609 + { 72.1610 +- putchar (output_separator); 72.1611 ++ PUT_TAB_CHAR; 72.1612 + prfield (i, line); 72.1613 + } 72.1614 + } 72.1615 +@@ -591,7 +838,6 @@ static void 72.1616 + prjoin (struct line const *line1, struct line const *line2) 72.1617 + { 72.1618 + const struct outlist *outlist; 72.1619 +- char output_separator = tab < 0 ? ' ' : tab; 72.1620 + size_t field; 72.1621 + struct line const *line; 72.1622 + 72.1623 +@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct 72.1624 + o = o->next; 72.1625 + if (o == NULL) 72.1626 + break; 72.1627 +- putchar (output_separator); 72.1628 ++ PUT_TAB_CHAR; 72.1629 + } 72.1630 + putchar (eolchar); 72.1631 + } 72.1632 +@@ -1103,21 +1349,46 @@ main (int argc, char **argv) 72.1633 + 72.1634 + case 't': 72.1635 + { 72.1636 +- unsigned char newtab = optarg[0]; 72.1637 ++ char *newtab = NULL; 72.1638 ++ size_t newtablen; 72.1639 ++ newtab = xstrdup (optarg); 72.1640 ++#if HAVE_MBRTOWC 72.1641 ++ if (MB_CUR_MAX > 1) 72.1642 ++ { 72.1643 ++ mbstate_t state; 72.1644 ++ 72.1645 ++ memset (&state, 0, sizeof (mbstate_t)); 72.1646 ++ newtablen = mbrtowc (NULL, newtab, 72.1647 ++ strnlen (newtab, MB_LEN_MAX), 72.1648 ++ &state); 72.1649 ++ if (newtablen == (size_t) 0 72.1650 ++ || newtablen == (size_t) -1 72.1651 ++ || newtablen == (size_t) -2) 72.1652 ++ newtablen = 1; 72.1653 ++ } 72.1654 ++ else 72.1655 ++#endif 72.1656 ++ newtablen = 1; 72.1657 + if (! newtab) 72.1658 +- newtab = '\n'; /* '' => process the whole line. */ 72.1659 ++ { 72.1660 ++ newtab = (char*)"\n"; /* '' => process the whole line. */ 72.1661 ++ } 72.1662 + else if (optarg[1]) 72.1663 + { 72.1664 +- if (STREQ (optarg, "\\0")) 72.1665 +- newtab = '\0'; 72.1666 +- else 72.1667 +- error (EXIT_FAILURE, 0, _("multi-character tab %s"), 72.1668 +- quote (optarg)); 72.1669 ++ if (newtablen == 1 && newtab[1]) 72.1670 ++ { 72.1671 ++ if (STREQ (newtab, "\\0")) 72.1672 ++ newtab[0] = '\0'; 72.1673 ++ } 72.1674 ++ } 72.1675 ++ if (tab != NULL && strcmp (tab, newtab)) 72.1676 ++ { 72.1677 ++ free (newtab); 72.1678 ++ error (EXIT_FAILURE, 0, _("incompatible tabs")); 72.1679 + } 72.1680 +- if (0 <= tab && tab != newtab) 72.1681 +- error (EXIT_FAILURE, 0, _("incompatible tabs")); 72.1682 + tab = newtab; 72.1683 +- } 72.1684 ++ tablen = newtablen; 72.1685 ++ } 72.1686 + break; 72.1687 + 72.1688 + case 'z': 72.1689 +diff -Naurp coreutils-8.25-orig/src/pr.c coreutils-8.25/src/pr.c 72.1690 +--- coreutils-8.25-orig/src/pr.c 2016-01-01 07:48:50.000000000 -0600 72.1691 ++++ coreutils-8.25/src/pr.c 2016-02-08 19:07:10.306944635 -0600 72.1692 +@@ -311,6 +311,24 @@ 72.1693 + 72.1694 + #include <getopt.h> 72.1695 + #include <sys/types.h> 72.1696 ++ 72.1697 ++/* Get MB_LEN_MAX. */ 72.1698 ++#include <limits.h> 72.1699 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 72.1700 ++ installation; work around this configuration error. */ 72.1701 ++#if !defined MB_LEN_MAX || MB_LEN_MAX == 1 72.1702 ++# define MB_LEN_MAX 16 72.1703 ++#endif 72.1704 ++ 72.1705 ++/* Get MB_CUR_MAX. */ 72.1706 ++#include <stdlib.h> 72.1707 ++ 72.1708 ++/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */ 72.1709 ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ 72.1710 ++#if HAVE_WCHAR_H 72.1711 ++# include <wchar.h> 72.1712 ++#endif 72.1713 ++ 72.1714 + #include "system.h" 72.1715 + #include "error.h" 72.1716 + #include "fadvise.h" 72.1717 +@@ -323,6 +341,18 @@ 72.1718 + #include "xstrtol.h" 72.1719 + #include "xdectoint.h" 72.1720 + 72.1721 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 72.1722 ++#if HAVE_MBRTOWC && defined mbstate_t 72.1723 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 72.1724 ++#endif 72.1725 ++ 72.1726 ++#ifndef HAVE_DECL_WCWIDTH 72.1727 ++"this configure-time declaration test was not run" 72.1728 ++#endif 72.1729 ++#if !HAVE_DECL_WCWIDTH 72.1730 ++extern int wcwidth (); 72.1731 ++#endif 72.1732 ++ 72.1733 + /* The official name of this program (e.g., no 'g' prefix). */ 72.1734 + #define PROGRAM_NAME "pr" 72.1735 + 72.1736 +@@ -415,7 +445,20 @@ struct COLUMN 72.1737 + 72.1738 + typedef struct COLUMN COLUMN; 72.1739 + 72.1740 +-static int char_to_clump (char c); 72.1741 ++/* Funtion pointers to switch functions for single byte locale or for 72.1742 ++ multibyte locale. If multibyte functions do not exist in your sysytem, 72.1743 ++ these pointers always point the function for single byte locale. */ 72.1744 ++static void (*print_char) (char c); 72.1745 ++static int (*char_to_clump) (char c); 72.1746 ++ 72.1747 ++/* Functions for single byte locale. */ 72.1748 ++static void print_char_single (char c); 72.1749 ++static int char_to_clump_single (char c); 72.1750 ++ 72.1751 ++/* Functions for multibyte locale. */ 72.1752 ++static void print_char_multi (char c); 72.1753 ++static int char_to_clump_multi (char c); 72.1754 ++ 72.1755 + static bool read_line (COLUMN *p); 72.1756 + static bool print_page (void); 72.1757 + static bool print_stored (COLUMN *p); 72.1758 +@@ -427,6 +470,7 @@ static void add_line_number (COLUMN *p); 72.1759 + static void getoptnum (const char *n_str, int min, int *num, 72.1760 + const char *errfmt); 72.1761 + static void getoptarg (char *arg, char switch_char, char *character, 72.1762 ++ int *character_length, int *character_width, 72.1763 + int *number); 72.1764 + static void print_files (int number_of_files, char **av); 72.1765 + static void init_parameters (int number_of_files); 72.1766 +@@ -440,7 +484,6 @@ static void store_char (char c); 72.1767 + static void pad_down (unsigned int lines); 72.1768 + static void read_rest_of_line (COLUMN *p); 72.1769 + static void skip_read (COLUMN *p, int column_number); 72.1770 +-static void print_char (char c); 72.1771 + static void cleanup (void); 72.1772 + static void print_sep_string (void); 72.1773 + static void separator_string (const char *optarg_S); 72.1774 +@@ -452,7 +495,7 @@ static COLUMN *column_vector; 72.1775 + we store the leftmost columns contiguously in buff. 72.1776 + To print a line from buff, get the index of the first character 72.1777 + from line_vector[i], and print up to line_vector[i + 1]. */ 72.1778 +-static char *buff; 72.1779 ++static unsigned char *buff; 72.1780 + 72.1781 + /* Index of the position in buff where the next character 72.1782 + will be stored. */ 72.1783 +@@ -556,7 +599,7 @@ static int chars_per_column; 72.1784 + static bool untabify_input = false; 72.1785 + 72.1786 + /* (-e) The input tab character. */ 72.1787 +-static char input_tab_char = '\t'; 72.1788 ++static char input_tab_char[MB_LEN_MAX] = "\t"; 72.1789 + 72.1790 + /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... 72.1791 + where the leftmost column is 1. */ 72.1792 +@@ -566,7 +609,10 @@ static int chars_per_input_tab = 8; 72.1793 + static bool tabify_output = false; 72.1794 + 72.1795 + /* (-i) The output tab character. */ 72.1796 +-static char output_tab_char = '\t'; 72.1797 ++static char output_tab_char[MB_LEN_MAX] = "\t"; 72.1798 ++ 72.1799 ++/* (-i) The byte length of output tab character. */ 72.1800 ++static int output_tab_char_length = 1; 72.1801 + 72.1802 + /* (-i) The width of the output tab. */ 72.1803 + static int chars_per_output_tab = 8; 72.1804 +@@ -636,7 +682,13 @@ static int line_number; 72.1805 + static bool numbered_lines = false; 72.1806 + 72.1807 + /* (-n) Character which follows each line number. */ 72.1808 +-static char number_separator = '\t'; 72.1809 ++static char number_separator[MB_LEN_MAX] = "\t"; 72.1810 ++ 72.1811 ++/* (-n) The byte length of the character which follows each line number. */ 72.1812 ++static int number_separator_length = 1; 72.1813 ++ 72.1814 ++/* (-n) The character width of the character which follows each line number. */ 72.1815 ++static int number_separator_width = 0; 72.1816 + 72.1817 + /* (-n) line counting starts with 1st line of input file (not with 1st 72.1818 + line of 1st page printed). */ 72.1819 +@@ -689,6 +741,7 @@ static bool use_col_separator = false; 72.1820 + -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ 72.1821 + static char *col_sep_string = (char *) ""; 72.1822 + static int col_sep_length = 0; 72.1823 ++static int col_sep_width = 0; 72.1824 + static char *column_separator = (char *) " "; 72.1825 + static char *line_separator = (char *) "\t"; 72.1826 + 72.1827 +@@ -839,6 +892,13 @@ separator_string (const char *optarg_S) 72.1828 + col_sep_length = (int) strlen (optarg_S); 72.1829 + col_sep_string = xmalloc (col_sep_length + 1); 72.1830 + strcpy (col_sep_string, optarg_S); 72.1831 ++ 72.1832 ++#if HAVE_MBRTOWC 72.1833 ++ if (MB_CUR_MAX > 1) 72.1834 ++ col_sep_width = mbswidth (col_sep_string, 0); 72.1835 ++ else 72.1836 ++#endif 72.1837 ++ col_sep_width = col_sep_length; 72.1838 + } 72.1839 + 72.1840 + int 72.1841 +@@ -863,6 +923,21 @@ main (int argc, char **argv) 72.1842 + 72.1843 + atexit (close_stdout); 72.1844 + 72.1845 ++/* Define which functions are used, the ones for single byte locale or the ones 72.1846 ++ for multibyte locale. */ 72.1847 ++#if HAVE_MBRTOWC 72.1848 ++ if (MB_CUR_MAX > 1) 72.1849 ++ { 72.1850 ++ print_char = print_char_multi; 72.1851 ++ char_to_clump = char_to_clump_multi; 72.1852 ++ } 72.1853 ++ else 72.1854 ++#endif 72.1855 ++ { 72.1856 ++ print_char = print_char_single; 72.1857 ++ char_to_clump = char_to_clump_single; 72.1858 ++ } 72.1859 ++ 72.1860 + n_files = 0; 72.1861 + file_names = (argc > 1 72.1862 + ? xmalloc ((argc - 1) * sizeof (char *)) 72.1863 +@@ -939,8 +1014,12 @@ main (int argc, char **argv) 72.1864 + break; 72.1865 + case 'e': 72.1866 + if (optarg) 72.1867 +- getoptarg (optarg, 'e', &input_tab_char, 72.1868 +- &chars_per_input_tab); 72.1869 ++ { 72.1870 ++ int dummy_length, dummy_width; 72.1871 ++ 72.1872 ++ getoptarg (optarg, 'e', input_tab_char, &dummy_length, 72.1873 ++ &dummy_width, &chars_per_input_tab); 72.1874 ++ } 72.1875 + /* Could check tab width > 0. */ 72.1876 + untabify_input = true; 72.1877 + break; 72.1878 +@@ -953,8 +1032,12 @@ main (int argc, char **argv) 72.1879 + break; 72.1880 + case 'i': 72.1881 + if (optarg) 72.1882 +- getoptarg (optarg, 'i', &output_tab_char, 72.1883 +- &chars_per_output_tab); 72.1884 ++ { 72.1885 ++ int dummy_width; 72.1886 ++ 72.1887 ++ getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length, 72.1888 ++ &dummy_width, &chars_per_output_tab); 72.1889 ++ } 72.1890 + /* Could check tab width > 0. */ 72.1891 + tabify_output = true; 72.1892 + break; 72.1893 +@@ -972,8 +1055,8 @@ main (int argc, char **argv) 72.1894 + case 'n': 72.1895 + numbered_lines = true; 72.1896 + if (optarg) 72.1897 +- getoptarg (optarg, 'n', &number_separator, 72.1898 +- &chars_per_number); 72.1899 ++ getoptarg (optarg, 'n', number_separator, &number_separator_length, 72.1900 ++ &number_separator_width, &chars_per_number); 72.1901 + break; 72.1902 + case 'N': 72.1903 + skip_count = false; 72.1904 +@@ -997,7 +1080,7 @@ main (int argc, char **argv) 72.1905 + old_s = false; 72.1906 + /* Reset an additional input of -s, -S dominates -s */ 72.1907 + col_sep_string = bad_cast (""); 72.1908 +- col_sep_length = 0; 72.1909 ++ col_sep_length = col_sep_width = 0; 72.1910 + use_col_separator = true; 72.1911 + if (optarg) 72.1912 + separator_string (optarg); 72.1913 +@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, i 72.1914 + a number. */ 72.1915 + 72.1916 + static void 72.1917 +-getoptarg (char *arg, char switch_char, char *character, int *number) 72.1918 ++getoptarg (char *arg, char switch_char, char *character, int *character_length, 72.1919 ++ int *character_width, int *number) 72.1920 + { 72.1921 + if (!ISDIGIT (*arg)) 72.1922 +- *character = *arg++; 72.1923 ++ { 72.1924 ++#ifdef HAVE_MBRTOWC 72.1925 ++ if (MB_CUR_MAX > 1) /* for multibyte locale. */ 72.1926 ++ { 72.1927 ++ wchar_t wc; 72.1928 ++ size_t mblength; 72.1929 ++ int width; 72.1930 ++ mbstate_t state = {'\0'}; 72.1931 ++ 72.1932 ++ mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state); 72.1933 ++ 72.1934 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 72.1935 ++ { 72.1936 ++ *character_length = 1; 72.1937 ++ *character_width = 1; 72.1938 ++ } 72.1939 ++ else 72.1940 ++ { 72.1941 ++ *character_length = (mblength < 1) ? 1 : mblength; 72.1942 ++ width = wcwidth (wc); 72.1943 ++ *character_width = (width < 0) ? 0 : width; 72.1944 ++ } 72.1945 ++ 72.1946 ++ strncpy (character, arg, *character_length); 72.1947 ++ arg += *character_length; 72.1948 ++ } 72.1949 ++ else /* for single byte locale. */ 72.1950 ++#endif 72.1951 ++ { 72.1952 ++ *character = *arg++; 72.1953 ++ *character_length = 1; 72.1954 ++ *character_width = 1; 72.1955 ++ } 72.1956 ++ } 72.1957 ++ 72.1958 + if (*arg) 72.1959 + { 72.1960 + long int tmp_long; 72.1961 +@@ -1177,6 +1295,11 @@ static void 72.1962 + init_parameters (int number_of_files) 72.1963 + { 72.1964 + int chars_used_by_number = 0; 72.1965 ++ int mb_len = 1; 72.1966 ++#if HAVE_MBRTOWC 72.1967 ++ if (MB_CUR_MAX > 1) 72.1968 ++ mb_len = MB_LEN_MAX; 72.1969 ++#endif 72.1970 + 72.1971 + lines_per_body = lines_per_page - lines_per_header - lines_per_footer; 72.1972 + if (lines_per_body <= 0) 72.1973 +@@ -1214,7 +1337,7 @@ init_parameters (int number_of_files) 72.1974 + else 72.1975 + col_sep_string = column_separator; 72.1976 + 72.1977 +- col_sep_length = 1; 72.1978 ++ col_sep_length = col_sep_width = 1; 72.1979 + use_col_separator = true; 72.1980 + } 72.1981 + /* It's rather pointless to define a TAB separator with column 72.1982 +@@ -1244,11 +1367,11 @@ init_parameters (int number_of_files) 72.1983 + + TAB_WIDTH (chars_per_input_tab, chars_per_number); */ 72.1984 + 72.1985 + /* Estimate chars_per_text without any margin and keep it constant. */ 72.1986 +- if (number_separator == '\t') 72.1987 ++ if (number_separator[0] == '\t') 72.1988 + number_width = (chars_per_number 72.1989 + + TAB_WIDTH (chars_per_default_tab, chars_per_number)); 72.1990 + else 72.1991 +- number_width = chars_per_number + 1; 72.1992 ++ number_width = chars_per_number + number_separator_width; 72.1993 + 72.1994 + /* The number is part of the column width unless we are 72.1995 + printing files in parallel. */ 72.1996 +@@ -1257,7 +1380,7 @@ init_parameters (int number_of_files) 72.1997 + } 72.1998 + 72.1999 + chars_per_column = (chars_per_line - chars_used_by_number 72.2000 +- - (columns - 1) * col_sep_length) / columns; 72.2001 ++ - (columns - 1) * col_sep_width) / columns; 72.2002 + 72.2003 + if (chars_per_column < 1) 72.2004 + error (EXIT_FAILURE, 0, _("page width too narrow")); 72.2005 +@@ -1275,7 +1398,7 @@ init_parameters (int number_of_files) 72.2006 + We've to use 8 as the lower limit, if we use chars_per_default_tab = 8 72.2007 + to expand a tab which is not an input_tab-char. */ 72.2008 + free (clump_buff); 72.2009 +- clump_buff = xmalloc (MAX (8, chars_per_input_tab)); 72.2010 ++ clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab)); 72.2011 + } 72.2012 + 72.2013 + /* Open the necessary files, 72.2014 +@@ -1383,7 +1506,7 @@ init_funcs (void) 72.2015 + 72.2016 + /* Enlarge p->start_position of first column to use the same form of 72.2017 + padding_not_printed with all columns. */ 72.2018 +- h = h + col_sep_length; 72.2019 ++ h = h + col_sep_width; 72.2020 + 72.2021 + /* This loop takes care of all but the rightmost column. */ 72.2022 + 72.2023 +@@ -1417,7 +1540,7 @@ init_funcs (void) 72.2024 + } 72.2025 + else 72.2026 + { 72.2027 +- h = h_next + col_sep_length; 72.2028 ++ h = h_next + col_sep_width; 72.2029 + h_next = h + chars_per_column; 72.2030 + } 72.2031 + } 72.2032 +@@ -1708,9 +1831,9 @@ static void 72.2033 + align_column (COLUMN *p) 72.2034 + { 72.2035 + padding_not_printed = p->start_position; 72.2036 +- if (padding_not_printed - col_sep_length > 0) 72.2037 ++ if (padding_not_printed - col_sep_width > 0) 72.2038 + { 72.2039 +- pad_across_to (padding_not_printed - col_sep_length); 72.2040 ++ pad_across_to (padding_not_printed - col_sep_width); 72.2041 + padding_not_printed = ANYWHERE; 72.2042 + } 72.2043 + 72.2044 +@@ -1981,13 +2104,13 @@ store_char (char c) 72.2045 + /* May be too generous. */ 72.2046 + buff = X2REALLOC (buff, &buff_allocated); 72.2047 + } 72.2048 +- buff[buff_current++] = c; 72.2049 ++ buff[buff_current++] = (unsigned char) c; 72.2050 + } 72.2051 + 72.2052 + static void 72.2053 + add_line_number (COLUMN *p) 72.2054 + { 72.2055 +- int i; 72.2056 ++ int i, j; 72.2057 + char *s; 72.2058 + int num_width; 72.2059 + 72.2060 +@@ -2004,22 +2127,24 @@ add_line_number (COLUMN *p) 72.2061 + /* Tabification is assumed for multiple columns, also for n-separators, 72.2062 + but 'default n-separator = TAB' hasn't been given priority over 72.2063 + equal column_width also specified by POSIX. */ 72.2064 +- if (number_separator == '\t') 72.2065 ++ if (number_separator[0] == '\t') 72.2066 + { 72.2067 + i = number_width - chars_per_number; 72.2068 + while (i-- > 0) 72.2069 + (p->char_func) (' '); 72.2070 + } 72.2071 + else 72.2072 +- (p->char_func) (number_separator); 72.2073 ++ for (j = 0; j < number_separator_length; j++) 72.2074 ++ (p->char_func) (number_separator[j]); 72.2075 + } 72.2076 + else 72.2077 + /* To comply with POSIX, we avoid any expansion of default TAB 72.2078 + separator with a single column output. No column_width requirement 72.2079 + has to be considered. */ 72.2080 + { 72.2081 +- (p->char_func) (number_separator); 72.2082 +- if (number_separator == '\t') 72.2083 ++ for (j = 0; j < number_separator_length; j++) 72.2084 ++ (p->char_func) (number_separator[j]); 72.2085 ++ if (number_separator[0] == '\t') 72.2086 + output_position = POS_AFTER_TAB (chars_per_output_tab, 72.2087 + output_position); 72.2088 + } 72.2089 +@@ -2180,7 +2305,7 @@ print_white_space (void) 72.2090 + while (goal - h_old > 1 72.2091 + && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) 72.2092 + { 72.2093 +- putchar (output_tab_char); 72.2094 ++ fwrite (output_tab_char, sizeof(char), output_tab_char_length, stdout); 72.2095 + h_old = h_new; 72.2096 + } 72.2097 + while (++h_old <= goal) 72.2098 +@@ -2200,6 +2325,7 @@ print_sep_string (void) 72.2099 + { 72.2100 + char *s; 72.2101 + int l = col_sep_length; 72.2102 ++ int not_space_flag; 72.2103 + 72.2104 + s = col_sep_string; 72.2105 + 72.2106 +@@ -2213,6 +2339,7 @@ print_sep_string (void) 72.2107 + { 72.2108 + for (; separators_not_printed > 0; --separators_not_printed) 72.2109 + { 72.2110 ++ not_space_flag = 0; 72.2111 + while (l-- > 0) 72.2112 + { 72.2113 + /* 3 types of sep_strings: spaces only, spaces and chars, 72.2114 +@@ -2226,12 +2353,15 @@ print_sep_string (void) 72.2115 + } 72.2116 + else 72.2117 + { 72.2118 ++ not_space_flag = 1; 72.2119 + if (spaces_not_printed > 0) 72.2120 + print_white_space (); 72.2121 + putchar (*s++); 72.2122 +- ++output_position; 72.2123 + } 72.2124 + } 72.2125 ++ if (not_space_flag) 72.2126 ++ output_position += col_sep_width; 72.2127 ++ 72.2128 + /* sep_string ends with some spaces */ 72.2129 + if (spaces_not_printed > 0) 72.2130 + print_white_space (); 72.2131 +@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clu 72.2132 + required number of tabs and spaces. */ 72.2133 + 72.2134 + static void 72.2135 +-print_char (char c) 72.2136 ++print_char_single (char c) 72.2137 + { 72.2138 + if (tabify_output) 72.2139 + { 72.2140 +@@ -2283,6 +2413,74 @@ print_char (char c) 72.2141 + putchar (c); 72.2142 + } 72.2143 + 72.2144 ++#ifdef HAVE_MBRTOWC 72.2145 ++static void 72.2146 ++print_char_multi (char c) 72.2147 ++{ 72.2148 ++ static size_t mbc_pos = 0; 72.2149 ++ static char mbc[MB_LEN_MAX] = {'\0'}; 72.2150 ++ static mbstate_t state = {'\0'}; 72.2151 ++ mbstate_t state_bak; 72.2152 ++ wchar_t wc; 72.2153 ++ size_t mblength; 72.2154 ++ int width; 72.2155 ++ 72.2156 ++ if (tabify_output) 72.2157 ++ { 72.2158 ++ state_bak = state; 72.2159 ++ mbc[mbc_pos++] = c; 72.2160 ++ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); 72.2161 ++ 72.2162 ++ while (mbc_pos > 0) 72.2163 ++ { 72.2164 ++ switch (mblength) 72.2165 ++ { 72.2166 ++ case (size_t)-2: 72.2167 ++ state = state_bak; 72.2168 ++ return; 72.2169 ++ 72.2170 ++ case (size_t)-1: 72.2171 ++ state = state_bak; 72.2172 ++ ++output_position; 72.2173 ++ putchar (mbc[0]); 72.2174 ++ memmove (mbc, mbc + 1, MB_CUR_MAX - 1); 72.2175 ++ --mbc_pos; 72.2176 ++ break; 72.2177 ++ 72.2178 ++ case 0: 72.2179 ++ mblength = 1; 72.2180 ++ 72.2181 ++ default: 72.2182 ++ if (wc == L' ') 72.2183 ++ { 72.2184 ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 72.2185 ++ --mbc_pos; 72.2186 ++ ++spaces_not_printed; 72.2187 ++ return; 72.2188 ++ } 72.2189 ++ else if (spaces_not_printed > 0) 72.2190 ++ print_white_space (); 72.2191 ++ 72.2192 ++ /* Nonprintables are assumed to have width 0, except L'\b'. */ 72.2193 ++ if ((width = wcwidth (wc)) < 1) 72.2194 ++ { 72.2195 ++ if (wc == L'\b') 72.2196 ++ --output_position; 72.2197 ++ } 72.2198 ++ else 72.2199 ++ output_position += width; 72.2200 ++ 72.2201 ++ fwrite (mbc, sizeof(char), mblength, stdout); 72.2202 ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 72.2203 ++ mbc_pos -= mblength; 72.2204 ++ } 72.2205 ++ } 72.2206 ++ return; 72.2207 ++ } 72.2208 ++ putchar (c); 72.2209 ++} 72.2210 ++#endif 72.2211 ++ 72.2212 + /* Skip to page PAGE before printing. 72.2213 + PAGE may be larger than total number of pages. */ 72.2214 + 72.2215 +@@ -2462,9 +2660,9 @@ read_line (COLUMN *p) 72.2216 + align_empty_cols = false; 72.2217 + } 72.2218 + 72.2219 +- if (padding_not_printed - col_sep_length > 0) 72.2220 ++ if (padding_not_printed - col_sep_width > 0) 72.2221 + { 72.2222 +- pad_across_to (padding_not_printed - col_sep_length); 72.2223 ++ pad_across_to (padding_not_printed - col_sep_width); 72.2224 + padding_not_printed = ANYWHERE; 72.2225 + } 72.2226 + 72.2227 +@@ -2534,7 +2732,7 @@ print_stored (COLUMN *p) 72.2228 + int i; 72.2229 + 72.2230 + int line = p->current_line++; 72.2231 +- char *first = &buff[line_vector[line]]; 72.2232 ++ unsigned char *first = &buff[line_vector[line]]; 72.2233 + /* FIXME 72.2234 + UMR: Uninitialized memory read: 72.2235 + * This is occurring while in: 72.2236 +@@ -2546,7 +2744,7 @@ print_stored (COLUMN *p) 72.2237 + xmalloc [xmalloc.c:94] 72.2238 + init_store_cols [pr.c:1648] 72.2239 + */ 72.2240 +- char *last = &buff[line_vector[line + 1]]; 72.2241 ++ unsigned char *last = &buff[line_vector[line + 1]]; 72.2242 + 72.2243 + pad_vertically = true; 72.2244 + 72.2245 +@@ -2565,9 +2763,9 @@ print_stored (COLUMN *p) 72.2246 + } 72.2247 + } 72.2248 + 72.2249 +- if (padding_not_printed - col_sep_length > 0) 72.2250 ++ if (padding_not_printed - col_sep_width > 0) 72.2251 + { 72.2252 +- pad_across_to (padding_not_printed - col_sep_length); 72.2253 ++ pad_across_to (padding_not_printed - col_sep_width); 72.2254 + padding_not_printed = ANYWHERE; 72.2255 + } 72.2256 + 72.2257 +@@ -2580,8 +2778,8 @@ print_stored (COLUMN *p) 72.2258 + if (spaces_not_printed == 0) 72.2259 + { 72.2260 + output_position = p->start_position + end_vector[line]; 72.2261 +- if (p->start_position - col_sep_length == chars_per_margin) 72.2262 +- output_position -= col_sep_length; 72.2263 ++ if (p->start_position - col_sep_width == chars_per_margin) 72.2264 ++ output_position -= col_sep_width; 72.2265 + } 72.2266 + 72.2267 + return true; 72.2268 +@@ -2600,7 +2798,7 @@ print_stored (COLUMN *p) 72.2269 + number of characters is 1.) */ 72.2270 + 72.2271 + static int 72.2272 +-char_to_clump (char c) 72.2273 ++char_to_clump_single (char c) 72.2274 + { 72.2275 + unsigned char uc = c; 72.2276 + char *s = clump_buff; 72.2277 +@@ -2610,10 +2808,10 @@ char_to_clump (char c) 72.2278 + int chars; 72.2279 + int chars_per_c = 8; 72.2280 + 72.2281 +- if (c == input_tab_char) 72.2282 ++ if (c == input_tab_char[0]) 72.2283 + chars_per_c = chars_per_input_tab; 72.2284 + 72.2285 +- if (c == input_tab_char || c == '\t') 72.2286 ++ if (c == input_tab_char[0] || c == '\t') 72.2287 + { 72.2288 + width = TAB_WIDTH (chars_per_c, input_position); 72.2289 + 72.2290 +@@ -2694,6 +2892,164 @@ char_to_clump (char c) 72.2291 + return chars; 72.2292 + } 72.2293 + 72.2294 ++#ifdef HAVE_MBRTOWC 72.2295 ++static int 72.2296 ++char_to_clump_multi (char c) 72.2297 ++{ 72.2298 ++ static size_t mbc_pos = 0; 72.2299 ++ static char mbc[MB_LEN_MAX] = {'\0'}; 72.2300 ++ static mbstate_t state = {'\0'}; 72.2301 ++ mbstate_t state_bak; 72.2302 ++ wchar_t wc; 72.2303 ++ size_t mblength; 72.2304 ++ int wc_width; 72.2305 ++ register char *s = clump_buff; 72.2306 ++ register int i, j; 72.2307 ++ char esc_buff[4]; 72.2308 ++ int width; 72.2309 ++ int chars; 72.2310 ++ int chars_per_c = 8; 72.2311 ++ 72.2312 ++ state_bak = state; 72.2313 ++ mbc[mbc_pos++] = c; 72.2314 ++ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); 72.2315 ++ 72.2316 ++ width = 0; 72.2317 ++ chars = 0; 72.2318 ++ while (mbc_pos > 0) 72.2319 ++ { 72.2320 ++ switch (mblength) 72.2321 ++ { 72.2322 ++ case (size_t)-2: 72.2323 ++ state = state_bak; 72.2324 ++ return 0; 72.2325 ++ 72.2326 ++ case (size_t)-1: 72.2327 ++ state = state_bak; 72.2328 ++ mblength = 1; 72.2329 ++ 72.2330 ++ if (use_esc_sequence || use_cntrl_prefix) 72.2331 ++ { 72.2332 ++ width = +4; 72.2333 ++ chars = +4; 72.2334 ++ *s++ = '\\'; 72.2335 ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[0]); 72.2336 ++ for (i = 0; i <= 2; ++i) 72.2337 ++ *s++ = (int) esc_buff[i]; 72.2338 ++ } 72.2339 ++ else 72.2340 ++ { 72.2341 ++ width += 1; 72.2342 ++ chars += 1; 72.2343 ++ *s++ = mbc[0]; 72.2344 ++ } 72.2345 ++ break; 72.2346 ++ 72.2347 ++ case 0: 72.2348 ++ mblength = 1; 72.2349 ++ /* Fall through */ 72.2350 ++ 72.2351 ++ default: 72.2352 ++ if (memcmp (mbc, input_tab_char, mblength) == 0) 72.2353 ++ chars_per_c = chars_per_input_tab; 72.2354 ++ 72.2355 ++ if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t') 72.2356 ++ { 72.2357 ++ int width_inc; 72.2358 ++ 72.2359 ++ width_inc = TAB_WIDTH (chars_per_c, input_position); 72.2360 ++ width += width_inc; 72.2361 ++ 72.2362 ++ if (untabify_input) 72.2363 ++ { 72.2364 ++ for (i = width_inc; i; --i) 72.2365 ++ *s++ = ' '; 72.2366 ++ chars += width_inc; 72.2367 ++ } 72.2368 ++ else 72.2369 ++ { 72.2370 ++ for (i = 0; i < mblength; i++) 72.2371 ++ *s++ = mbc[i]; 72.2372 ++ chars += mblength; 72.2373 ++ } 72.2374 ++ } 72.2375 ++ else if ((wc_width = wcwidth (wc)) < 1) 72.2376 ++ { 72.2377 ++ if (use_esc_sequence) 72.2378 ++ { 72.2379 ++ for (i = 0; i < mblength; i++) 72.2380 ++ { 72.2381 ++ width += 4; 72.2382 ++ chars += 4; 72.2383 ++ *s++ = '\\'; 72.2384 ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); 72.2385 ++ for (j = 0; j <= 2; ++j) 72.2386 ++ *s++ = (int) esc_buff[j]; 72.2387 ++ } 72.2388 ++ } 72.2389 ++ else if (use_cntrl_prefix) 72.2390 ++ { 72.2391 ++ if (wc < 0200) 72.2392 ++ { 72.2393 ++ width += 2; 72.2394 ++ chars += 2; 72.2395 ++ *s++ = '^'; 72.2396 ++ *s++ = wc ^ 0100; 72.2397 ++ } 72.2398 ++ else 72.2399 ++ { 72.2400 ++ for (i = 0; i < mblength; i++) 72.2401 ++ { 72.2402 ++ width += 4; 72.2403 ++ chars += 4; 72.2404 ++ *s++ = '\\'; 72.2405 ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); 72.2406 ++ for (j = 0; j <= 2; ++j) 72.2407 ++ *s++ = (int) esc_buff[j]; 72.2408 ++ } 72.2409 ++ } 72.2410 ++ } 72.2411 ++ else if (wc == L'\b') 72.2412 ++ { 72.2413 ++ width += -1; 72.2414 ++ chars += 1; 72.2415 ++ *s++ = c; 72.2416 ++ } 72.2417 ++ else 72.2418 ++ { 72.2419 ++ width += 0; 72.2420 ++ chars += mblength; 72.2421 ++ for (i = 0; i < mblength; i++) 72.2422 ++ *s++ = mbc[i]; 72.2423 ++ } 72.2424 ++ } 72.2425 ++ else 72.2426 ++ { 72.2427 ++ width += wc_width; 72.2428 ++ chars += mblength; 72.2429 ++ for (i = 0; i < mblength; i++) 72.2430 ++ *s++ = mbc[i]; 72.2431 ++ } 72.2432 ++ } 72.2433 ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 72.2434 ++ mbc_pos -= mblength; 72.2435 ++ } 72.2436 ++ 72.2437 ++ /* Too many backspaces must put us in position 0 -- never negative. */ 72.2438 ++ if (width < 0 && input_position == 0) 72.2439 ++ { 72.2440 ++ chars = 0; 72.2441 ++ input_position = 0; 72.2442 ++ } 72.2443 ++ else if (width < 0 && input_position <= -width) 72.2444 ++ input_position = 0; 72.2445 ++ else 72.2446 ++ input_position += width; 72.2447 ++ 72.2448 ++ return chars; 72.2449 ++} 72.2450 ++#endif 72.2451 ++ 72.2452 + /* We've just printed some files and need to clean up things before 72.2453 + looking for more options and printing the next batch of files. 72.2454 + 72.2455 +diff -Naurp coreutils-8.25-orig/src/sort.c coreutils-8.25/src/sort.c 72.2456 +--- coreutils-8.25-orig/src/sort.c 2016-01-16 13:09:33.000000000 -0600 72.2457 ++++ coreutils-8.25/src/sort.c 2016-02-08 19:07:10.310944648 -0600 72.2458 +@@ -29,6 +29,14 @@ 72.2459 + #include <sys/wait.h> 72.2460 + #include <signal.h> 72.2461 + #include <assert.h> 72.2462 ++#if HAVE_WCHAR_H 72.2463 ++# include <wchar.h> 72.2464 ++#endif 72.2465 ++/* Get isw* functions. */ 72.2466 ++#if HAVE_WCTYPE_H 72.2467 ++# include <wctype.h> 72.2468 ++#endif 72.2469 ++ 72.2470 + #include "system.h" 72.2471 + #include "argmatch.h" 72.2472 + #include "error.h" 72.2473 +@@ -163,14 +171,39 @@ static int decimal_point; 72.2474 + /* Thousands separator; if -1, then there isn't one. */ 72.2475 + static int thousands_sep; 72.2476 + 72.2477 ++/* True if -f is specified. */ 72.2478 ++static bool folding; 72.2479 ++ 72.2480 + /* Nonzero if the corresponding locales are hard. */ 72.2481 + static bool hard_LC_COLLATE; 72.2482 +-#if HAVE_NL_LANGINFO 72.2483 ++#if HAVE_LANGINFO_CODESET 72.2484 + static bool hard_LC_TIME; 72.2485 + #endif 72.2486 + 72.2487 + #define NONZERO(x) ((x) != 0) 72.2488 + 72.2489 ++/* get a multibyte character's byte length. */ 72.2490 ++#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE) \ 72.2491 ++ do \ 72.2492 ++ { \ 72.2493 ++ wchar_t wc; \ 72.2494 ++ mbstate_t state_bak; \ 72.2495 ++ \ 72.2496 ++ state_bak = STATE; \ 72.2497 ++ mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE); \ 72.2498 ++ \ 72.2499 ++ switch (MBLENGTH) \ 72.2500 ++ { \ 72.2501 ++ case (size_t)-1: \ 72.2502 ++ case (size_t)-2: \ 72.2503 ++ STATE = state_bak; \ 72.2504 ++ /* Fall through. */ \ 72.2505 ++ case 0: \ 72.2506 ++ MBLENGTH = 1; \ 72.2507 ++ } \ 72.2508 ++ } \ 72.2509 ++ while (0) 72.2510 ++ 72.2511 + /* The kind of blanks for '-b' to skip in various options. */ 72.2512 + enum blanktype { bl_start, bl_end, bl_both }; 72.2513 + 72.2514 +@@ -344,13 +377,11 @@ static bool reverse; 72.2515 + they were read if all keys compare equal. */ 72.2516 + static bool stable; 72.2517 + 72.2518 +-/* If TAB has this value, blanks separate fields. */ 72.2519 +-enum { TAB_DEFAULT = CHAR_MAX + 1 }; 72.2520 +- 72.2521 +-/* Tab character separating fields. If TAB_DEFAULT, then fields are 72.2522 ++/* Tab character separating fields. If tab_length is 0, then fields are 72.2523 + separated by the empty string between a non-blank character and a blank 72.2524 + character. */ 72.2525 +-static int tab = TAB_DEFAULT; 72.2526 ++static char tab[MB_LEN_MAX + 1]; 72.2527 ++static size_t tab_length = 0; 72.2528 + 72.2529 + /* Flag to remove consecutive duplicate lines from the output. 72.2530 + Only the last of a sequence of equal lines will be output. */ 72.2531 +@@ -810,6 +841,46 @@ reap_all (void) 72.2532 + reap (-1); 72.2533 + } 72.2534 + 72.2535 ++/* Function pointers. */ 72.2536 ++static void 72.2537 ++(*inittables) (void); 72.2538 ++static char * 72.2539 ++(*begfield) (const struct line*, const struct keyfield *); 72.2540 ++static char * 72.2541 ++(*limfield) (const struct line*, const struct keyfield *); 72.2542 ++static void 72.2543 ++(*skipblanks) (char **ptr, char *lim); 72.2544 ++static int 72.2545 ++(*getmonth) (char const *, size_t, char **); 72.2546 ++static int 72.2547 ++(*keycompare) (const struct line *, const struct line *); 72.2548 ++static int 72.2549 ++(*numcompare) (const char *, const char *); 72.2550 ++ 72.2551 ++/* Test for white space multibyte character. 72.2552 ++ Set LENGTH the byte length of investigated multibyte character. */ 72.2553 ++#if HAVE_MBRTOWC 72.2554 ++static int 72.2555 ++ismbblank (const char *str, size_t len, size_t *length) 72.2556 ++{ 72.2557 ++ size_t mblength; 72.2558 ++ wchar_t wc; 72.2559 ++ mbstate_t state; 72.2560 ++ 72.2561 ++ memset (&state, '\0', sizeof(mbstate_t)); 72.2562 ++ mblength = mbrtowc (&wc, str, len, &state); 72.2563 ++ 72.2564 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 72.2565 ++ { 72.2566 ++ *length = 1; 72.2567 ++ return 0; 72.2568 ++ } 72.2569 ++ 72.2570 ++ *length = (mblength < 1) ? 1 : mblength; 72.2571 ++ return iswblank (wc) || wc == '\n'; 72.2572 ++} 72.2573 ++#endif 72.2574 ++ 72.2575 + /* Clean up any remaining temporary files. */ 72.2576 + 72.2577 + static void 72.2578 +@@ -1254,7 +1325,7 @@ zaptemp (char const *name) 72.2579 + free (node); 72.2580 + } 72.2581 + 72.2582 +-#if HAVE_NL_LANGINFO 72.2583 ++#if HAVE_LANGINFO_CODESET 72.2584 + 72.2585 + static int 72.2586 + struct_month_cmp (void const *m1, void const *m2) 72.2587 +@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void c 72.2588 + /* Initialize the character class tables. */ 72.2589 + 72.2590 + static void 72.2591 +-inittables (void) 72.2592 ++inittables_uni (void) 72.2593 + { 72.2594 + size_t i; 72.2595 + 72.2596 +@@ -1281,7 +1352,7 @@ inittables (void) 72.2597 + fold_toupper[i] = toupper (i); 72.2598 + } 72.2599 + 72.2600 +-#if HAVE_NL_LANGINFO 72.2601 ++#if HAVE_LANGINFO_CODESET 72.2602 + /* If we're not in the "C" locale, read different names for months. */ 72.2603 + if (hard_LC_TIME) 72.2604 + { 72.2605 +@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char con 72.2606 + xstrtol_fatal (e, oi, c, long_options, s); 72.2607 + } 72.2608 + 72.2609 ++#if HAVE_MBRTOWC 72.2610 ++static void 72.2611 ++inittables_mb (void) 72.2612 ++{ 72.2613 ++ int i, j, k, l; 72.2614 ++ char *name, *s, *lc_time, *lc_ctype; 72.2615 ++ size_t s_len, mblength; 72.2616 ++ char mbc[MB_LEN_MAX]; 72.2617 ++ wchar_t wc, pwc; 72.2618 ++ mbstate_t state_mb, state_wc; 72.2619 ++ 72.2620 ++ lc_time = setlocale (LC_TIME, ""); 72.2621 ++ if (lc_time) 72.2622 ++ lc_time = xstrdup (lc_time); 72.2623 ++ 72.2624 ++ lc_ctype = setlocale (LC_CTYPE, ""); 72.2625 ++ if (lc_ctype) 72.2626 ++ lc_ctype = xstrdup (lc_ctype); 72.2627 ++ 72.2628 ++ if (lc_time && lc_ctype) 72.2629 ++ /* temporarily set LC_CTYPE to match LC_TIME, so that we can convert 72.2630 ++ * the names of months to upper case */ 72.2631 ++ setlocale (LC_CTYPE, lc_time); 72.2632 ++ 72.2633 ++ for (i = 0; i < MONTHS_PER_YEAR; i++) 72.2634 ++ { 72.2635 ++ s = (char *) nl_langinfo (ABMON_1 + i); 72.2636 ++ s_len = strlen (s); 72.2637 ++ monthtab[i].name = name = (char *) xmalloc (s_len + 1); 72.2638 ++ monthtab[i].val = i + 1; 72.2639 ++ 72.2640 ++ memset (&state_mb, '\0', sizeof (mbstate_t)); 72.2641 ++ memset (&state_wc, '\0', sizeof (mbstate_t)); 72.2642 ++ 72.2643 ++ for (j = 0; j < s_len;) 72.2644 ++ { 72.2645 ++ if (!ismbblank (s + j, s_len - j, &mblength)) 72.2646 ++ break; 72.2647 ++ j += mblength; 72.2648 ++ } 72.2649 ++ 72.2650 ++ for (k = 0; j < s_len;) 72.2651 ++ { 72.2652 ++ mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb); 72.2653 ++ assert (mblength != (size_t)-1 && mblength != (size_t)-2); 72.2654 ++ if (mblength == 0) 72.2655 ++ break; 72.2656 ++ 72.2657 ++ pwc = towupper (wc); 72.2658 ++ if (pwc == wc) 72.2659 ++ { 72.2660 ++ memcpy (mbc, s + j, mblength); 72.2661 ++ j += mblength; 72.2662 ++ } 72.2663 ++ else 72.2664 ++ { 72.2665 ++ j += mblength; 72.2666 ++ mblength = wcrtomb (mbc, pwc, &state_wc); 72.2667 ++ assert (mblength != (size_t)0 && mblength != (size_t)-1); 72.2668 ++ } 72.2669 ++ 72.2670 ++ for (l = 0; l < mblength; l++) 72.2671 ++ name[k++] = mbc[l]; 72.2672 ++ } 72.2673 ++ name[k] = '\0'; 72.2674 ++ } 72.2675 ++ qsort ((void *) monthtab, MONTHS_PER_YEAR, 72.2676 ++ sizeof (struct month), struct_month_cmp); 72.2677 ++ 72.2678 ++ if (lc_time && lc_ctype) 72.2679 ++ /* restore the original locales */ 72.2680 ++ setlocale (LC_CTYPE, lc_ctype); 72.2681 ++ 72.2682 ++ free (lc_ctype); 72.2683 ++ free (lc_time); 72.2684 ++} 72.2685 ++#endif 72.2686 ++ 72.2687 + /* Specify the amount of main memory to use when sorting. */ 72.2688 + static void 72.2689 + specify_sort_size (int oi, char c, char const *s) 72.2690 +@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf 72.2691 + by KEY in LINE. */ 72.2692 + 72.2693 + static char * 72.2694 +-begfield (struct line const *line, struct keyfield const *key) 72.2695 ++begfield_uni (const struct line *line, const struct keyfield *key) 72.2696 + { 72.2697 + char *ptr = line->text, *lim = ptr + line->length - 1; 72.2698 + size_t sword = key->sword; 72.2699 +@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struc 72.2700 + /* The leading field separator itself is included in a field when -t 72.2701 + is absent. */ 72.2702 + 72.2703 +- if (tab != TAB_DEFAULT) 72.2704 ++ if (tab_length) 72.2705 + while (ptr < lim && sword--) 72.2706 + { 72.2707 +- while (ptr < lim && *ptr != tab) 72.2708 ++ while (ptr < lim && *ptr != tab[0]) 72.2709 + ++ptr; 72.2710 + if (ptr < lim) 72.2711 + ++ptr; 72.2712 +@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struc 72.2713 + return ptr; 72.2714 + } 72.2715 + 72.2716 ++#if HAVE_MBRTOWC 72.2717 ++static char * 72.2718 ++begfield_mb (const struct line *line, const struct keyfield *key) 72.2719 ++{ 72.2720 ++ int i; 72.2721 ++ char *ptr = line->text, *lim = ptr + line->length - 1; 72.2722 ++ size_t sword = key->sword; 72.2723 ++ size_t schar = key->schar; 72.2724 ++ size_t mblength; 72.2725 ++ mbstate_t state; 72.2726 ++ 72.2727 ++ memset (&state, '\0', sizeof(mbstate_t)); 72.2728 ++ 72.2729 ++ if (tab_length) 72.2730 ++ while (ptr < lim && sword--) 72.2731 ++ { 72.2732 ++ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) 72.2733 ++ { 72.2734 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 72.2735 ++ ptr += mblength; 72.2736 ++ } 72.2737 ++ if (ptr < lim) 72.2738 ++ { 72.2739 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 72.2740 ++ ptr += mblength; 72.2741 ++ } 72.2742 ++ } 72.2743 ++ else 72.2744 ++ while (ptr < lim && sword--) 72.2745 ++ { 72.2746 ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 72.2747 ++ ptr += mblength; 72.2748 ++ if (ptr < lim) 72.2749 ++ { 72.2750 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 72.2751 ++ ptr += mblength; 72.2752 ++ } 72.2753 ++ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) 72.2754 ++ ptr += mblength; 72.2755 ++ } 72.2756 ++ 72.2757 ++ if (key->skipsblanks) 72.2758 ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 72.2759 ++ ptr += mblength; 72.2760 ++ 72.2761 ++ for (i = 0; i < schar; i++) 72.2762 ++ { 72.2763 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 72.2764 ++ 72.2765 ++ if (ptr + mblength > lim) 72.2766 ++ break; 72.2767 ++ else 72.2768 ++ ptr += mblength; 72.2769 ++ } 72.2770 ++ 72.2771 ++ return ptr; 72.2772 ++} 72.2773 ++#endif 72.2774 ++ 72.2775 + /* Return the limit of (a pointer to the first character after) the field 72.2776 + in LINE specified by KEY. */ 72.2777 + 72.2778 + static char * 72.2779 +-limfield (struct line const *line, struct keyfield const *key) 72.2780 ++limfield_uni (const struct line *line, const struct keyfield *key) 72.2781 + { 72.2782 + char *ptr = line->text, *lim = ptr + line->length - 1; 72.2783 + size_t eword = key->eword, echar = key->echar; 72.2784 +@@ -1653,10 +1861,10 @@ limfield (struct line const *line, struc 72.2785 + 'beginning' is the first character following the delimiting TAB. 72.2786 + Otherwise, leave PTR pointing at the first 'blank' character after 72.2787 + the preceding field. */ 72.2788 +- if (tab != TAB_DEFAULT) 72.2789 ++ if (tab_length) 72.2790 + while (ptr < lim && eword--) 72.2791 + { 72.2792 +- while (ptr < lim && *ptr != tab) 72.2793 ++ while (ptr < lim && *ptr != tab[0]) 72.2794 + ++ptr; 72.2795 + if (ptr < lim && (eword || echar)) 72.2796 + ++ptr; 72.2797 +@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struc 72.2798 + */ 72.2799 + 72.2800 + /* Make LIM point to the end of (one byte past) the current field. */ 72.2801 +- if (tab != TAB_DEFAULT) 72.2802 ++ if (tab_length) 72.2803 + { 72.2804 + char *newlim; 72.2805 +- newlim = memchr (ptr, tab, lim - ptr); 72.2806 ++ newlim = memchr (ptr, tab[0], lim - ptr); 72.2807 + if (newlim) 72.2808 + lim = newlim; 72.2809 + } 72.2810 +@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struc 72.2811 + return ptr; 72.2812 + } 72.2813 + 72.2814 ++#if HAVE_MBRTOWC 72.2815 ++static char * 72.2816 ++limfield_mb (const struct line *line, const struct keyfield *key) 72.2817 ++{ 72.2818 ++ char *ptr = line->text, *lim = ptr + line->length - 1; 72.2819 ++ size_t eword = key->eword, echar = key->echar; 72.2820 ++ int i; 72.2821 ++ size_t mblength; 72.2822 ++ mbstate_t state; 72.2823 ++ 72.2824 ++ if (echar == 0) 72.2825 ++ eword++; /* skip all of end field. */ 72.2826 ++ 72.2827 ++ memset (&state, '\0', sizeof(mbstate_t)); 72.2828 ++ 72.2829 ++ if (tab_length) 72.2830 ++ while (ptr < lim && eword--) 72.2831 ++ { 72.2832 ++ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) 72.2833 ++ { 72.2834 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 72.2835 ++ ptr += mblength; 72.2836 ++ } 72.2837 ++ if (ptr < lim && (eword | echar)) 72.2838 ++ { 72.2839 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 72.2840 ++ ptr += mblength; 72.2841 ++ } 72.2842 ++ } 72.2843 ++ else 72.2844 ++ while (ptr < lim && eword--) 72.2845 ++ { 72.2846 ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 72.2847 ++ ptr += mblength; 72.2848 ++ if (ptr < lim) 72.2849 ++ { 72.2850 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 72.2851 ++ ptr += mblength; 72.2852 ++ } 72.2853 ++ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) 72.2854 ++ ptr += mblength; 72.2855 ++ } 72.2856 ++ 72.2857 ++ 72.2858 ++# ifdef POSIX_UNSPECIFIED 72.2859 ++ /* Make LIM point to the end of (one byte past) the current field. */ 72.2860 ++ if (tab_length) 72.2861 ++ { 72.2862 ++ char *newlim, *p; 72.2863 ++ 72.2864 ++ newlim = NULL; 72.2865 ++ for (p = ptr; p < lim;) 72.2866 ++ { 72.2867 ++ if (memcmp (p, tab, tab_length) == 0) 72.2868 ++ { 72.2869 ++ newlim = p; 72.2870 ++ break; 72.2871 ++ } 72.2872 ++ 72.2873 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 72.2874 ++ p += mblength; 72.2875 ++ } 72.2876 ++ } 72.2877 ++ else 72.2878 ++ { 72.2879 ++ char *newlim; 72.2880 ++ newlim = ptr; 72.2881 ++ 72.2882 ++ while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength)) 72.2883 ++ newlim += mblength; 72.2884 ++ if (ptr < lim) 72.2885 ++ { 72.2886 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 72.2887 ++ ptr += mblength; 72.2888 ++ } 72.2889 ++ while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength)) 72.2890 ++ newlim += mblength; 72.2891 ++ lim = newlim; 72.2892 ++ } 72.2893 ++# endif 72.2894 ++ 72.2895 ++ if (echar != 0) 72.2896 ++ { 72.2897 ++ /* If we're skipping leading blanks, don't start counting characters 72.2898 ++ * until after skipping past any leading blanks. */ 72.2899 ++ if (key->skipeblanks) 72.2900 ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 72.2901 ++ ptr += mblength; 72.2902 ++ 72.2903 ++ memset (&state, '\0', sizeof(mbstate_t)); 72.2904 ++ 72.2905 ++ /* Advance PTR by ECHAR (if possible), but no further than LIM. */ 72.2906 ++ for (i = 0; i < echar; i++) 72.2907 ++ { 72.2908 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 72.2909 ++ 72.2910 ++ if (ptr + mblength > lim) 72.2911 ++ break; 72.2912 ++ else 72.2913 ++ ptr += mblength; 72.2914 ++ } 72.2915 ++ } 72.2916 ++ 72.2917 ++ return ptr; 72.2918 ++} 72.2919 ++#endif 72.2920 ++ 72.2921 ++static void 72.2922 ++skipblanks_uni (char **ptr, char *lim) 72.2923 ++{ 72.2924 ++ while (*ptr < lim && blanks[to_uchar (**ptr)]) 72.2925 ++ ++(*ptr); 72.2926 ++} 72.2927 ++ 72.2928 ++#if HAVE_MBRTOWC 72.2929 ++static void 72.2930 ++skipblanks_mb (char **ptr, char *lim) 72.2931 ++{ 72.2932 ++ size_t mblength; 72.2933 ++ while (*ptr < lim && ismbblank (*ptr, lim - *ptr, &mblength)) 72.2934 ++ (*ptr) += mblength; 72.2935 ++} 72.2936 ++#endif 72.2937 ++ 72.2938 + /* Fill BUF reading from FP, moving buf->left bytes from the end 72.2939 + of buf->buf to the beginning first. If EOF is reached and the 72.2940 + file wasn't terminated by a newline, supply one. Set up BUF's line 72.2941 +@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, c 72.2942 + else 72.2943 + { 72.2944 + if (key->skipsblanks) 72.2945 +- while (blanks[to_uchar (*line_start)]) 72.2946 +- line_start++; 72.2947 ++ { 72.2948 ++#if HAVE_MBRTOWC 72.2949 ++ if (MB_CUR_MAX > 1) 72.2950 ++ { 72.2951 ++ size_t mblength; 72.2952 ++ while (line_start < line->keylim && 72.2953 ++ ismbblank (line_start, 72.2954 ++ line->keylim - line_start, 72.2955 ++ &mblength)) 72.2956 ++ line_start += mblength; 72.2957 ++ } 72.2958 ++ else 72.2959 ++#endif 72.2960 ++ while (blanks[to_uchar (*line_start)]) 72.2961 ++ line_start++; 72.2962 ++ } 72.2963 + line->keybeg = line_start; 72.2964 + } 72.2965 + } 72.2966 +@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char co 72.2967 + hideously fast. */ 72.2968 + 72.2969 + static int 72.2970 +-numcompare (char const *a, char const *b) 72.2971 ++numcompare_uni (const char *a, const char *b) 72.2972 + { 72.2973 + while (blanks[to_uchar (*a)]) 72.2974 + a++; 72.2975 +@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b 72.2976 + return strnumcmp (a, b, decimal_point, thousands_sep); 72.2977 + } 72.2978 + 72.2979 ++#if HAVE_MBRTOWC 72.2980 ++static int 72.2981 ++numcompare_mb (const char *a, const char *b) 72.2982 ++{ 72.2983 ++ size_t mblength, len; 72.2984 ++ len = strlen (a); /* okay for UTF-8 */ 72.2985 ++ while (*a && ismbblank (a, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) 72.2986 ++ { 72.2987 ++ a += mblength; 72.2988 ++ len -= mblength; 72.2989 ++ } 72.2990 ++ len = strlen (b); /* okay for UTF-8 */ 72.2991 ++ while (*b && ismbblank (b, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) 72.2992 ++ b += mblength; 72.2993 ++ 72.2994 ++ return strnumcmp (a, b, decimal_point, thousands_sep); 72.2995 ++} 72.2996 ++#endif /* HAV_EMBRTOWC */ 72.2997 ++ 72.2998 + /* Work around a problem whereby the long double value returned by glibc's 72.2999 + strtold ("NaN", ...) contains uninitialized bits: clear all bytes of 72.3000 + A and B before calling strtold. FIXME: remove this function once 72.3001 +@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char 72.3002 + Return 0 if the name in S is not recognized. */ 72.3003 + 72.3004 + static int 72.3005 +-getmonth (char const *month, char **ea) 72.3006 ++getmonth_uni (char const *month, size_t len, char **ea) 72.3007 + { 72.3008 + size_t lo = 0; 72.3009 + size_t hi = MONTHS_PER_YEAR; 72.3010 +@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, stru 72.3011 + char saved = *lim; 72.3012 + *lim = '\0'; 72.3013 + 72.3014 +- while (blanks[to_uchar (*beg)]) 72.3015 +- beg++; 72.3016 ++ skipblanks (&beg, lim); 72.3017 + 72.3018 + char *tighter_lim = beg; 72.3019 + 72.3020 + if (lim < beg) 72.3021 + tighter_lim = lim; 72.3022 + else if (key->month) 72.3023 +- getmonth (beg, &tighter_lim); 72.3024 ++ getmonth (beg, lim-beg, &tighter_lim); 72.3025 + else if (key->general_numeric) 72.3026 + ignore_value (strtold (beg, &tighter_lim)); 72.3027 + else if (key->numeric || key->human_numeric) 72.3028 +@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gke 72.3029 + bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) 72.3030 + && !(key->schar || key->echar); 72.3031 + bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ 72.3032 +- if (!gkey_only && tab == TAB_DEFAULT && !line_offset 72.3033 ++ if (!gkey_only && !tab_length && !line_offset 72.3034 + && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) 72.3035 + || (!key->skipsblanks && key->schar) 72.3036 + || (!key->skipeblanks && key->echar))) 72.3037 +@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gke 72.3038 + error (0, 0, _("option '-r' only applies to last-resort comparison")); 72.3039 + } 72.3040 + 72.3041 ++#if HAVE_MBRTOWC 72.3042 ++static int 72.3043 ++getmonth_mb (const char *s, size_t len, char **ea) 72.3044 ++{ 72.3045 ++ char *month; 72.3046 ++ register size_t i; 72.3047 ++ register int lo = 0, hi = MONTHS_PER_YEAR, result; 72.3048 ++ char *tmp; 72.3049 ++ size_t wclength, mblength; 72.3050 ++ const char *pp; 72.3051 ++ const wchar_t *wpp; 72.3052 ++ wchar_t *month_wcs; 72.3053 ++ mbstate_t state; 72.3054 ++ 72.3055 ++ while (len > 0 && ismbblank (s, len, &mblength)) 72.3056 ++ { 72.3057 ++ s += mblength; 72.3058 ++ len -= mblength; 72.3059 ++ } 72.3060 ++ 72.3061 ++ if (len == 0) 72.3062 ++ return 0; 72.3063 ++ 72.3064 ++ if (SIZE_MAX - len < 1) 72.3065 ++ xalloc_die (); 72.3066 ++ 72.3067 ++ month = (char *) xnmalloc (len + 1, MB_CUR_MAX); 72.3068 ++ 72.3069 ++ pp = tmp = (char *) xnmalloc (len + 1, MB_CUR_MAX); 72.3070 ++ memcpy (tmp, s, len); 72.3071 ++ tmp[len] = '\0'; 72.3072 ++ wpp = month_wcs = (wchar_t *) xnmalloc (len + 1, sizeof (wchar_t)); 72.3073 ++ memset (&state, '\0', sizeof (mbstate_t)); 72.3074 ++ 72.3075 ++ wclength = mbsrtowcs (month_wcs, &pp, len + 1, &state); 72.3076 ++ if (wclength == (size_t)-1 || pp != NULL) 72.3077 ++ error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s)); 72.3078 ++ 72.3079 ++ for (i = 0; i < wclength; i++) 72.3080 ++ { 72.3081 ++ month_wcs[i] = towupper(month_wcs[i]); 72.3082 ++ if (iswblank (month_wcs[i])) 72.3083 ++ { 72.3084 ++ month_wcs[i] = L'\0'; 72.3085 ++ break; 72.3086 ++ } 72.3087 ++ } 72.3088 ++ 72.3089 ++ mblength = wcsrtombs (month, &wpp, (len + 1) * MB_CUR_MAX, &state); 72.3090 ++ assert (mblength != (-1) && wpp == NULL); 72.3091 ++ 72.3092 ++ do 72.3093 ++ { 72.3094 ++ int ix = (lo + hi) / 2; 72.3095 ++ 72.3096 ++ if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0) 72.3097 ++ hi = ix; 72.3098 ++ else 72.3099 ++ lo = ix; 72.3100 ++ } 72.3101 ++ while (hi - lo > 1); 72.3102 ++ 72.3103 ++ result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name)) 72.3104 ++ ? monthtab[lo].val : 0); 72.3105 ++ 72.3106 ++ if (ea && result) 72.3107 ++ *ea = (char*) s + strlen (monthtab[lo].name); 72.3108 ++ 72.3109 ++ free (month); 72.3110 ++ free (tmp); 72.3111 ++ free (month_wcs); 72.3112 ++ 72.3113 ++ return result; 72.3114 ++} 72.3115 ++#endif 72.3116 ++ 72.3117 + /* Compare two lines A and B trying every key in sequence until there 72.3118 + are no more keys or a difference is found. */ 72.3119 + 72.3120 + static int 72.3121 +-keycompare (struct line const *a, struct line const *b) 72.3122 ++keycompare_uni (const struct line *a, const struct line *b) 72.3123 + { 72.3124 + struct keyfield *key = keylist; 72.3125 + 72.3126 +@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct 72.3127 + else if (key->human_numeric) 72.3128 + diff = human_numcompare (ta, tb); 72.3129 + else if (key->month) 72.3130 +- diff = getmonth (ta, NULL) - getmonth (tb, NULL); 72.3131 ++ diff = getmonth (ta, tlena, NULL) - getmonth (tb, tlenb, NULL); 72.3132 + else if (key->random) 72.3133 + diff = compare_random (ta, tlena, tb, tlenb); 72.3134 + else if (key->version) 72.3135 +@@ -2695,6 +3135,211 @@ keycompare (struct line const *a, struct 72.3136 + return key->reverse ? -diff : diff; 72.3137 + } 72.3138 + 72.3139 ++#if HAVE_MBRTOWC 72.3140 ++static int 72.3141 ++keycompare_mb (const struct line *a, const struct line *b) 72.3142 ++{ 72.3143 ++ struct keyfield *key = keylist; 72.3144 ++ 72.3145 ++ /* For the first iteration only, the key positions have been 72.3146 ++ precomputed for us. */ 72.3147 ++ char *texta = a->keybeg; 72.3148 ++ char *textb = b->keybeg; 72.3149 ++ char *lima = a->keylim; 72.3150 ++ char *limb = b->keylim; 72.3151 ++ 72.3152 ++ size_t mblength_a, mblength_b; 72.3153 ++ wchar_t wc_a, wc_b; 72.3154 ++ mbstate_t state_a, state_b; 72.3155 ++ 72.3156 ++ int diff = 0; 72.3157 ++ 72.3158 ++ memset (&state_a, '\0', sizeof(mbstate_t)); 72.3159 ++ memset (&state_b, '\0', sizeof(mbstate_t)); 72.3160 ++ /* Ignore keys with start after end. */ 72.3161 ++ if (a->keybeg - a->keylim > 0) 72.3162 ++ return 0; 72.3163 ++ 72.3164 ++ 72.3165 ++ /* Ignore and/or translate chars before comparing. */ 72.3166 ++# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \ 72.3167 ++ do \ 72.3168 ++ { \ 72.3169 ++ wchar_t uwc; \ 72.3170 ++ char mbc[MB_LEN_MAX]; \ 72.3171 ++ mbstate_t state_wc; \ 72.3172 ++ \ 72.3173 ++ for (NEW_LEN = i = 0; i < LEN;) \ 72.3174 ++ { \ 72.3175 ++ mbstate_t state_bak; \ 72.3176 ++ \ 72.3177 ++ state_bak = STATE; \ 72.3178 ++ MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE); \ 72.3179 ++ \ 72.3180 ++ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1 \ 72.3181 ++ || MBLENGTH == 0) \ 72.3182 ++ { \ 72.3183 ++ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \ 72.3184 ++ STATE = state_bak; \ 72.3185 ++ if (!ignore) \ 72.3186 ++ COPY[NEW_LEN++] = TEXT[i]; \ 72.3187 ++ i++; \ 72.3188 ++ continue; \ 72.3189 ++ } \ 72.3190 ++ \ 72.3191 ++ if (ignore) \ 72.3192 ++ { \ 72.3193 ++ if ((ignore == nonprinting && !iswprint (WC)) \ 72.3194 ++ || (ignore == nondictionary \ 72.3195 ++ && !iswalnum (WC) && !iswblank (WC))) \ 72.3196 ++ { \ 72.3197 ++ i += MBLENGTH; \ 72.3198 ++ continue; \ 72.3199 ++ } \ 72.3200 ++ } \ 72.3201 ++ \ 72.3202 ++ if (translate) \ 72.3203 ++ { \ 72.3204 ++ \ 72.3205 ++ uwc = towupper(WC); \ 72.3206 ++ if (WC == uwc) \ 72.3207 ++ { \ 72.3208 ++ memcpy (mbc, TEXT + i, MBLENGTH); \ 72.3209 ++ i += MBLENGTH; \ 72.3210 ++ } \ 72.3211 ++ else \ 72.3212 ++ { \ 72.3213 ++ i += MBLENGTH; \ 72.3214 ++ WC = uwc; \ 72.3215 ++ memset (&state_wc, '\0', sizeof (mbstate_t)); \ 72.3216 ++ \ 72.3217 ++ MBLENGTH = wcrtomb (mbc, WC, &state_wc); \ 72.3218 ++ assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0); \ 72.3219 ++ } \ 72.3220 ++ \ 72.3221 ++ for (j = 0; j < MBLENGTH; j++) \ 72.3222 ++ COPY[NEW_LEN++] = mbc[j]; \ 72.3223 ++ } \ 72.3224 ++ else \ 72.3225 ++ for (j = 0; j < MBLENGTH; j++) \ 72.3226 ++ COPY[NEW_LEN++] = TEXT[i++]; \ 72.3227 ++ } \ 72.3228 ++ COPY[NEW_LEN] = '\0'; \ 72.3229 ++ } \ 72.3230 ++ while (0) 72.3231 ++ 72.3232 ++ /* Actually compare the fields. */ 72.3233 ++ 72.3234 ++ for (;;) 72.3235 ++ { 72.3236 ++ /* Find the lengths. */ 72.3237 ++ size_t lena = lima <= texta ? 0 : lima - texta; 72.3238 ++ size_t lenb = limb <= textb ? 0 : limb - textb; 72.3239 ++ 72.3240 ++ char enda IF_LINT (= 0); 72.3241 ++ char endb IF_LINT (= 0); 72.3242 ++ 72.3243 ++ char const *translate = key->translate; 72.3244 ++ bool const *ignore = key->ignore; 72.3245 ++ 72.3246 ++ if (ignore || translate) 72.3247 ++ { 72.3248 ++ if (SIZE_MAX - lenb - 2 < lena) 72.3249 ++ xalloc_die (); 72.3250 ++ char *copy_a = (char *) xnmalloc (lena + lenb + 2, MB_CUR_MAX); 72.3251 ++ char *copy_b = copy_a + lena * MB_CUR_MAX + 1; 72.3252 ++ size_t new_len_a, new_len_b; 72.3253 ++ size_t i, j; 72.3254 ++ 72.3255 ++ IGNORE_CHARS (new_len_a, lena, texta, copy_a, 72.3256 ++ wc_a, mblength_a, state_a); 72.3257 ++ IGNORE_CHARS (new_len_b, lenb, textb, copy_b, 72.3258 ++ wc_b, mblength_b, state_b); 72.3259 ++ texta = copy_a; textb = copy_b; 72.3260 ++ lena = new_len_a; lenb = new_len_b; 72.3261 ++ } 72.3262 ++ else 72.3263 ++ { 72.3264 ++ /* Use the keys in-place, temporarily null-terminated. */ 72.3265 ++ enda = texta[lena]; texta[lena] = '\0'; 72.3266 ++ endb = textb[lenb]; textb[lenb] = '\0'; 72.3267 ++ } 72.3268 ++ 72.3269 ++ if (key->random) 72.3270 ++ diff = compare_random (texta, lena, textb, lenb); 72.3271 ++ else if (key->numeric | key->general_numeric | key->human_numeric) 72.3272 ++ { 72.3273 ++ char savea = *lima, saveb = *limb; 72.3274 ++ 72.3275 ++ *lima = *limb = '\0'; 72.3276 ++ diff = (key->numeric ? numcompare (texta, textb) 72.3277 ++ : key->general_numeric ? general_numcompare (texta, textb) 72.3278 ++ : human_numcompare (texta, textb)); 72.3279 ++ *lima = savea, *limb = saveb; 72.3280 ++ } 72.3281 ++ else if (key->version) 72.3282 ++ diff = filevercmp (texta, textb); 72.3283 ++ else if (key->month) 72.3284 ++ diff = getmonth (texta, lena, NULL) - getmonth (textb, lenb, NULL); 72.3285 ++ else if (lena == 0) 72.3286 ++ diff = - NONZERO (lenb); 72.3287 ++ else if (lenb == 0) 72.3288 ++ diff = 1; 72.3289 ++ else if (hard_LC_COLLATE && !folding) 72.3290 ++ { 72.3291 ++ diff = xmemcoll0 (texta, lena + 1, textb, lenb + 1); 72.3292 ++ } 72.3293 ++ else 72.3294 ++ { 72.3295 ++ diff = memcmp (texta, textb, MIN (lena, lenb)); 72.3296 ++ if (diff == 0) 72.3297 ++ diff = lena < lenb ? -1 : lena != lenb; 72.3298 ++ } 72.3299 ++ 72.3300 ++ if (ignore || translate) 72.3301 ++ free (texta); 72.3302 ++ else 72.3303 ++ { 72.3304 ++ texta[lena] = enda; 72.3305 ++ textb[lenb] = endb; 72.3306 ++ } 72.3307 ++ 72.3308 ++ if (diff) 72.3309 ++ goto not_equal; 72.3310 ++ 72.3311 ++ key = key->next; 72.3312 ++ if (! key) 72.3313 ++ break; 72.3314 ++ 72.3315 ++ /* Find the beginning and limit of the next field. */ 72.3316 ++ if (key->eword != -1) 72.3317 ++ lima = limfield (a, key), limb = limfield (b, key); 72.3318 ++ else 72.3319 ++ lima = a->text + a->length - 1, limb = b->text + b->length - 1; 72.3320 ++ 72.3321 ++ if (key->sword != -1) 72.3322 ++ texta = begfield (a, key), textb = begfield (b, key); 72.3323 ++ else 72.3324 ++ { 72.3325 ++ texta = a->text, textb = b->text; 72.3326 ++ if (key->skipsblanks) 72.3327 ++ { 72.3328 ++ while (texta < lima && ismbblank (texta, lima - texta, &mblength_a)) 72.3329 ++ texta += mblength_a; 72.3330 ++ while (textb < limb && ismbblank (textb, limb - textb, &mblength_b)) 72.3331 ++ textb += mblength_b; 72.3332 ++ } 72.3333 ++ } 72.3334 ++ } 72.3335 ++ 72.3336 ++not_equal: 72.3337 ++ if (key && key->reverse) 72.3338 ++ return -diff; 72.3339 ++ else 72.3340 ++ return diff; 72.3341 ++} 72.3342 ++#endif 72.3343 ++ 72.3344 + /* Compare two lines A and B, returning negative, zero, or positive 72.3345 + depending on whether A compares less than, equal to, or greater than B. */ 72.3346 + 72.3347 +@@ -2722,7 +3367,7 @@ compare (struct line const *a, struct li 72.3348 + diff = - NONZERO (blen); 72.3349 + else if (blen == 0) 72.3350 + diff = 1; 72.3351 +- else if (hard_LC_COLLATE) 72.3352 ++ else if (hard_LC_COLLATE && !folding) 72.3353 + { 72.3354 + /* Note xmemcoll0 is a performance enhancement as 72.3355 + it will not unconditionally write '\0' after the 72.3356 +@@ -4121,6 +4766,7 @@ set_ordering (char const *s, struct keyf 72.3357 + break; 72.3358 + case 'f': 72.3359 + key->translate = fold_toupper; 72.3360 ++ folding = true; 72.3361 + break; 72.3362 + case 'g': 72.3363 + key->general_numeric = true; 72.3364 +@@ -4199,7 +4845,7 @@ main (int argc, char **argv) 72.3365 + initialize_exit_failure (SORT_FAILURE); 72.3366 + 72.3367 + hard_LC_COLLATE = hard_locale (LC_COLLATE); 72.3368 +-#if HAVE_NL_LANGINFO 72.3369 ++#if HAVE_LANGINFO_CODESET 72.3370 + hard_LC_TIME = hard_locale (LC_TIME); 72.3371 + #endif 72.3372 + 72.3373 +@@ -4220,6 +4866,29 @@ main (int argc, char **argv) 72.3374 + thousands_sep = -1; 72.3375 + } 72.3376 + 72.3377 ++#if HAVE_MBRTOWC 72.3378 ++ if (MB_CUR_MAX > 1) 72.3379 ++ { 72.3380 ++ inittables = inittables_mb; 72.3381 ++ begfield = begfield_mb; 72.3382 ++ limfield = limfield_mb; 72.3383 ++ skipblanks = skipblanks_mb; 72.3384 ++ getmonth = getmonth_mb; 72.3385 ++ keycompare = keycompare_mb; 72.3386 ++ numcompare = numcompare_mb; 72.3387 ++ } 72.3388 ++ else 72.3389 ++#endif 72.3390 ++ { 72.3391 ++ inittables = inittables_uni; 72.3392 ++ begfield = begfield_uni; 72.3393 ++ limfield = limfield_uni; 72.3394 ++ skipblanks = skipblanks_uni; 72.3395 ++ getmonth = getmonth_uni; 72.3396 ++ keycompare = keycompare_uni; 72.3397 ++ numcompare = numcompare_uni; 72.3398 ++ } 72.3399 ++ 72.3400 + have_read_stdin = false; 72.3401 + inittables (); 72.3402 + 72.3403 +@@ -4494,13 +5163,34 @@ main (int argc, char **argv) 72.3404 + 72.3405 + case 't': 72.3406 + { 72.3407 +- char newtab = optarg[0]; 72.3408 +- if (! newtab) 72.3409 ++ char newtab[MB_LEN_MAX + 1]; 72.3410 ++ size_t newtab_length = 1; 72.3411 ++ strncpy (newtab, optarg, MB_LEN_MAX); 72.3412 ++ if (! newtab[0]) 72.3413 + error (SORT_FAILURE, 0, _("empty tab")); 72.3414 +- if (optarg[1]) 72.3415 ++#if HAVE_MBRTOWC 72.3416 ++ if (MB_CUR_MAX > 1) 72.3417 ++ { 72.3418 ++ wchar_t wc; 72.3419 ++ mbstate_t state; 72.3420 ++ 72.3421 ++ memset (&state, '\0', sizeof (mbstate_t)); 72.3422 ++ newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, 72.3423 ++ MB_LEN_MAX), 72.3424 ++ &state); 72.3425 ++ switch (newtab_length) 72.3426 ++ { 72.3427 ++ case (size_t) -1: 72.3428 ++ case (size_t) -2: 72.3429 ++ case 0: 72.3430 ++ newtab_length = 1; 72.3431 ++ } 72.3432 ++ } 72.3433 ++#endif 72.3434 ++ if (newtab_length == 1 && optarg[1]) 72.3435 + { 72.3436 + if (STREQ (optarg, "\\0")) 72.3437 +- newtab = '\0'; 72.3438 ++ newtab[0] = '\0'; 72.3439 + else 72.3440 + { 72.3441 + /* Provoke with 'sort -txx'. Complain about 72.3442 +@@ -4511,9 +5201,12 @@ main (int argc, char **argv) 72.3443 + quote (optarg)); 72.3444 + } 72.3445 + } 72.3446 +- if (tab != TAB_DEFAULT && tab != newtab) 72.3447 ++ if (tab_length 72.3448 ++ && (tab_length != newtab_length 72.3449 ++ || memcmp (tab, newtab, tab_length) != 0)) 72.3450 + error (SORT_FAILURE, 0, _("incompatible tabs")); 72.3451 +- tab = newtab; 72.3452 ++ memcpy (tab, newtab, newtab_length); 72.3453 ++ tab_length = newtab_length; 72.3454 + } 72.3455 + break; 72.3456 + 72.3457 +@@ -4751,12 +5444,10 @@ main (int argc, char **argv) 72.3458 + sort (files, nfiles, outfile, nthreads); 72.3459 + } 72.3460 + 72.3461 +-#ifdef lint 72.3462 + if (files_from) 72.3463 + readtokens0_free (&tok); 72.3464 + else 72.3465 + free (files); 72.3466 +-#endif 72.3467 + 72.3468 + if (have_read_stdin && fclose (stdin) == EOF) 72.3469 + die (_("close failed"), "-"); 72.3470 +diff -Naurp coreutils-8.25-orig/src/unexpand.c coreutils-8.25/src/unexpand.c 72.3471 +--- coreutils-8.25-orig/src/unexpand.c 2016-01-01 07:48:50.000000000 -0600 72.3472 ++++ coreutils-8.25/src/unexpand.c 2016-02-08 19:07:10.311944651 -0600 72.3473 +@@ -38,12 +38,29 @@ 72.3474 + #include <stdio.h> 72.3475 + #include <getopt.h> 72.3476 + #include <sys/types.h> 72.3477 ++ 72.3478 ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ 72.3479 ++#if HAVE_WCHAR_H 72.3480 ++# include <wchar.h> 72.3481 ++#endif 72.3482 ++ 72.3483 + #include "system.h" 72.3484 + #include "error.h" 72.3485 + #include "fadvise.h" 72.3486 + #include "quote.h" 72.3487 + #include "xstrndup.h" 72.3488 + 72.3489 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 72.3490 ++ installation; work around this configuration error. */ 72.3491 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 72.3492 ++# define MB_LEN_MAX 16 72.3493 ++#endif 72.3494 ++ 72.3495 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 72.3496 ++#if HAVE_MBRTOWC && defined mbstate_t 72.3497 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 72.3498 ++#endif 72.3499 ++ 72.3500 + /* The official name of this program (e.g., no 'g' prefix). */ 72.3501 + #define PROGRAM_NAME "unexpand" 72.3502 + 72.3503 +@@ -103,6 +120,210 @@ static struct option const longopts[] = 72.3504 + {NULL, 0, NULL, 0} 72.3505 + }; 72.3506 + 72.3507 ++static FILE *next_file (FILE *fp); 72.3508 ++ 72.3509 ++#if HAVE_MBRTOWC 72.3510 ++static void 72.3511 ++unexpand_multibyte (void) 72.3512 ++{ 72.3513 ++ FILE *fp; /* Input stream. */ 72.3514 ++ mbstate_t i_state; /* Current shift state of the input stream. */ 72.3515 ++ mbstate_t i_state_bak; /* Back up the I_STATE. */ 72.3516 ++ mbstate_t o_state; /* Current shift state of the output stream. */ 72.3517 ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 72.3518 ++ char *bufpos = buf; /* Next read position of BUF. */ 72.3519 ++ size_t buflen = 0; /* The length of the byte sequence in buf. */ 72.3520 ++ wint_t wc; /* A gotten wide character. */ 72.3521 ++ size_t mblength; /* The byte size of a multibyte character 72.3522 ++ which shows as same character as WC. */ 72.3523 ++ bool prev_tab = false; 72.3524 ++ 72.3525 ++ /* Index in `tab_list' of next tabstop: */ 72.3526 ++ int tab_index = 0; /* For calculating width of pending tabs. */ 72.3527 ++ int print_tab_index = 0; /* For printing as many tabs as possible. */ 72.3528 ++ unsigned int column = 0; /* Column on screen of next char. */ 72.3529 ++ int next_tab_column; /* Column the next tab stop is on. */ 72.3530 ++ int convert = 1; /* If nonzero, perform translations. */ 72.3531 ++ unsigned int pending = 0; /* Pending columns of blanks. */ 72.3532 ++ 72.3533 ++ fp = next_file ((FILE *) NULL); 72.3534 ++ if (fp == NULL) 72.3535 ++ return; 72.3536 ++ 72.3537 ++ memset (&o_state, '\0', sizeof(mbstate_t)); 72.3538 ++ memset (&i_state, '\0', sizeof(mbstate_t)); 72.3539 ++ 72.3540 ++ for (;;) 72.3541 ++ { 72.3542 ++ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) 72.3543 ++ { 72.3544 ++ memmove (buf, bufpos, buflen); 72.3545 ++ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); 72.3546 ++ bufpos = buf; 72.3547 ++ } 72.3548 ++ 72.3549 ++ /* Get a wide character. */ 72.3550 ++ if (buflen < 1) 72.3551 ++ { 72.3552 ++ mblength = 1; 72.3553 ++ wc = WEOF; 72.3554 ++ } 72.3555 ++ else 72.3556 ++ { 72.3557 ++ i_state_bak = i_state; 72.3558 ++ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &i_state); 72.3559 ++ } 72.3560 ++ 72.3561 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 72.3562 ++ { 72.3563 ++ i_state = i_state_bak; 72.3564 ++ wc = L'\0'; 72.3565 ++ } 72.3566 ++ 72.3567 ++ if (wc == L' ' && convert && column < INT_MAX) 72.3568 ++ { 72.3569 ++ ++pending; 72.3570 ++ ++column; 72.3571 ++ } 72.3572 ++ else if (wc == L'\t' && convert) 72.3573 ++ { 72.3574 ++ if (tab_size == 0) 72.3575 ++ { 72.3576 ++ /* Do not let tab_index == first_free_tab; 72.3577 ++ stop when it is 1 less. */ 72.3578 ++ while (tab_index < first_free_tab - 1 72.3579 ++ && column >= tab_list[tab_index]) 72.3580 ++ tab_index++; 72.3581 ++ next_tab_column = tab_list[tab_index]; 72.3582 ++ if (tab_index < first_free_tab - 1) 72.3583 ++ tab_index++; 72.3584 ++ if (column >= next_tab_column) 72.3585 ++ { 72.3586 ++ convert = 0; /* Ran out of tab stops. */ 72.3587 ++ goto flush_pend_mb; 72.3588 ++ } 72.3589 ++ } 72.3590 ++ else 72.3591 ++ { 72.3592 ++ next_tab_column = column + tab_size - column % tab_size; 72.3593 ++ } 72.3594 ++ pending += next_tab_column - column; 72.3595 ++ column = next_tab_column; 72.3596 ++ } 72.3597 ++ else 72.3598 ++ { 72.3599 ++flush_pend_mb: 72.3600 ++ /* Flush pending spaces. Print as many tabs as possible, 72.3601 ++ then print the rest as spaces. */ 72.3602 ++ if (pending == 1 && column != 1 && !prev_tab) 72.3603 ++ { 72.3604 ++ putchar (' '); 72.3605 ++ pending = 0; 72.3606 ++ } 72.3607 ++ column -= pending; 72.3608 ++ while (pending > 0) 72.3609 ++ { 72.3610 ++ if (tab_size == 0) 72.3611 ++ { 72.3612 ++ /* Do not let print_tab_index == first_free_tab; 72.3613 ++ stop when it is 1 less. */ 72.3614 ++ while (print_tab_index < first_free_tab - 1 72.3615 ++ && column >= tab_list[print_tab_index]) 72.3616 ++ print_tab_index++; 72.3617 ++ next_tab_column = tab_list[print_tab_index]; 72.3618 ++ if (print_tab_index < first_free_tab - 1) 72.3619 ++ print_tab_index++; 72.3620 ++ } 72.3621 ++ else 72.3622 ++ { 72.3623 ++ next_tab_column = 72.3624 ++ column + tab_size - column % tab_size; 72.3625 ++ } 72.3626 ++ if (next_tab_column - column <= pending) 72.3627 ++ { 72.3628 ++ putchar ('\t'); 72.3629 ++ pending -= next_tab_column - column; 72.3630 ++ column = next_tab_column; 72.3631 ++ } 72.3632 ++ else 72.3633 ++ { 72.3634 ++ --print_tab_index; 72.3635 ++ column += pending; 72.3636 ++ while (pending != 0) 72.3637 ++ { 72.3638 ++ putchar (' '); 72.3639 ++ pending--; 72.3640 ++ } 72.3641 ++ } 72.3642 ++ } 72.3643 ++ 72.3644 ++ if (wc == WEOF) 72.3645 ++ { 72.3646 ++ fp = next_file (fp); 72.3647 ++ if (fp == NULL) 72.3648 ++ break; /* No more files. */ 72.3649 ++ else 72.3650 ++ { 72.3651 ++ memset (&i_state, '\0', sizeof(mbstate_t)); 72.3652 ++ continue; 72.3653 ++ } 72.3654 ++ } 72.3655 ++ 72.3656 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 72.3657 ++ { 72.3658 ++ if (convert) 72.3659 ++ { 72.3660 ++ ++column; 72.3661 ++ if (convert_entire_line == 0) 72.3662 ++ convert = 0; 72.3663 ++ } 72.3664 ++ mblength = 1; 72.3665 ++ putchar (buf[0]); 72.3666 ++ } 72.3667 ++ else if (mblength == 0) 72.3668 ++ { 72.3669 ++ if (convert && convert_entire_line == 0) 72.3670 ++ convert = 0; 72.3671 ++ mblength = 1; 72.3672 ++ putchar ('\0'); 72.3673 ++ } 72.3674 ++ else 72.3675 ++ { 72.3676 ++ if (convert) 72.3677 ++ { 72.3678 ++ if (wc == L'\b') 72.3679 ++ { 72.3680 ++ if (column > 0) 72.3681 ++ --column; 72.3682 ++ } 72.3683 ++ else 72.3684 ++ { 72.3685 ++ int width; /* The width of WC. */ 72.3686 ++ 72.3687 ++ width = wcwidth (wc); 72.3688 ++ column += (width > 0) ? width : 0; 72.3689 ++ if (convert_entire_line == 0) 72.3690 ++ convert = 0; 72.3691 ++ } 72.3692 ++ } 72.3693 ++ 72.3694 ++ if (wc == L'\n') 72.3695 ++ { 72.3696 ++ tab_index = print_tab_index = 0; 72.3697 ++ column = pending = 0; 72.3698 ++ convert = 1; 72.3699 ++ } 72.3700 ++ fwrite (bufpos, sizeof(char), mblength, stdout); 72.3701 ++ } 72.3702 ++ } 72.3703 ++ prev_tab = wc == L'\t'; 72.3704 ++ buflen -= mblength; 72.3705 ++ bufpos += mblength; 72.3706 ++ } 72.3707 ++} 72.3708 ++#endif 72.3709 ++ 72.3710 ++ 72.3711 + void 72.3712 + usage (int status) 72.3713 + { 72.3714 +@@ -523,7 +744,12 @@ main (int argc, char **argv) 72.3715 + 72.3716 + file_list = (optind < argc ? &argv[optind] : stdin_argv); 72.3717 + 72.3718 +- unexpand (); 72.3719 ++#if HAVE_MBRTOWC 72.3720 ++ if (MB_CUR_MAX > 1) 72.3721 ++ unexpand_multibyte (); 72.3722 ++ else 72.3723 ++#endif 72.3724 ++ unexpand (); 72.3725 + 72.3726 + if (have_read_stdin && fclose (stdin) != 0) 72.3727 + error (EXIT_FAILURE, errno, "-"); 72.3728 +diff -Naurp coreutils-8.25-orig/src/uniq.c coreutils-8.25/src/uniq.c 72.3729 +--- coreutils-8.25-orig/src/uniq.c 2016-01-13 05:08:59.000000000 -0600 72.3730 ++++ coreutils-8.25/src/uniq.c 2016-02-08 19:07:10.312944654 -0600 72.3731 +@@ -21,6 +21,17 @@ 72.3732 + #include <getopt.h> 72.3733 + #include <sys/types.h> 72.3734 + 72.3735 ++/* Get mbstate_t, mbrtowc(). */ 72.3736 ++#if HAVE_WCHAR_H 72.3737 ++# include <wchar.h> 72.3738 ++#endif 72.3739 ++ 72.3740 ++/* Get isw* functions. */ 72.3741 ++#if HAVE_WCTYPE_H 72.3742 ++# include <wctype.h> 72.3743 ++#endif 72.3744 ++#include <assert.h> 72.3745 ++ 72.3746 + #include "system.h" 72.3747 + #include "argmatch.h" 72.3748 + #include "linebuffer.h" 72.3749 +@@ -33,6 +44,18 @@ 72.3750 + #include "xstrtol.h" 72.3751 + #include "memcasecmp.h" 72.3752 + #include "quote.h" 72.3753 ++#include "xmemcoll.h" 72.3754 ++ 72.3755 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 72.3756 ++ installation; work around this configuration error. */ 72.3757 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 72.3758 ++# define MB_LEN_MAX 16 72.3759 ++#endif 72.3760 ++ 72.3761 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 72.3762 ++#if HAVE_MBRTOWC && defined mbstate_t 72.3763 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 72.3764 ++#endif 72.3765 + 72.3766 + /* The official name of this program (e.g., no 'g' prefix). */ 72.3767 + #define PROGRAM_NAME "uniq" 72.3768 +@@ -143,6 +166,10 @@ enum 72.3769 + GROUP_OPTION = CHAR_MAX + 1 72.3770 + }; 72.3771 + 72.3772 ++/* Function pointers. */ 72.3773 ++static char * 72.3774 ++(*find_field) (struct linebuffer *line); 72.3775 ++ 72.3776 + static struct option const longopts[] = 72.3777 + { 72.3778 + {"count", no_argument, NULL, 'c'}, 72.3779 +@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *m 72.3780 + return a pointer to the beginning of the line's field to be compared. */ 72.3781 + 72.3782 + static char * _GL_ATTRIBUTE_PURE 72.3783 +-find_field (struct linebuffer const *line) 72.3784 ++find_field_uni (struct linebuffer *line) 72.3785 + { 72.3786 + size_t count; 72.3787 + char const *lp = line->buffer; 72.3788 +@@ -272,6 +299,83 @@ find_field (struct linebuffer const *lin 72.3789 + return line->buffer + i; 72.3790 + } 72.3791 + 72.3792 ++#if HAVE_MBRTOWC 72.3793 ++ 72.3794 ++# define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL) \ 72.3795 ++ do \ 72.3796 ++ { \ 72.3797 ++ mbstate_t state_bak; \ 72.3798 ++ \ 72.3799 ++ CONVFAIL = 0; \ 72.3800 ++ state_bak = *STATEP; \ 72.3801 ++ \ 72.3802 ++ MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP); \ 72.3803 ++ \ 72.3804 ++ switch (MBLENGTH) \ 72.3805 ++ { \ 72.3806 ++ case (size_t)-2: \ 72.3807 ++ case (size_t)-1: \ 72.3808 ++ *STATEP = state_bak; \ 72.3809 ++ CONVFAIL++; \ 72.3810 ++ /* Fall through */ \ 72.3811 ++ case 0: \ 72.3812 ++ MBLENGTH = 1; \ 72.3813 ++ } \ 72.3814 ++ } \ 72.3815 ++ while (0) 72.3816 ++ 72.3817 ++static char * 72.3818 ++find_field_multi (struct linebuffer *line) 72.3819 ++{ 72.3820 ++ size_t count; 72.3821 ++ char *lp = line->buffer; 72.3822 ++ size_t size = line->length - 1; 72.3823 ++ size_t pos; 72.3824 ++ size_t mblength; 72.3825 ++ wchar_t wc; 72.3826 ++ mbstate_t *statep; 72.3827 ++ int convfail = 0; 72.3828 ++ 72.3829 ++ pos = 0; 72.3830 ++ statep = &(line->state); 72.3831 ++ 72.3832 ++ /* skip fields. */ 72.3833 ++ for (count = 0; count < skip_fields && pos < size; count++) 72.3834 ++ { 72.3835 ++ while (pos < size) 72.3836 ++ { 72.3837 ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 72.3838 ++ 72.3839 ++ if (convfail || !(iswblank (wc) || wc == '\n')) 72.3840 ++ { 72.3841 ++ pos += mblength; 72.3842 ++ break; 72.3843 ++ } 72.3844 ++ pos += mblength; 72.3845 ++ } 72.3846 ++ 72.3847 ++ while (pos < size) 72.3848 ++ { 72.3849 ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 72.3850 ++ 72.3851 ++ if (!convfail && (iswblank (wc) || wc == '\n')) 72.3852 ++ break; 72.3853 ++ 72.3854 ++ pos += mblength; 72.3855 ++ } 72.3856 ++ } 72.3857 ++ 72.3858 ++ /* skip fields. */ 72.3859 ++ for (count = 0; count < skip_chars && pos < size; count++) 72.3860 ++ { 72.3861 ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 72.3862 ++ pos += mblength; 72.3863 ++ } 72.3864 ++ 72.3865 ++ return lp + pos; 72.3866 ++} 72.3867 ++#endif 72.3868 ++ 72.3869 + /* Return false if two strings OLD and NEW match, true if not. 72.3870 + OLD and NEW point not to the beginnings of the lines 72.3871 + but rather to the beginnings of the fields to compare. 72.3872 +@@ -280,6 +384,8 @@ find_field (struct linebuffer const *lin 72.3873 + static bool 72.3874 + different (char *old, char *new, size_t oldlen, size_t newlen) 72.3875 + { 72.3876 ++ char *copy_old, *copy_new; 72.3877 ++ 72.3878 + if (check_chars < oldlen) 72.3879 + oldlen = check_chars; 72.3880 + if (check_chars < newlen) 72.3881 +@@ -287,15 +393,104 @@ different (char *old, char *new, size_t 72.3882 + 72.3883 + if (ignore_case) 72.3884 + { 72.3885 +- /* FIXME: This should invoke strcoll somehow. */ 72.3886 +- return oldlen != newlen || memcasecmp (old, new, oldlen); 72.3887 ++ size_t i; 72.3888 ++ 72.3889 ++ copy_old = xmalloc (oldlen + 1); 72.3890 ++ copy_new = xmalloc (oldlen + 1); 72.3891 ++ 72.3892 ++ for (i = 0; i < oldlen; i++) 72.3893 ++ { 72.3894 ++ copy_old[i] = toupper (old[i]); 72.3895 ++ copy_new[i] = toupper (new[i]); 72.3896 ++ } 72.3897 ++ bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen); 72.3898 ++ free (copy_old); 72.3899 ++ free (copy_new); 72.3900 ++ return rc; 72.3901 + } 72.3902 +- else if (hard_LC_COLLATE) 72.3903 +- return xmemcoll (old, oldlen, new, newlen) != 0; 72.3904 + else 72.3905 +- return oldlen != newlen || memcmp (old, new, oldlen); 72.3906 ++ { 72.3907 ++ copy_old = (char *)old; 72.3908 ++ copy_new = (char *)new; 72.3909 ++ } 72.3910 ++ 72.3911 ++ return xmemcoll (copy_old, oldlen, copy_new, newlen); 72.3912 ++ 72.3913 + } 72.3914 + 72.3915 ++#if HAVE_MBRTOWC 72.3916 ++static int 72.3917 ++different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) 72.3918 ++{ 72.3919 ++ size_t i, j, chars; 72.3920 ++ const char *str[2]; 72.3921 ++ char *copy[2]; 72.3922 ++ size_t len[2]; 72.3923 ++ mbstate_t state[2]; 72.3924 ++ size_t mblength; 72.3925 ++ wchar_t wc, uwc; 72.3926 ++ mbstate_t state_bak; 72.3927 ++ 72.3928 ++ str[0] = old; 72.3929 ++ str[1] = new; 72.3930 ++ len[0] = oldlen; 72.3931 ++ len[1] = newlen; 72.3932 ++ state[0] = oldstate; 72.3933 ++ state[1] = newstate; 72.3934 ++ 72.3935 ++ for (i = 0; i < 2; i++) 72.3936 ++ { 72.3937 ++ copy[i] = xmalloc (len[i] + 1); 72.3938 ++ memset (copy[i], '\0', len[i] + 1); 72.3939 ++ 72.3940 ++ for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) 72.3941 ++ { 72.3942 ++ state_bak = state[i]; 72.3943 ++ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); 72.3944 ++ 72.3945 ++ switch (mblength) 72.3946 ++ { 72.3947 ++ case (size_t)-1: 72.3948 ++ case (size_t)-2: 72.3949 ++ state[i] = state_bak; 72.3950 ++ /* Fall through */ 72.3951 ++ case 0: 72.3952 ++ mblength = 1; 72.3953 ++ break; 72.3954 ++ 72.3955 ++ default: 72.3956 ++ if (ignore_case) 72.3957 ++ { 72.3958 ++ uwc = towupper (wc); 72.3959 ++ 72.3960 ++ if (uwc != wc) 72.3961 ++ { 72.3962 ++ mbstate_t state_wc; 72.3963 ++ size_t mblen; 72.3964 ++ 72.3965 ++ memset (&state_wc, '\0', sizeof(mbstate_t)); 72.3966 ++ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); 72.3967 ++ assert (mblen != (size_t)-1); 72.3968 ++ } 72.3969 ++ else 72.3970 ++ memcpy (copy[i] + j, str[i] + j, mblength); 72.3971 ++ } 72.3972 ++ else 72.3973 ++ memcpy (copy[i] + j, str[i] + j, mblength); 72.3974 ++ } 72.3975 ++ j += mblength; 72.3976 ++ } 72.3977 ++ copy[i][j] = '\0'; 72.3978 ++ len[i] = j; 72.3979 ++ } 72.3980 ++ int rc = xmemcoll (copy[0], len[0], copy[1], len[1]); 72.3981 ++ free (copy[0]); 72.3982 ++ free (copy[1]); 72.3983 ++ return rc; 72.3984 ++ 72.3985 ++} 72.3986 ++#endif 72.3987 ++ 72.3988 + /* Output the line in linebuffer LINE to standard output 72.3989 + provided that the switches say it should be output. 72.3990 + MATCH is true if the line matches the previous line. 72.3991 +@@ -359,19 +554,38 @@ check_file (const char *infile, const ch 72.3992 + char *prevfield IF_LINT ( = NULL); 72.3993 + size_t prevlen IF_LINT ( = 0); 72.3994 + bool first_group_printed = false; 72.3995 ++#if HAVE_MBRTOWC 72.3996 ++ mbstate_t prevstate; 72.3997 ++ 72.3998 ++ memset (&prevstate, '\0', sizeof (mbstate_t)); 72.3999 ++#endif 72.4000 + 72.4001 + while (!feof (stdin)) 72.4002 + { 72.4003 + char *thisfield; 72.4004 + size_t thislen; 72.4005 + bool new_group; 72.4006 ++#if HAVE_MBRTOWC 72.4007 ++ mbstate_t thisstate; 72.4008 ++#endif 72.4009 + 72.4010 + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) 72.4011 + break; 72.4012 + 72.4013 + thisfield = find_field (thisline); 72.4014 + thislen = thisline->length - 1 - (thisfield - thisline->buffer); 72.4015 ++#if HAVE_MBRTOWC 72.4016 ++ if (MB_CUR_MAX > 1) 72.4017 ++ { 72.4018 ++ thisstate = thisline->state; 72.4019 + 72.4020 ++ new_group = (prevline->length == 0 72.4021 ++ || different_multi (thisfield, prevfield, 72.4022 ++ thislen, prevlen, 72.4023 ++ thisstate, prevstate)); 72.4024 ++ } 72.4025 ++ else 72.4026 ++#endif 72.4027 + new_group = (prevline->length == 0 72.4028 + || different (thisfield, prevfield, thislen, prevlen)); 72.4029 + 72.4030 +@@ -389,6 +603,10 @@ check_file (const char *infile, const ch 72.4031 + SWAP_LINES (prevline, thisline); 72.4032 + prevfield = thisfield; 72.4033 + prevlen = thislen; 72.4034 ++#if HAVE_MBRTOWC 72.4035 ++ if (MB_CUR_MAX > 1) 72.4036 ++ prevstate = thisstate; 72.4037 ++#endif 72.4038 + first_group_printed = true; 72.4039 + } 72.4040 + } 72.4041 +@@ -401,17 +619,26 @@ check_file (const char *infile, const ch 72.4042 + size_t prevlen; 72.4043 + uintmax_t match_count = 0; 72.4044 + bool first_delimiter = true; 72.4045 ++#if HAVE_MBRTOWC 72.4046 ++ mbstate_t prevstate; 72.4047 ++#endif 72.4048 + 72.4049 + if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) 72.4050 + goto closefiles; 72.4051 + prevfield = find_field (prevline); 72.4052 + prevlen = prevline->length - 1 - (prevfield - prevline->buffer); 72.4053 ++#if HAVE_MBRTOWC 72.4054 ++ prevstate = prevline->state; 72.4055 ++#endif 72.4056 + 72.4057 + while (!feof (stdin)) 72.4058 + { 72.4059 + bool match; 72.4060 + char *thisfield; 72.4061 + size_t thislen; 72.4062 ++#if HAVE_MBRTOWC 72.4063 ++ mbstate_t thisstate = thisline->state; 72.4064 ++#endif 72.4065 + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) 72.4066 + { 72.4067 + if (ferror (stdin)) 72.4068 +@@ -420,6 +647,14 @@ check_file (const char *infile, const ch 72.4069 + } 72.4070 + thisfield = find_field (thisline); 72.4071 + thislen = thisline->length - 1 - (thisfield - thisline->buffer); 72.4072 ++#if HAVE_MBRTOWC 72.4073 ++ if (MB_CUR_MAX > 1) 72.4074 ++ { 72.4075 ++ match = !different_multi (thisfield, prevfield, 72.4076 ++ thislen, prevlen, thisstate, prevstate); 72.4077 ++ } 72.4078 ++ else 72.4079 ++#endif 72.4080 + match = !different (thisfield, prevfield, thislen, prevlen); 72.4081 + match_count += match; 72.4082 + 72.4083 +@@ -452,6 +687,9 @@ check_file (const char *infile, const ch 72.4084 + SWAP_LINES (prevline, thisline); 72.4085 + prevfield = thisfield; 72.4086 + prevlen = thislen; 72.4087 ++#if HAVE_MBRTOWC 72.4088 ++ prevstate = thisstate; 72.4089 ++#endif 72.4090 + if (!match) 72.4091 + match_count = 0; 72.4092 + } 72.4093 +@@ -498,6 +736,19 @@ main (int argc, char **argv) 72.4094 + 72.4095 + atexit (close_stdout); 72.4096 + 72.4097 ++#if HAVE_MBRTOWC 72.4098 ++ if (MB_CUR_MAX > 1) 72.4099 ++ { 72.4100 ++ find_field = find_field_multi; 72.4101 ++ } 72.4102 ++ else 72.4103 ++#endif 72.4104 ++ { 72.4105 ++ find_field = find_field_uni; 72.4106 ++ } 72.4107 ++ 72.4108 ++ 72.4109 ++ 72.4110 + skip_chars = 0; 72.4111 + skip_fields = 0; 72.4112 + check_chars = SIZE_MAX; 72.4113 +diff -Naurp coreutils-8.25-orig/tests/i18n/sort-month.sh coreutils-8.25/tests/i18n/sort-month.sh 72.4114 +--- coreutils-8.25-orig/tests/i18n/sort-month.sh 1969-12-31 18:00:00.000000000 -0600 72.4115 ++++ coreutils-8.25/tests/i18n/sort-month.sh 2016-02-08 19:07:10.312944654 -0600 72.4116 +@@ -0,0 +1,34 @@ 72.4117 ++#!/bin/sh 72.4118 ++# Verify sort -M multi-byte support. 72.4119 ++ 72.4120 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 72.4121 ++print_ver_ sort 72.4122 ++require_valgrind_ 72.4123 ++ 72.4124 ++# Skip this test if some deallocations are 72.4125 ++# avoided at process end. 72.4126 ++grep '^#define lint 1' $CONFIG_HEADER > /dev/null || 72.4127 ++ skip_ 'Allocation checks only work reliably in "lint" mode' 72.4128 ++ 72.4129 ++export LC_ALL=en_US.UTF-8 72.4130 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 72.4131 ++ || skip_ "No UTF-8 locale available" 72.4132 ++ 72.4133 ++# Note the use of ɑ here which expands to 72.4134 ++# a wider representation upon case conversion 72.4135 ++# which triggered an assertion in sort -M 72.4136 ++cat <<EOF > exp 72.4137 ++. 72.4138 ++ɑ 72.4139 ++EOF 72.4140 ++ 72.4141 ++ 72.4142 ++# check large mem leak with --month-sort 72.4143 ++# https://bugzilla.redhat.com/show_bug.cgi?id=1259942 72.4144 ++valgrind --leak-check=full \ 72.4145 ++ --error-exitcode=1 --errors-for-leak-kinds=definite \ 72.4146 ++ sort -M < exp > out || fail=1 72.4147 ++compare exp out || { fail=1; cat out; } 72.4148 ++ 72.4149 ++ 72.4150 ++Exit $fail 72.4151 +diff -Naurp coreutils-8.25-orig/tests/i18n/sort.sh coreutils-8.25/tests/i18n/sort.sh 72.4152 +--- coreutils-8.25-orig/tests/i18n/sort.sh 1969-12-31 18:00:00.000000000 -0600 72.4153 ++++ coreutils-8.25/tests/i18n/sort.sh 2016-02-08 19:07:10.312944654 -0600 72.4154 +@@ -0,0 +1,29 @@ 72.4155 ++#!/bin/sh 72.4156 ++# Verify sort's multi-byte support. 72.4157 ++ 72.4158 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 72.4159 ++print_ver_ sort 72.4160 ++ 72.4161 ++export LC_ALL=en_US.UTF-8 72.4162 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 72.4163 ++ || skip_ "No UTF-8 locale available" 72.4164 ++ 72.4165 ++# Enable heap consistency checkng on older systems 72.4166 ++export MALLOC_CHECK_=2 72.4167 ++ 72.4168 ++ 72.4169 ++# check buffer overflow issue due to 72.4170 ++# expanding multi-byte representation due to case conversion 72.4171 ++# https://bugzilla.suse.com/show_bug.cgi?id=928749 72.4172 ++cat <<EOF > exp 72.4173 ++. 72.4174 ++ɑ 72.4175 ++EOF 72.4176 ++cat <<EOF | sort -f > out || fail=1 72.4177 ++. 72.4178 ++ɑ 72.4179 ++EOF 72.4180 ++compare exp out || { fail=1; cat out; } 72.4181 ++ 72.4182 ++ 72.4183 ++Exit $fail 72.4184 +diff -Naurp coreutils-8.25-orig/tests/local.mk coreutils-8.25/tests/local.mk 72.4185 +--- coreutils-8.25-orig/tests/local.mk 2016-01-16 12:18:13.000000000 -0600 72.4186 ++++ coreutils-8.25/tests/local.mk 2016-02-08 19:07:10.313944658 -0600 72.4187 +@@ -344,6 +344,9 @@ all_tests = \ 72.4188 + tests/misc/sort-discrim.sh \ 72.4189 + tests/misc/sort-files0-from.pl \ 72.4190 + tests/misc/sort-float.sh \ 72.4191 ++ tests/misc/sort-mb-tests.sh \ 72.4192 ++ tests/i18n/sort.sh \ 72.4193 ++ tests/i18n/sort-month.sh \ 72.4194 + tests/misc/sort-merge.pl \ 72.4195 + tests/misc/sort-merge-fdlimit.sh \ 72.4196 + tests/misc/sort-month.sh \ 72.4197 +diff -Naurp coreutils-8.25-orig/tests/misc/cut.pl coreutils-8.25/tests/misc/cut.pl 72.4198 +--- coreutils-8.25-orig/tests/misc/cut.pl 2016-01-16 12:18:13.000000000 -0600 72.4199 ++++ coreutils-8.25/tests/misc/cut.pl 2016-02-08 19:07:10.314944661 -0600 72.4200 +@@ -23,9 +23,11 @@ use strict; 72.4201 + # Turn off localization of executable's output. 72.4202 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 72.4203 + 72.4204 +-my $mb_locale = $ENV{LOCALE_FR_UTF8}; 72.4205 ++my $mb_locale; 72.4206 ++# uncommented enable multibyte paths 72.4207 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 72.4208 + ! defined $mb_locale || $mb_locale eq 'none' 72.4209 +- and $mb_locale = 'C'; 72.4210 ++ and $mb_locale = 'C'; 72.4211 + 72.4212 + my $prog = 'cut'; 72.4213 + my $try = "Try '$prog --help' for more information.\n"; 72.4214 +@@ -240,6 +242,7 @@ if ($mb_locale ne 'C') 72.4215 + my @new_t = @$t; 72.4216 + my $test_name = shift @new_t; 72.4217 + 72.4218 ++ next if ($test_name =~ "newline-[12][0-9]"); 72.4219 + push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 72.4220 + } 72.4221 + push @Tests, @new; 72.4222 +diff -Naurp coreutils-8.25-orig/tests/misc/expand.pl coreutils-8.25/tests/misc/expand.pl 72.4223 +--- coreutils-8.25-orig/tests/misc/expand.pl 2016-01-16 12:18:13.000000000 -0600 72.4224 ++++ coreutils-8.25/tests/misc/expand.pl 2016-02-08 19:07:10.314944661 -0600 72.4225 +@@ -23,6 +23,15 @@ use strict; 72.4226 + # Turn off localization of executable's output. 72.4227 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 72.4228 + 72.4229 ++#comment out next line to disable multibyte tests 72.4230 ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; 72.4231 ++! defined $mb_locale || $mb_locale eq 'none' 72.4232 ++ and $mb_locale = 'C'; 72.4233 ++ 72.4234 ++my $prog = 'expand'; 72.4235 ++my $try = "Try \`$prog --help' for more information.\n"; 72.4236 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 72.4237 ++ 72.4238 + my @Tests = 72.4239 + ( 72.4240 + ['t1', '--tabs=3', {IN=>"a\tb"}, {OUT=>"a b"}], 72.4241 +@@ -31,6 +40,37 @@ my @Tests = 72.4242 + ['i2', '--tabs=3 -i', {IN=>" \ta\tb"}, {OUT=>" a\tb"}], 72.4243 + ); 72.4244 + 72.4245 ++if ($mb_locale ne 'C') 72.4246 ++ { 72.4247 ++ # Duplicate each test vector, appending "-mb" to the test name and 72.4248 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 72.4249 ++ # provide coverage for the distro-added multi-byte code paths. 72.4250 ++ my @new; 72.4251 ++ foreach my $t (@Tests) 72.4252 ++ { 72.4253 ++ my @new_t = @$t; 72.4254 ++ my $test_name = shift @new_t; 72.4255 ++ 72.4256 ++ # Depending on whether expand is multi-byte-patched, 72.4257 ++ # it emits different diagnostics: 72.4258 ++ # non-MB: invalid byte or field list 72.4259 ++ # MB: invalid byte, character or field list 72.4260 ++ # Adjust the expected error output accordingly. 72.4261 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 72.4262 ++ (@new_t)) 72.4263 ++ { 72.4264 ++ my $sub = {ERR_SUBST => 's/, character//'}; 72.4265 ++ push @new_t, $sub; 72.4266 ++ push @$t, $sub; 72.4267 ++ } 72.4268 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 72.4269 ++ } 72.4270 ++ push @Tests, @new; 72.4271 ++ } 72.4272 ++ 72.4273 ++ 72.4274 ++@Tests = triple_test \@Tests; 72.4275 ++ 72.4276 + my $save_temps = $ENV{DEBUG}; 72.4277 + my $verbose = $ENV{VERBOSE}; 72.4278 + 72.4279 +diff -Naurp coreutils-8.25-orig/tests/misc/fold.pl coreutils-8.25/tests/misc/fold.pl 72.4280 +--- coreutils-8.25-orig/tests/misc/fold.pl 2016-01-16 12:18:13.000000000 -0600 72.4281 ++++ coreutils-8.25/tests/misc/fold.pl 2016-02-08 19:07:10.314944661 -0600 72.4282 +@@ -20,9 +20,18 @@ use strict; 72.4283 + 72.4284 + (my $program_name = $0) =~ s|.*/||; 72.4285 + 72.4286 ++my $prog = 'fold'; 72.4287 ++my $try = "Try \`$prog --help' for more information.\n"; 72.4288 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 72.4289 ++ 72.4290 + # Turn off localization of executable's output. 72.4291 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 72.4292 + 72.4293 ++# uncommented to enable multibyte paths 72.4294 ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; 72.4295 ++! defined $mb_locale || $mb_locale eq 'none' 72.4296 ++ and $mb_locale = 'C'; 72.4297 ++ 72.4298 + my @Tests = 72.4299 + ( 72.4300 + ['s1', '-w2 -s', {IN=>"a\t"}, {OUT=>"a\n\t"}], 72.4301 +@@ -31,9 +40,48 @@ my @Tests = 72.4302 + ['s4', '-w4 -s', {IN=>"abc ef\n"}, {OUT=>"abc \nef\n"}], 72.4303 + ); 72.4304 + 72.4305 ++# Add _POSIX2_VERSION=199209 to the environment of each test 72.4306 ++# that uses an old-style option like +1. 72.4307 ++if ($mb_locale ne 'C') 72.4308 ++ { 72.4309 ++ # Duplicate each test vector, appending "-mb" to the test name and 72.4310 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 72.4311 ++ # provide coverage for the distro-added multi-byte code paths. 72.4312 ++ my @new; 72.4313 ++ foreach my $t (@Tests) 72.4314 ++ { 72.4315 ++ my @new_t = @$t; 72.4316 ++ my $test_name = shift @new_t; 72.4317 ++ 72.4318 ++ # Depending on whether fold is multi-byte-patched, 72.4319 ++ # it emits different diagnostics: 72.4320 ++ # non-MB: invalid byte or field list 72.4321 ++ # MB: invalid byte, character or field list 72.4322 ++ # Adjust the expected error output accordingly. 72.4323 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 72.4324 ++ (@new_t)) 72.4325 ++ { 72.4326 ++ my $sub = {ERR_SUBST => 's/, character//'}; 72.4327 ++ push @new_t, $sub; 72.4328 ++ push @$t, $sub; 72.4329 ++ } 72.4330 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 72.4331 ++ } 72.4332 ++ push @Tests, @new; 72.4333 ++ } 72.4334 ++ 72.4335 ++@Tests = triple_test \@Tests; 72.4336 ++ 72.4337 ++# Remember that triple_test creates from each test with exactly one "IN" 72.4338 ++# file two more tests (.p and .r suffix on name) corresponding to reading 72.4339 ++# input from a file and from a pipe. The pipe-reading test would fail 72.4340 ++# due to a race condition about 1 in 20 times. 72.4341 ++# Remove the IN_PIPE version of the "output-is-input" test above. 72.4342 ++# The others aren't susceptible because they have three inputs each. 72.4343 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 72.4344 ++ 72.4345 + my $save_temps = $ENV{DEBUG}; 72.4346 + my $verbose = $ENV{VERBOSE}; 72.4347 + 72.4348 +-my $prog = 'fold'; 72.4349 + my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); 72.4350 + exit $fail; 72.4351 +diff -Naurp coreutils-8.25-orig/tests/misc/join.pl coreutils-8.25/tests/misc/join.pl 72.4352 +--- coreutils-8.25-orig/tests/misc/join.pl 2016-01-16 12:18:13.000000000 -0600 72.4353 ++++ coreutils-8.25/tests/misc/join.pl 2016-02-08 19:07:10.315944664 -0600 72.4354 +@@ -25,6 +25,15 @@ my $limits = getlimits (); 72.4355 + 72.4356 + my $prog = 'join'; 72.4357 + 72.4358 ++my $try = "Try \`$prog --help' for more information.\n"; 72.4359 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 72.4360 ++ 72.4361 ++my $mb_locale; 72.4362 ++#Comment out next line to disable multibyte tests 72.4363 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 72.4364 ++! defined $mb_locale || $mb_locale eq 'none' 72.4365 ++ and $mb_locale = 'C'; 72.4366 ++ 72.4367 + my $delim = chr 0247; 72.4368 + sub t_subst ($) 72.4369 + { 72.4370 +@@ -329,8 +338,49 @@ foreach my $t (@tv) 72.4371 + push @Tests, $new_ent; 72.4372 + } 72.4373 + 72.4374 ++# Add _POSIX2_VERSION=199209 to the environment of each test 72.4375 ++# that uses an old-style option like +1. 72.4376 ++if ($mb_locale ne 'C') 72.4377 ++ { 72.4378 ++ # Duplicate each test vector, appending "-mb" to the test name and 72.4379 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 72.4380 ++ # provide coverage for the distro-added multi-byte code paths. 72.4381 ++ my @new; 72.4382 ++ foreach my $t (@Tests) 72.4383 ++ { 72.4384 ++ my @new_t = @$t; 72.4385 ++ my $test_name = shift @new_t; 72.4386 ++ 72.4387 ++ # Depending on whether join is multi-byte-patched, 72.4388 ++ # it emits different diagnostics: 72.4389 ++ # non-MB: invalid byte or field list 72.4390 ++ # MB: invalid byte, character or field list 72.4391 ++ # Adjust the expected error output accordingly. 72.4392 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 72.4393 ++ (@new_t)) 72.4394 ++ { 72.4395 ++ my $sub = {ERR_SUBST => 's/, character//'}; 72.4396 ++ push @new_t, $sub; 72.4397 ++ push @$t, $sub; 72.4398 ++ } 72.4399 ++ #Adjust the output some error messages including test_name for mb 72.4400 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR}} 72.4401 ++ (@new_t)) 72.4402 ++ { 72.4403 ++ my $sub2 = {ERR_SUBST => "s/$test_name-mb/$test_name/"}; 72.4404 ++ push @new_t, $sub2; 72.4405 ++ push @$t, $sub2; 72.4406 ++ } 72.4407 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 72.4408 ++ } 72.4409 ++ push @Tests, @new; 72.4410 ++ } 72.4411 ++ 72.4412 + @Tests = triple_test \@Tests; 72.4413 + 72.4414 ++#skip invalid-j-mb test, it is failing because of the format 72.4415 ++@Tests = grep {$_->[0] ne 'invalid-j-mb'} @Tests; 72.4416 ++ 72.4417 + my $save_temps = $ENV{DEBUG}; 72.4418 + my $verbose = $ENV{VERBOSE}; 72.4419 + 72.4420 +diff -Naurp coreutils-8.25-orig/tests/misc/sort-mb-tests.sh coreutils-8.25/tests/misc/sort-mb-tests.sh 72.4421 +--- coreutils-8.25-orig/tests/misc/sort-mb-tests.sh 1969-12-31 18:00:00.000000000 -0600 72.4422 ++++ coreutils-8.25/tests/misc/sort-mb-tests.sh 2016-02-08 19:07:10.315944664 -0600 72.4423 +@@ -0,0 +1,45 @@ 72.4424 ++#!/bin/sh 72.4425 ++# Verify sort's multi-byte support. 72.4426 ++ 72.4427 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 72.4428 ++print_ver_ sort 72.4429 ++ 72.4430 ++export LC_ALL=en_US.UTF-8 72.4431 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 72.4432 ++ || skip_ "No UTF-8 locale available" 72.4433 ++ 72.4434 ++ 72.4435 ++cat <<EOF > exp 72.4436 ++Banana@5 72.4437 ++Apple@10 72.4438 ++Citrus@20 72.4439 ++Cherry@30 72.4440 ++EOF 72.4441 ++ 72.4442 ++cat <<EOF | sort -t @ -k2 -n > out || fail=1 72.4443 ++Apple@10 72.4444 ++Banana@5 72.4445 ++Citrus@20 72.4446 ++Cherry@30 72.4447 ++EOF 72.4448 ++ 72.4449 ++compare exp out || { fail=1; cat out; } 72.4450 ++ 72.4451 ++ 72.4452 ++cat <<EOF > exp 72.4453 ++Citrus@AA20@@5 72.4454 ++Cherry@AA30@@10 72.4455 ++Apple@AA10@@20 72.4456 ++Banana@AA5@@30 72.4457 ++EOF 72.4458 ++ 72.4459 ++cat <<EOF | sort -t @ -k4 -n > out || fail=1 72.4460 ++Apple@AA10@@20 72.4461 ++Banana@AA5@@30 72.4462 ++Citrus@AA20@@5 72.4463 ++Cherry@AA30@@10 72.4464 ++EOF 72.4465 ++ 72.4466 ++compare exp out || { fail=1; cat out; } 72.4467 ++ 72.4468 ++Exit $fail 72.4469 +diff -Naurp coreutils-8.25-orig/tests/misc/sort-merge.pl coreutils-8.25/tests/misc/sort-merge.pl 72.4470 +--- coreutils-8.25-orig/tests/misc/sort-merge.pl 2016-01-16 12:18:14.000000000 -0600 72.4471 ++++ coreutils-8.25/tests/misc/sort-merge.pl 2016-02-08 19:07:10.316944667 -0600 72.4472 +@@ -26,6 +26,15 @@ my $prog = 'sort'; 72.4473 + # Turn off localization of executable's output. 72.4474 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 72.4475 + 72.4476 ++my $mb_locale; 72.4477 ++# uncommented according to upstream commit enabling multibyte paths 72.4478 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 72.4479 ++! defined $mb_locale || $mb_locale eq 'none' 72.4480 ++ and $mb_locale = 'C'; 72.4481 ++ 72.4482 ++my $try = "Try \`$prog --help' for more information.\n"; 72.4483 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 72.4484 ++ 72.4485 + # three empty files and one that says 'foo' 72.4486 + my @inputs = (+(map{{IN=> {"empty$_"=> ''}}}1..3), {IN=> {foo=> "foo\n"}}); 72.4487 + 72.4488 +@@ -77,6 +86,39 @@ my @Tests = 72.4489 + {OUT=>$big_input}], 72.4490 + ); 72.4491 + 72.4492 ++# Add _POSIX2_VERSION=199209 to the environment of each test 72.4493 ++# that uses an old-style option like +1. 72.4494 ++if ($mb_locale ne 'C') 72.4495 ++ { 72.4496 ++ # Duplicate each test vector, appending "-mb" to the test name and 72.4497 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 72.4498 ++ # provide coverage for the distro-added multi-byte code paths. 72.4499 ++ my @new; 72.4500 ++ foreach my $t (@Tests) 72.4501 ++ { 72.4502 ++ my @new_t = @$t; 72.4503 ++ my $test_name = shift @new_t; 72.4504 ++ 72.4505 ++ # Depending on whether sort is multi-byte-patched, 72.4506 ++ # it emits different diagnostics: 72.4507 ++ # non-MB: invalid byte or field list 72.4508 ++ # MB: invalid byte, character or field list 72.4509 ++ # Adjust the expected error output accordingly. 72.4510 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 72.4511 ++ (@new_t)) 72.4512 ++ { 72.4513 ++ my $sub = {ERR_SUBST => 's/, character//'}; 72.4514 ++ push @new_t, $sub; 72.4515 ++ push @$t, $sub; 72.4516 ++ } 72.4517 ++ next if ($test_name =~ "nmerge-."); 72.4518 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 72.4519 ++ } 72.4520 ++ push @Tests, @new; 72.4521 ++ } 72.4522 ++ 72.4523 ++@Tests = triple_test \@Tests; 72.4524 ++ 72.4525 + my $save_temps = $ENV{DEBUG}; 72.4526 + my $verbose = $ENV{VERBOSE}; 72.4527 + 72.4528 +diff -Naurp coreutils-8.25-orig/tests/misc/sort.pl coreutils-8.25/tests/misc/sort.pl 72.4529 +--- coreutils-8.25-orig/tests/misc/sort.pl 2016-01-16 12:18:14.000000000 -0600 72.4530 ++++ coreutils-8.25/tests/misc/sort.pl 2016-02-08 19:07:10.316944667 -0600 72.4531 +@@ -24,10 +24,15 @@ my $prog = 'sort'; 72.4532 + # Turn off localization of executable's output. 72.4533 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 72.4534 + 72.4535 +-my $mb_locale = $ENV{LOCALE_FR_UTF8}; 72.4536 ++my $mb_locale; 72.4537 ++#Comment out next line to disable multibyte tests 72.4538 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 72.4539 + ! defined $mb_locale || $mb_locale eq 'none' 72.4540 + and $mb_locale = 'C'; 72.4541 + 72.4542 ++my $try = "Try \`$prog --help' for more information.\n"; 72.4543 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 72.4544 ++ 72.4545 + # Since each test is run with a file name and with redirected stdin, 72.4546 + # the name in the diagnostic is either the file name or "-". 72.4547 + # Normalize each diagnostic to use '-'. 72.4548 +@@ -424,6 +429,38 @@ foreach my $t (@Tests) 72.4549 + } 72.4550 + } 72.4551 + 72.4552 ++if ($mb_locale ne 'C') 72.4553 ++ { 72.4554 ++ # Duplicate each test vector, appending "-mb" to the test name and 72.4555 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 72.4556 ++ # provide coverage for the distro-added multi-byte code paths. 72.4557 ++ my @new; 72.4558 ++ foreach my $t (@Tests) 72.4559 ++ { 72.4560 ++ my @new_t = @$t; 72.4561 ++ my $test_name = shift @new_t; 72.4562 ++ 72.4563 ++ # Depending on whether sort is multi-byte-patched, 72.4564 ++ # it emits different diagnostics: 72.4565 ++ # non-MB: invalid byte or field list 72.4566 ++ # MB: invalid byte, character or field list 72.4567 ++ # Adjust the expected error output accordingly. 72.4568 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 72.4569 ++ (@new_t)) 72.4570 ++ { 72.4571 ++ my $sub = {ERR_SUBST => 's/, character//'}; 72.4572 ++ push @new_t, $sub; 72.4573 ++ push @$t, $sub; 72.4574 ++ } 72.4575 ++ #disable several failing tests until investigation, disable all tests with envvars set 72.4576 ++ next if (grep {ref $_ eq 'HASH' && exists $_->{ENV}} (@new_t)); 72.4577 ++ next if ($test_name =~ "18g" or $test_name =~ "sort-numeric" or $test_name =~ "08[ab]" or $test_name =~ "03[def]" or $test_name =~ "h4" or $test_name =~ "n1" or $test_name =~ "2[01]a"); 72.4578 ++ next if ($test_name =~ "11[ab]"); # avoid FP: expected result differs to MB result due to collation rules. 72.4579 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 72.4580 ++ } 72.4581 ++ push @Tests, @new; 72.4582 ++ } 72.4583 ++ 72.4584 + @Tests = triple_test \@Tests; 72.4585 + 72.4586 + # Remember that triple_test creates from each test with exactly one "IN" 72.4587 +@@ -433,6 +470,7 @@ foreach my $t (@Tests) 72.4588 + # Remove the IN_PIPE version of the "output-is-input" test above. 72.4589 + # The others aren't susceptible because they have three inputs each. 72.4590 + @Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 72.4591 ++@Tests = grep {$_->[0] ne 'output-is-input-mb.p'} @Tests; 72.4592 + 72.4593 + my $save_temps = $ENV{DEBUG}; 72.4594 + my $verbose = $ENV{VERBOSE}; 72.4595 +diff -Naurp coreutils-8.25-orig/tests/misc/unexpand.pl coreutils-8.25/tests/misc/unexpand.pl 72.4596 +--- coreutils-8.25-orig/tests/misc/unexpand.pl 2016-01-16 12:18:14.000000000 -0600 72.4597 ++++ coreutils-8.25/tests/misc/unexpand.pl 2016-02-08 19:07:10.317944671 -0600 72.4598 +@@ -27,6 +27,14 @@ my $limits = getlimits (); 72.4599 + 72.4600 + my $prog = 'unexpand'; 72.4601 + 72.4602 ++# comment out next line to disable multibyte tests 72.4603 ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; 72.4604 ++! defined $mb_locale || $mb_locale eq 'none' 72.4605 ++ and $mb_locale = 'C'; 72.4606 ++ 72.4607 ++my $try = "Try \`$prog --help' for more information.\n"; 72.4608 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 72.4609 ++ 72.4610 + my @Tests = 72.4611 + ( 72.4612 + ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], 72.4613 +@@ -92,6 +100,37 @@ my @Tests = 72.4614 + {EXIT => 1}, {ERR => "$prog: tab stop value is too large\n"}], 72.4615 + ); 72.4616 + 72.4617 ++if ($mb_locale ne 'C') 72.4618 ++ { 72.4619 ++ # Duplicate each test vector, appending "-mb" to the test name and 72.4620 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 72.4621 ++ # provide coverage for the distro-added multi-byte code paths. 72.4622 ++ my @new; 72.4623 ++ foreach my $t (@Tests) 72.4624 ++ { 72.4625 ++ my @new_t = @$t; 72.4626 ++ my $test_name = shift @new_t; 72.4627 ++ 72.4628 ++ # Depending on whether unexpand is multi-byte-patched, 72.4629 ++ # it emits different diagnostics: 72.4630 ++ # non-MB: invalid byte or field list 72.4631 ++ # MB: invalid byte, character or field list 72.4632 ++ # Adjust the expected error output accordingly. 72.4633 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 72.4634 ++ (@new_t)) 72.4635 ++ { 72.4636 ++ my $sub = {ERR_SUBST => 's/, character//'}; 72.4637 ++ push @new_t, $sub; 72.4638 ++ push @$t, $sub; 72.4639 ++ } 72.4640 ++ next if ($test_name =~ 'b-1'); 72.4641 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 72.4642 ++ } 72.4643 ++ push @Tests, @new; 72.4644 ++ } 72.4645 ++ 72.4646 ++@Tests = triple_test \@Tests; 72.4647 ++ 72.4648 + my $save_temps = $ENV{DEBUG}; 72.4649 + my $verbose = $ENV{VERBOSE}; 72.4650 + 72.4651 +diff -Naurp coreutils-8.25-orig/tests/misc/uniq.pl coreutils-8.25/tests/misc/uniq.pl 72.4652 +--- coreutils-8.25-orig/tests/misc/uniq.pl 2016-01-16 12:18:14.000000000 -0600 72.4653 ++++ coreutils-8.25/tests/misc/uniq.pl 2016-02-08 19:07:10.317944671 -0600 72.4654 +@@ -23,9 +23,17 @@ my $limits = getlimits (); 72.4655 + my $prog = 'uniq'; 72.4656 + my $try = "Try '$prog --help' for more information.\n"; 72.4657 + 72.4658 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 72.4659 ++ 72.4660 + # Turn off localization of executable's output. 72.4661 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 72.4662 + 72.4663 ++my $mb_locale; 72.4664 ++#Comment out next line to disable multibyte tests 72.4665 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 72.4666 ++! defined $mb_locale || $mb_locale eq 'none' 72.4667 ++ and $mb_locale = 'C'; 72.4668 ++ 72.4669 + # When possible, create a "-z"-testing variant of each test. 72.4670 + sub add_z_variants($) 72.4671 + { 72.4672 +@@ -262,6 +270,53 @@ foreach my $t (@Tests) 72.4673 + and push @$t, {ENV=>'_POSIX2_VERSION=199209'}; 72.4674 + } 72.4675 + 72.4676 ++if ($mb_locale ne 'C') 72.4677 ++ { 72.4678 ++ # Duplicate each test vector, appending "-mb" to the test name and 72.4679 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 72.4680 ++ # provide coverage for the distro-added multi-byte code paths. 72.4681 ++ my @new; 72.4682 ++ foreach my $t (@Tests) 72.4683 ++ { 72.4684 ++ my @new_t = @$t; 72.4685 ++ my $test_name = shift @new_t; 72.4686 ++ 72.4687 ++ # Depending on whether uniq is multi-byte-patched, 72.4688 ++ # it emits different diagnostics: 72.4689 ++ # non-MB: invalid byte or field list 72.4690 ++ # MB: invalid byte, character or field list 72.4691 ++ # Adjust the expected error output accordingly. 72.4692 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 72.4693 ++ (@new_t)) 72.4694 ++ { 72.4695 ++ my $sub = {ERR_SUBST => 's/, character//'}; 72.4696 ++ push @new_t, $sub; 72.4697 ++ push @$t, $sub; 72.4698 ++ } 72.4699 ++ # In test #145, replace the each ‘...’ by '...'. 72.4700 ++ if ($test_name =~ "145") 72.4701 ++ { 72.4702 ++ my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"}; 72.4703 ++ push @new_t, $sub; 72.4704 ++ push @$t, $sub; 72.4705 ++ } 72.4706 ++ next if ( $test_name =~ "schar" 72.4707 ++ or $test_name =~ "^obs-plus" 72.4708 ++ or $test_name =~ "119"); 72.4709 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 72.4710 ++ } 72.4711 ++ push @Tests, @new; 72.4712 ++ } 72.4713 ++ 72.4714 ++# Remember that triple_test creates from each test with exactly one "IN" 72.4715 ++# file two more tests (.p and .r suffix on name) corresponding to reading 72.4716 ++# input from a file and from a pipe. The pipe-reading test would fail 72.4717 ++# due to a race condition about 1 in 20 times. 72.4718 ++# Remove the IN_PIPE version of the "output-is-input" test above. 72.4719 ++# The others aren't susceptible because they have three inputs each. 72.4720 ++ 72.4721 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 72.4722 ++ 72.4723 + @Tests = add_z_variants \@Tests; 72.4724 + @Tests = triple_test \@Tests; 72.4725 + 72.4726 +diff -Naurp coreutils-8.25-orig/tests/pr/pr-tests.pl coreutils-8.25/tests/pr/pr-tests.pl 72.4727 +--- coreutils-8.25-orig/tests/pr/pr-tests.pl 2016-01-16 12:18:14.000000000 -0600 72.4728 ++++ coreutils-8.25/tests/pr/pr-tests.pl 2016-02-08 19:07:10.318944674 -0600 72.4729 +@@ -24,6 +24,15 @@ use strict; 72.4730 + my $prog = 'pr'; 72.4731 + my $normalize_strerror = "s/': .*/'/"; 72.4732 + 72.4733 ++my $mb_locale; 72.4734 ++#Uncomment the following line to enable multibyte tests 72.4735 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 72.4736 ++! defined $mb_locale || $mb_locale eq 'none' 72.4737 ++ and $mb_locale = 'C'; 72.4738 ++ 72.4739 ++my $try = "Try \`$prog --help' for more information.\n"; 72.4740 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 72.4741 ++ 72.4742 + my @tv = ( 72.4743 + 72.4744 + # -b option is no longer an official option. But it's still working to 72.4745 +@@ -467,8 +476,48 @@ push @Tests, 72.4746 + {IN=>{3=>"x\ty\tz\n"}}, 72.4747 + {OUT=>join("\t", qw(a b c m n o x y z)) . "\n"} ]; 72.4748 + 72.4749 ++# Add _POSIX2_VERSION=199209 to the environment of each test 72.4750 ++# that uses an old-style option like +1. 72.4751 ++if ($mb_locale ne 'C') 72.4752 ++ { 72.4753 ++ # Duplicate each test vector, appending "-mb" to the test name and 72.4754 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 72.4755 ++ # provide coverage for the distro-added multi-byte code paths. 72.4756 ++ my @new; 72.4757 ++ foreach my $t (@Tests) 72.4758 ++ { 72.4759 ++ my @new_t = @$t; 72.4760 ++ my $test_name = shift @new_t; 72.4761 ++ 72.4762 ++ # Depending on whether pr is multi-byte-patched, 72.4763 ++ # it emits different diagnostics: 72.4764 ++ # non-MB: invalid byte or field list 72.4765 ++ # MB: invalid byte, character or field list 72.4766 ++ # Adjust the expected error output accordingly. 72.4767 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 72.4768 ++ (@new_t)) 72.4769 ++ { 72.4770 ++ my $sub = {ERR_SUBST => 's/, character//'}; 72.4771 ++ push @new_t, $sub; 72.4772 ++ push @$t, $sub; 72.4773 ++ } 72.4774 ++ #temporarily skip some failing tests 72.4775 ++ next if ($test_name =~ "col-0" or $test_name =~ "col-inval"); 72.4776 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 72.4777 ++ } 72.4778 ++ push @Tests, @new; 72.4779 ++ } 72.4780 ++ 72.4781 + @Tests = triple_test \@Tests; 72.4782 + 72.4783 ++# Remember that triple_test creates from each test with exactly one "IN" 72.4784 ++# file two more tests (.p and .r suffix on name) corresponding to reading 72.4785 ++# input from a file and from a pipe. The pipe-reading test would fail 72.4786 ++# due to a race condition about 1 in 20 times. 72.4787 ++# Remove the IN_PIPE version of the "output-is-input" test above. 72.4788 ++# The others aren't susceptible because they have three inputs each. 72.4789 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 72.4790 ++ 72.4791 + my $save_temps = $ENV{DEBUG}; 72.4792 + my $verbose = $ENV{VERBOSE}; 72.4793 +
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 73.2 +++ b/coreutils/stuff/patches/coreutils-fix-po.patch Sat May 27 16:55:17 2017 +0300 73.3 @@ -0,0 +1,84 @@ 73.4 +--- a/po/nb.po 73.5 ++++ b/po/nb.po 73.6 +@@ -2721,7 +2721,7 @@ 73.7 + "A line OFFSET is a required '+' or '-' followed by a positive integer.\n" 73.8 + msgstr "" 73.9 + "\n" 73.10 +-"\vMØNSTER må utformes slik:\n" 73.11 ++"MØNSTER må utformes slik:\n" 73.12 + " INTEGER kopier frem til - men ikke inkludert - angitt " 73.13 + "linjenummer\n" 73.14 + " /REGEXP/[OFFSET] kopier frem til - men ikke inkludert - en samsvarende " 73.15 +@@ -7132,7 +7132,7 @@ 73.16 + "Multiple fields/ranges can be separated with commas\n" 73.17 + msgstr "" 73.18 + "\n" 73.19 +-"\vFELT støtter feltrekkevidder i cut(1)-stil:\n" 73.20 ++"FELT støtter feltrekkevidder i cut(1)-stil:\n" 73.21 + " N N'te byte, tegn eller felt, talt fra 1\n" 73.22 + " N- fra N'te byte, tegn eller felt, til slutten av linja\n" 73.23 + " N-M fra N'te til M'te (inklusive) byte, tegn eller felt\n" 73.24 +--- a/po/sl.po 73.25 ++++ b/po/sl.po 73.26 +@@ -2641,7 +2641,7 @@ 73.27 + #: src/csplit.c:1299 73.28 + #, c-format 73.29 + msgid "invalid conversion specifier in suffix: \\%.3o" 73.30 +-msgstr "neveljavno določilo pretvorbe v priponi: \\\\%.3o" 73.31 ++msgstr "neveljavno določilo pretvorbe v priponi: \\%.3o" 73.32 + 73.33 + #: src/csplit.c:1304 73.34 + #, c-format 73.35 +@@ -6711,7 +6711,7 @@ 73.36 + "ločitvena\n" 73.37 + "znaka za ločevanje logičnih strani; če je drugi znak izpuščen, se " 73.38 + "privzame :.\n" 73.39 +-"Uporabite \\\\\\\\ za \\\\. SLOG je nekaj od naštetega:\n" 73.40 ++"Uporabite \\\\ za \\. SLOG je nekaj od naštetega:\n" 73.41 + 73.42 + #: src/nl.c:211 73.43 + msgid "" 73.44 +@@ -7951,8 +7951,8 @@ 73.45 + msgstr "" 73.46 + " -h, --header=ZGLAVJE\n" 73.47 + " uporabimo navedeno osredinjeno ZGLAVJE namesto imena\n" 73.48 +-" datoteke; -h \\\"\\\" izpiše prazno vrstica; ne " 73.49 +-"uporabljajte -h\\\"\\\"\n" 73.50 ++" datoteke; -h \"\" izpiše prazno vrstica; ne " 73.51 ++"uporabljajte -h\"\"\n" 73.52 + " -i[ZNAK[ŠIRINA]], --output-tabs[=ZNAK[ŠIRINA]]\n" 73.53 + " presledke skrčimo v ZNAK (privzeto TAB) do ŠIRINE\n" 73.54 + " tabulatorja (privzeto 8)\n" 73.55 +@@ -12078,15 +12078,15 @@ 73.56 + "MNOŽICE določajo nizi znakov. Večinoma predstavljajo sebe, posebej pa se\n" 73.57 + "tolmačijo naslednja zaporedja:\n" 73.58 + "\n" 73.59 +-" \\\\NNN znak z osmiško kodo NNN (dolžina 1, 2 ali 3 osmiške " 73.60 ++" \\NNN znak z osmiško kodo NNN (dolžina 1, 2 ali 3 osmiške " 73.61 + "števke)\n" 73.62 +-" \\\\\\\\ obratna poševnica\n" 73.63 +-" \\\\a zvonček\n" 73.64 +-" \\\\b pomik za en znak v levo\n" 73.65 +-" \\\\f skok na novo stran\n" 73.66 +-" \\\\n skok v novo vrstico\n" 73.67 +-" \\\\r pomik na levi rob\n" 73.68 +-" \\\\t vodoravni tabulator\n" 73.69 ++" \\\\ obratna poševnica\n" 73.70 ++" \\a zvonček\n" 73.71 ++" \\b pomik za en znak v levo\n" 73.72 ++" \\f skok na novo stran\n" 73.73 ++" \\n skok v novo vrstico\n" 73.74 ++" \\r pomik na levi rob\n" 73.75 ++" \\t vodoravni tabulator\n" 73.76 + 73.77 + #: src/tr.c:317 73.78 + msgid "" 73.79 +@@ -12100,7 +12100,7 @@ 73.80 + " [:cntrl:] all control characters\n" 73.81 + " [:digit:] all digits\n" 73.82 + msgstr "" 73.83 +-" \\\\v navpični tabulator\n" 73.84 ++" \\v navpični tabulator\n" 73.85 + " ZNAK1-ZNAK2 naraščajoče zaporedje znakov od ZNAKA1 do ZNAKA2\n" 73.86 + " [ZNAK1-ZNAK2] isto kot ZNAK1-ZNAK2, če to uporabljata obe množici\n" 73.87 + " [ZNAK*] v MNOŽICI 2; toliko ponovitev ZNAKA kot v MNOŽICI 1\n"
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 74.2 +++ b/coreutils/stuff/patches/series Sat May 27 16:55:17 2017 +0300 74.3 @@ -0,0 +1,3 @@ 74.4 +coreutils-8.25-i18n-2.patch 74.5 +uname.u 74.6 +coreutils-fix-po.patch
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 75.2 +++ b/coreutils/stuff/patches/uname.u Sat May 27 16:55:17 2017 +0300 75.3 @@ -0,0 +1,173 @@ 75.4 +On linux platforms, grok /proc/cpuinfo for the CPU/vendor info. 75.5 + 75.6 +Prob not suitable for upstream seeing as how it's 100% linux-specific 75.7 +http://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html 75.8 + 75.9 +Patch originally by Carlos E. Gorges <carlos@techlinux.com.br>, but 75.10 +heavily reworked to suck less. 75.11 + 75.12 +To add support for additional platforms, check out the show_cpuinfo() 75.13 +func in the linux/arch/<ARCH>/ source tree of the kernel. 75.14 + 75.15 +--- coreutils/src/uname.c 75.16 ++++ coreutils/src/uname.c 75.17 +@@ -50,6 +50,11 @@ 75.18 + # include <mach-o/arch.h> 75.19 + #endif 75.20 + 75.21 ++#if defined(__linux__) 75.22 ++# define USE_PROCINFO 75.23 ++# define UNAME_HARDWARE_PLATFORM 75.24 ++#endif 75.25 ++ 75.26 + #include "system.h" 75.27 + #include "error.h" 75.28 + #include "quote.h" 75.29 +@@ -138,6 +143,117 @@ 75.30 + exit (status); 75.31 + } 75.32 + 75.33 ++#if defined(USE_PROCINFO) 75.34 ++ 75.35 ++# if defined(__s390__) || defined(__s390x__) 75.36 ++# define CPUINFO_FILE "/proc/sysinfo" 75.37 ++# define CPUINFO_FORMAT "%64[^\t :]%*[ :]%256[^\n]%c" 75.38 ++# else 75.39 ++# define CPUINFO_FILE "/proc/cpuinfo" 75.40 ++# define CPUINFO_FORMAT "%64[^\t:]\t:%256[^\n]%c" 75.41 ++# endif 75.42 ++ 75.43 ++# define PROCINFO_PROCESSOR 0 75.44 ++# define PROCINFO_HARDWARE_PLATFORM 1 75.45 ++ 75.46 ++static void __eat_cpuinfo_space(char *buf) 75.47 ++{ 75.48 ++ /* first eat trailing space */ 75.49 ++ char *tmp = buf + strlen(buf) - 1; 75.50 ++ while (tmp > buf && isspace(*tmp)) 75.51 ++ *tmp-- = '\0'; 75.52 ++ /* then eat leading space */ 75.53 ++ tmp = buf; 75.54 ++ while (*tmp && isspace(*tmp)) 75.55 ++ tmp++; 75.56 ++ if (tmp != buf) 75.57 ++ memmove(buf, tmp, strlen(tmp)+1); 75.58 ++ /* finally collapse whitespace */ 75.59 ++ tmp = buf; 75.60 ++ while (tmp[0] && tmp[1]) { 75.61 ++ if (isspace(tmp[0]) && isspace(tmp[1])) { 75.62 ++ memmove(tmp, tmp+1, strlen(tmp)); 75.63 ++ continue; 75.64 ++ } 75.65 ++ ++tmp; 75.66 ++ } 75.67 ++} 75.68 ++ 75.69 ++static int __linux_procinfo(int x, char *fstr, size_t s) 75.70 ++{ 75.71 ++ FILE *fp; 75.72 ++ 75.73 ++ char *procinfo_keys[] = { 75.74 ++ /* --processor --hardware-platform */ 75.75 ++ #if defined(__alpha__) 75.76 ++ "cpu model", "system type" 75.77 ++ #elif defined(__arm__) 75.78 ++ "Processor", "Hardware" 75.79 ++ #elif defined(__avr32__) 75.80 ++ "processor", "cpu family" 75.81 ++ #elif defined(__bfin__) 75.82 ++ "CPU", "BOARD Name" 75.83 ++ #elif defined(__cris__) 75.84 ++ "cpu", "cpu model" 75.85 ++ #elif defined(__frv__) 75.86 ++ "CPU-Core", "System" 75.87 ++ #elif defined(__i386__) || defined(__x86_64__) 75.88 ++ "model name", "vendor_id" 75.89 ++ #elif defined(__ia64__) 75.90 ++ "family", "vendor" 75.91 ++ #elif defined(__hppa__) 75.92 ++ "cpu", "model" 75.93 ++ #elif defined(__m68k__) 75.94 ++ "CPU", "MMU" 75.95 ++ #elif defined(__mips__) 75.96 ++ "cpu model", "system type" 75.97 ++ #elif defined(__powerpc__) || defined(__powerpc64__) 75.98 ++ "cpu", "machine" 75.99 ++ #elif defined(__s390__) || defined(__s390x__) 75.100 ++ "Type", "Manufacturer" 75.101 ++ #elif defined(__sh__) 75.102 ++ "cpu type", "machine" 75.103 ++ #elif defined(sparc) || defined(__sparc__) 75.104 ++ "type", "cpu" 75.105 ++ #elif defined(__vax__) 75.106 ++ "cpu type", "cpu" 75.107 ++ #else 75.108 ++ "unknown", "unknown" 75.109 ++ #endif 75.110 ++ }; 75.111 ++ 75.112 ++ if ((fp = fopen(CPUINFO_FILE, "r")) != NULL) { 75.113 ++ char key[65], value[257], eol, *ret = NULL; 75.114 ++ 75.115 ++ while (fscanf(fp, CPUINFO_FORMAT, key, value, &eol) != EOF) { 75.116 ++ __eat_cpuinfo_space(key); 75.117 ++ if (!strcmp(key, procinfo_keys[x])) { 75.118 ++ __eat_cpuinfo_space(value); 75.119 ++ ret = value; 75.120 ++ break; 75.121 ++ } 75.122 ++ if (eol != '\n') { 75.123 ++ /* we need two fscanf's here in case the previous 75.124 ++ * length limit caused us to read right up to the 75.125 ++ * newline ... doing "%*[^\n]\n" wont eat the newline 75.126 ++ */ 75.127 ++ fscanf(fp, "%*[^\n]"); 75.128 ++ fscanf(fp, "\n"); 75.129 ++ } 75.130 ++ } 75.131 ++ fclose(fp); 75.132 ++ 75.133 ++ if (ret) { 75.134 ++ strncpy(fstr, ret, s); 75.135 ++ return 0; 75.136 ++ } 75.137 ++ } 75.138 ++ 75.139 ++ return -1; 75.140 ++} 75.141 ++ 75.142 ++#endif 75.143 ++ 75.144 + /* Print ELEMENT, preceded by a space if something has already been 75.145 + printed. */ 75.146 + 75.147 +@@ -250,10 +344,14 @@ main (int argc, char **argv) 75.148 + if (toprint & PRINT_PROCESSOR) 75.149 + { 75.150 + char const *element = unknown; 75.151 +-#if HAVE_SYSINFO && defined SI_ARCHITECTURE 75.152 ++#if ( HAVE_SYSINFO && defined SI_ARCHITECTURE ) || defined(USE_PROCINFO) 75.153 + { 75.154 + static char processor[257]; 75.155 ++#if defined(USE_PROCINFO) 75.156 ++ if (0 <= __linux_procinfo (PROCINFO_PROCESSOR, processor, sizeof processor)) 75.157 ++#else 75.158 + if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) 75.159 ++#endif 75.160 + element = processor; 75.161 + } 75.162 + #endif 75.163 +@@ -306,9 +404,13 @@ main (int argc, char **argv) 75.164 + if (element == unknown) 75.165 + { 75.166 + static char hardware_platform[257]; 75.167 ++#if defined(USE_PROCINFO) 75.168 ++ if (0 <= __linux_procinfo (PROCINFO_HARDWARE_PLATFORM, hardware_platform, sizeof hardware_platform)) 75.169 ++#else 75.170 + size_t s = sizeof hardware_platform; 75.171 + static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM }; 75.172 + if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0) 75.173 ++#endif 75.174 + element = hardware_platform; 75.175 + } 75.176 + #endif
76.1 --- a/coreutils/stuff/sigcontext.h Sat May 27 16:29:45 2017 +0300 76.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 76.3 @@ -1,143 +0,0 @@ 76.4 -#ifndef _ASM_X86_SIGCONTEXT_H 76.5 -#define _ASM_X86_SIGCONTEXT_H 76.6 - 76.7 -#include <asm/types.h> 76.8 - 76.9 -#ifdef __i386__ 76.10 -/* 76.11 - * As documented in the iBCS2 standard.. 76.12 - * 76.13 - * The first part of "struct _fpstate" is just the normal i387 76.14 - * hardware setup, the extra "status" word is used to save the 76.15 - * coprocessor status word before entering the handler. 76.16 - * 76.17 - * Pentium III FXSR, SSE support 76.18 - * Gareth Hughes <gareth@valinux.com>, May 2000 76.19 - * 76.20 - * The FPU state data structure has had to grow to accommodate the 76.21 - * extended FPU state required by the Streaming SIMD Extensions. 76.22 - * There is no documented standard to accomplish this at the moment. 76.23 - */ 76.24 -struct _fpreg { 76.25 - unsigned short significand[4]; 76.26 - unsigned short exponent; 76.27 -}; 76.28 - 76.29 -struct _fpxreg { 76.30 - unsigned short significand[4]; 76.31 - unsigned short exponent; 76.32 - unsigned short padding[3]; 76.33 -}; 76.34 - 76.35 -struct _xmmreg { 76.36 - unsigned long element[4]; 76.37 -}; 76.38 - 76.39 -struct _fpstate { 76.40 - /* Regular FPU environment */ 76.41 - unsigned long cw; 76.42 - unsigned long sw; 76.43 - unsigned long tag; 76.44 - unsigned long ipoff; 76.45 - unsigned long cssel; 76.46 - unsigned long dataoff; 76.47 - unsigned long datasel; 76.48 - struct _fpreg _st[8]; 76.49 - unsigned short status; 76.50 - unsigned short magic; /* 0xffff = regular FPU data only */ 76.51 - 76.52 - /* FXSR FPU environment */ 76.53 - unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */ 76.54 - unsigned long mxcsr; 76.55 - unsigned long reserved; 76.56 - struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */ 76.57 - struct _xmmreg _xmm[8]; 76.58 - unsigned long padding[56]; 76.59 -}; 76.60 - 76.61 -#define X86_FXSR_MAGIC 0x0000 76.62 - 76.63 -/* 76.64 - * User-space might still rely on the old definition: 76.65 - */ 76.66 -struct sigcontext { 76.67 - unsigned short gs, __gsh; 76.68 - unsigned short fs, __fsh; 76.69 - unsigned short es, __esh; 76.70 - unsigned short ds, __dsh; 76.71 - unsigned long edi; 76.72 - unsigned long esi; 76.73 - unsigned long ebp; 76.74 - unsigned long esp; 76.75 - unsigned long ebx; 76.76 - unsigned long edx; 76.77 - unsigned long ecx; 76.78 - unsigned long eax; 76.79 - unsigned long trapno; 76.80 - unsigned long err; 76.81 - unsigned long eip; 76.82 - unsigned short cs, __csh; 76.83 - unsigned long eflags; 76.84 - unsigned long esp_at_signal; 76.85 - unsigned short ss, __ssh; 76.86 - struct _fpstate * fpstate; 76.87 - unsigned long oldmask; 76.88 - unsigned long cr2; 76.89 -}; 76.90 - 76.91 -#else /* __i386__ */ 76.92 - 76.93 -/* FXSAVE frame */ 76.94 -/* Note: reserved1/2 may someday contain valuable data. Always save/restore 76.95 - them when you change signal frames. */ 76.96 -struct _fpstate { 76.97 - __u16 cwd; 76.98 - __u16 swd; 76.99 - __u16 twd; /* Note this is not the same as the 32bit/x87/FSAVE twd */ 76.100 - __u16 fop; 76.101 - __u64 rip; 76.102 - __u64 rdp; 76.103 - __u32 mxcsr; 76.104 - __u32 mxcsr_mask; 76.105 - __u32 st_space[32]; /* 8*16 bytes for each FP-reg */ 76.106 - __u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg */ 76.107 - __u32 reserved2[24]; 76.108 -}; 76.109 - 76.110 -/* 76.111 - * User-space might still rely on the old definition: 76.112 - */ 76.113 -struct sigcontext { 76.114 - unsigned long r8; 76.115 - unsigned long r9; 76.116 - unsigned long r10; 76.117 - unsigned long r11; 76.118 - unsigned long r12; 76.119 - unsigned long r13; 76.120 - unsigned long r14; 76.121 - unsigned long r15; 76.122 - unsigned long rdi; 76.123 - unsigned long rsi; 76.124 - unsigned long rbp; 76.125 - unsigned long rbx; 76.126 - unsigned long rdx; 76.127 - unsigned long rax; 76.128 - unsigned long rcx; 76.129 - unsigned long rsp; 76.130 - unsigned long rip; 76.131 - unsigned long eflags; /* RFLAGS */ 76.132 - unsigned short cs; 76.133 - unsigned short gs; 76.134 - unsigned short fs; 76.135 - unsigned short __pad0; 76.136 - unsigned long err; 76.137 - unsigned long trapno; 76.138 - unsigned long oldmask; 76.139 - unsigned long cr2; 76.140 - struct _fpstate *fpstate; /* zero when no FPU context */ 76.141 - unsigned long reserved1[8]; 76.142 -}; 76.143 - 76.144 -#endif /* !__i386__ */ 76.145 - 76.146 -#endif
77.1 --- a/coreutils/stuff/uname.u Sat May 27 16:29:45 2017 +0300 77.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 77.3 @@ -1,173 +0,0 @@ 77.4 -On linux platforms, grok /proc/cpuinfo for the CPU/vendor info. 77.5 - 77.6 -Prob not suitable for upstream seeing as how it's 100% linux-specific 77.7 -http://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html 77.8 - 77.9 -Patch originally by Carlos E. Gorges <carlos@techlinux.com.br>, but 77.10 -heavily reworked to suck less. 77.11 - 77.12 -To add support for additional platforms, check out the show_cpuinfo() 77.13 -func in the linux/arch/<ARCH>/ source tree of the kernel. 77.14 - 77.15 ---- coreutils/src/uname.c 77.16 -+++ coreutils/src/uname.c 77.17 -@@ -50,6 +50,11 @@ 77.18 - # include <mach-o/arch.h> 77.19 - #endif 77.20 - 77.21 -+#if defined(__linux__) 77.22 -+# define USE_PROCINFO 77.23 -+# define UNAME_HARDWARE_PLATFORM 77.24 -+#endif 77.25 -+ 77.26 - #include "system.h" 77.27 - #include "error.h" 77.28 - #include "quote.h" 77.29 -@@ -138,6 +143,117 @@ 77.30 - exit (status); 77.31 - } 77.32 - 77.33 -+#if defined(USE_PROCINFO) 77.34 -+ 77.35 -+# if defined(__s390__) || defined(__s390x__) 77.36 -+# define CPUINFO_FILE "/proc/sysinfo" 77.37 -+# define CPUINFO_FORMAT "%64[^\t :]%*[ :]%256[^\n]%c" 77.38 -+# else 77.39 -+# define CPUINFO_FILE "/proc/cpuinfo" 77.40 -+# define CPUINFO_FORMAT "%64[^\t:]\t:%256[^\n]%c" 77.41 -+# endif 77.42 -+ 77.43 -+# define PROCINFO_PROCESSOR 0 77.44 -+# define PROCINFO_HARDWARE_PLATFORM 1 77.45 -+ 77.46 -+static void __eat_cpuinfo_space(char *buf) 77.47 -+{ 77.48 -+ /* first eat trailing space */ 77.49 -+ char *tmp = buf + strlen(buf) - 1; 77.50 -+ while (tmp > buf && isspace(*tmp)) 77.51 -+ *tmp-- = '\0'; 77.52 -+ /* then eat leading space */ 77.53 -+ tmp = buf; 77.54 -+ while (*tmp && isspace(*tmp)) 77.55 -+ tmp++; 77.56 -+ if (tmp != buf) 77.57 -+ memmove(buf, tmp, strlen(tmp)+1); 77.58 -+ /* finally collapse whitespace */ 77.59 -+ tmp = buf; 77.60 -+ while (tmp[0] && tmp[1]) { 77.61 -+ if (isspace(tmp[0]) && isspace(tmp[1])) { 77.62 -+ memmove(tmp, tmp+1, strlen(tmp)); 77.63 -+ continue; 77.64 -+ } 77.65 -+ ++tmp; 77.66 -+ } 77.67 -+} 77.68 -+ 77.69 -+static int __linux_procinfo(int x, char *fstr, size_t s) 77.70 -+{ 77.71 -+ FILE *fp; 77.72 -+ 77.73 -+ char *procinfo_keys[] = { 77.74 -+ /* --processor --hardware-platform */ 77.75 -+ #if defined(__alpha__) 77.76 -+ "cpu model", "system type" 77.77 -+ #elif defined(__arm__) 77.78 -+ "Processor", "Hardware" 77.79 -+ #elif defined(__avr32__) 77.80 -+ "processor", "cpu family" 77.81 -+ #elif defined(__bfin__) 77.82 -+ "CPU", "BOARD Name" 77.83 -+ #elif defined(__cris__) 77.84 -+ "cpu", "cpu model" 77.85 -+ #elif defined(__frv__) 77.86 -+ "CPU-Core", "System" 77.87 -+ #elif defined(__i386__) || defined(__x86_64__) 77.88 -+ "model name", "vendor_id" 77.89 -+ #elif defined(__ia64__) 77.90 -+ "family", "vendor" 77.91 -+ #elif defined(__hppa__) 77.92 -+ "cpu", "model" 77.93 -+ #elif defined(__m68k__) 77.94 -+ "CPU", "MMU" 77.95 -+ #elif defined(__mips__) 77.96 -+ "cpu model", "system type" 77.97 -+ #elif defined(__powerpc__) || defined(__powerpc64__) 77.98 -+ "cpu", "machine" 77.99 -+ #elif defined(__s390__) || defined(__s390x__) 77.100 -+ "Type", "Manufacturer" 77.101 -+ #elif defined(__sh__) 77.102 -+ "cpu type", "machine" 77.103 -+ #elif defined(sparc) || defined(__sparc__) 77.104 -+ "type", "cpu" 77.105 -+ #elif defined(__vax__) 77.106 -+ "cpu type", "cpu" 77.107 -+ #else 77.108 -+ "unknown", "unknown" 77.109 -+ #endif 77.110 -+ }; 77.111 -+ 77.112 -+ if ((fp = fopen(CPUINFO_FILE, "r")) != NULL) { 77.113 -+ char key[65], value[257], eol, *ret = NULL; 77.114 -+ 77.115 -+ while (fscanf(fp, CPUINFO_FORMAT, key, value, &eol) != EOF) { 77.116 -+ __eat_cpuinfo_space(key); 77.117 -+ if (!strcmp(key, procinfo_keys[x])) { 77.118 -+ __eat_cpuinfo_space(value); 77.119 -+ ret = value; 77.120 -+ break; 77.121 -+ } 77.122 -+ if (eol != '\n') { 77.123 -+ /* we need two fscanf's here in case the previous 77.124 -+ * length limit caused us to read right up to the 77.125 -+ * newline ... doing "%*[^\n]\n" wont eat the newline 77.126 -+ */ 77.127 -+ fscanf(fp, "%*[^\n]"); 77.128 -+ fscanf(fp, "\n"); 77.129 -+ } 77.130 -+ } 77.131 -+ fclose(fp); 77.132 -+ 77.133 -+ if (ret) { 77.134 -+ strncpy(fstr, ret, s); 77.135 -+ return 0; 77.136 -+ } 77.137 -+ } 77.138 -+ 77.139 -+ return -1; 77.140 -+} 77.141 -+ 77.142 -+#endif 77.143 -+ 77.144 - /* Print ELEMENT, preceded by a space if something has already been 77.145 - printed. */ 77.146 - 77.147 -@@ -250,10 +344,14 @@ main (int argc, char **argv) 77.148 - if (toprint & PRINT_PROCESSOR) 77.149 - { 77.150 - char const *element = unknown; 77.151 --#if HAVE_SYSINFO && defined SI_ARCHITECTURE 77.152 -+#if ( HAVE_SYSINFO && defined SI_ARCHITECTURE ) || defined(USE_PROCINFO) 77.153 - { 77.154 - static char processor[257]; 77.155 -+#if defined(USE_PROCINFO) 77.156 -+ if (0 <= __linux_procinfo (PROCINFO_PROCESSOR, processor, sizeof processor)) 77.157 -+#else 77.158 - if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) 77.159 -+#endif 77.160 - element = processor; 77.161 - } 77.162 - #endif 77.163 -@@ -306,9 +404,13 @@ main (int argc, char **argv) 77.164 - if (element == unknown) 77.165 - { 77.166 - static char hardware_platform[257]; 77.167 -+#if defined(USE_PROCINFO) 77.168 -+ if (0 <= __linux_procinfo (PROCINFO_HARDWARE_PLATFORM, hardware_platform, sizeof hardware_platform)) 77.169 -+#else 77.170 - size_t s = sizeof hardware_platform; 77.171 - static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM }; 77.172 - if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0) 77.173 -+#endif 77.174 - element = hardware_platform; 77.175 - } 77.176 - #endif
78.1 --- a/libpng-dev/receipt Sat May 27 16:29:45 2017 +0300 78.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 78.3 @@ -1,19 +0,0 @@ 78.4 -# SliTaz package receipt. 78.5 - 78.6 -PACKAGE="libpng-dev" 78.7 -VERSION="1.6.28" 78.8 -CATEGORY="development" 78.9 -SHORT_DESC="Development files for libpng (with APNG support)" 78.10 -MAINTAINER="al.bobylev@gmail.com" 78.11 -LICENSE="zlib/libpng" 78.12 -WEB_SITE="http://libpng.org/pub/png/libpng.html" 78.13 -HOST_ARCH="i486 arm" 78.14 - 78.15 -WANTED="libpng" 78.16 -DEPENDS="libpng" 78.17 - 78.18 -# Rules to gen a SliTaz package suitable for Tazpkg. 78.19 -genpkg_rules() 78.20 -{ 78.21 - cook_copy_files libpng*-config *.h *.la *.pc 78.22 -}
79.1 --- a/libpng/receipt Sat May 27 16:29:45 2017 +0300 79.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 79.3 @@ -1,42 +0,0 @@ 79.4 -# SliTaz package receipt. 79.5 - 79.6 -PACKAGE="libpng" 79.7 -VERSION="1.6.28" 79.8 -CATEGORY="libs" 79.9 -SHORT_DESC="PNG images library (with APNG support)" 79.10 -MAINTAINER="al.bobylev@gmail.com" 79.11 -LICENSE="zlib/libpng" 79.12 -WEB_SITE="http://www.libpng.org/pub/png/libpng.html" 79.13 -HOST_ARCH="i486 arm" 79.14 - 79.15 -TARBALL="$PACKAGE-$VERSION.tar.xz" 79.16 -WGET_URL="$SF_MIRROR/libpng/$TARBALL" 79.17 - 79.18 -PATCH="$PACKAGE-$VERSION-apng.patch.gz" 79.19 -PATCH_URL="$SF_MIRROR/apng/$PATCH" 79.20 - 79.21 -DEPENDS="zlib" 79.22 -BUILD_DEPENDS="gawk zlib-dev" 79.23 - 79.24 -# Rules to configure and make the package. 79.25 -compile_rules() 79.26 -{ 79.27 - [ -s "$SRC/$PATCH" ] || wget -O "$SRC/$PATCH" $PATCH_URL 79.28 - gzip -cd $SRC/$PATCH | patch -p0 79.29 - 79.30 - ./configure \ 79.31 - --disable-static \ 79.32 - $CONFIGURE_ARGS && 79.33 - make && make install 79.34 - 79.35 - # Misc png tools 79.36 - cd contrib/pngminus 79.37 - make PNGLIB="-L$DESTDIR/usr/lib -lpng" -f makefile.std png2pnm pnm2png 79.38 - cp -a png2pnm pnm2png $DESTDIR/usr/bin 79.39 -} 79.40 - 79.41 -# Rules to gen a SliTaz package suitable for Tazpkg. 79.42 -genpkg_rules() 79.43 -{ 79.44 - cook_copy_files png2pnm pnm2png pngfix png-fix-itxt *.so* 79.45 -}
80.1 --- a/libpng12-dev/receipt Sat May 27 16:29:45 2017 +0300 80.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 80.3 @@ -1,19 +0,0 @@ 80.4 -# SliTaz package receipt. 80.5 - 80.6 -PACKAGE="libpng12-dev" 80.7 -VERSION="1.2.57" 80.8 -CATEGORY="development" 80.9 -SHORT_DESC="PNG images library (1.2 series, with APNG support, development files)" 80.10 -MAINTAINER="al.bobylev@gmail.com" 80.11 -LICENSE="zlib/libpng" 80.12 -WEB_SITE="http://libpng.org/pub/png/libpng.html" 80.13 -HOST_ARCH="i486 arm" 80.14 - 80.15 -WANTED="libpng12" 80.16 -DEPENDS="libpng12" 80.17 - 80.18 -# Rules to gen a SliTaz package suitable for Tazpkg. 80.19 -genpkg_rules() 80.20 -{ 80.21 - cook_copy_files libpng*-config *.h *.la *.pc 80.22 -}
81.1 --- a/libpng12/receipt Sat May 27 16:29:45 2017 +0300 81.2 +++ b/libpng12/receipt Sat May 27 16:55:17 2017 +0300 81.3 @@ -1,9 +1,9 @@ 81.4 -# SliTaz package receipt. 81.5 +# SliTaz package receipt v2. 81.6 81.7 PACKAGE="libpng12" 81.8 VERSION="1.2.57" 81.9 CATEGORY="libs" 81.10 -SHORT_DESC="PNG images library (1.2 series, with APNG support)" 81.11 +SHORT_DESC="PNG images library 1.2 series with APNG support" 81.12 MAINTAINER="al.bobylev@gmail.com" 81.13 LICENSE="zlib/libpng" 81.14 WEB_SITE="http://www.libpng.org/pub/png/libpng.html" 81.15 @@ -15,8 +15,8 @@ 81.16 PATCH="libpng-$VERSION-apng.patch.gz" 81.17 PATCH_URL="$SF_MIRROR/apng/$PATCH" 81.18 81.19 -DEPENDS="zlib" 81.20 BUILD_DEPENDS="gawk zlib-dev" 81.21 +SPLIT="libpng12-dev" 81.22 81.23 # Rules to configure and make the package. 81.24 compile_rules() 81.25 @@ -33,5 +33,13 @@ 81.26 # Rules to gen a SliTaz package suitable for Tazpkg. 81.27 genpkg_rules() 81.28 { 81.29 - cook_copy_files *.so* 81.30 + case $PACKAGE in 81.31 + libpng12) 81.32 + copy @std 81.33 + DEPENDS="zlib" 81.34 + ;; 81.35 + libpng12-dev) 81.36 + copy @dev 81.37 + ;; 81.38 + esac 81.39 }
82.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 82.2 +++ b/libpng16/receipt Sat May 27 16:55:17 2017 +0300 82.3 @@ -0,0 +1,52 @@ 82.4 +# SliTaz package receipt v2. 82.5 + 82.6 +PACKAGE="libpng16" 82.7 +VERSION="1.6.28" 82.8 +CATEGORY="libs" 82.9 +SHORT_DESC="PNG images library 1.6 series with APNG support" 82.10 +MAINTAINER="al.bobylev@gmail.com" 82.11 +LICENSE="zlib/libpng" 82.12 +WEB_SITE="http://www.libpng.org/pub/png/libpng.html" 82.13 +HOST_ARCH="i486 arm" 82.14 + 82.15 +TARBALL="libpng-$VERSION.tar.xz" 82.16 +WGET_URL="$SF_MIRROR/libpng/$TARBALL" 82.17 + 82.18 +PATCH="libpng-$VERSION-apng.patch.gz" 82.19 +PATCH_URL="$SF_MIRROR/apng/$PATCH" 82.20 + 82.21 +BUILD_DEPENDS="gawk zlib-dev" 82.22 +SPLIT="libpng16-dev" 82.23 + 82.24 +# Rules to configure and make the package. 82.25 +compile_rules() 82.26 +{ 82.27 + [ -s "$SRC/$PATCH" ] || wget -O "$SRC/$PATCH" $PATCH_URL 82.28 + gzip -cd $SRC/$PATCH | patch -p0 82.29 + 82.30 + ./configure \ 82.31 + --disable-static \ 82.32 + $CONFIGURE_ARGS && 82.33 + make && make install 82.34 + 82.35 + # Misc png tools 82.36 + cd contrib/pngminus 82.37 + make PNGLIB="-L$DESTDIR/usr/lib -lpng" -f makefile.std png2pnm pnm2png 82.38 + cp -a png2pnm pnm2png $DESTDIR/usr/bin 82.39 +} 82.40 + 82.41 +# Rules to gen a SliTaz package suitable for Tazpkg. 82.42 +genpkg_rules() 82.43 +{ 82.44 + case $PACKAGE in 82.45 + libpng16) 82.46 + copy @std 82.47 + DEPENDS="zlib" 82.48 + PROVIDE="libpng" 82.49 + ;; 82.50 + libpng16-dev) 82.51 + copy @dev 82.52 + PROVIDE="libpng-dev" 82.53 + ;; 82.54 + esac 82.55 +}
83.1 --- a/libwebp-apps/receipt Sat May 27 16:29:45 2017 +0300 83.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 83.3 @@ -1,19 +0,0 @@ 83.4 -# SliTaz package receipt. 83.5 - 83.6 -PACKAGE="libwebp-apps" 83.7 -VERSION="0.5.1" 83.8 -CATEGORY="x-window" 83.9 -SHORT_DESC="WebP image library (applications)" 83.10 -MAINTAINER="al.bobylev@gmail.com" 83.11 -LICENSE="BSD" 83.12 -WEB_SITE="https://www.webmproject.org/" 83.13 -HOST_ARCH="i486 arm" 83.14 - 83.15 -WANTED="libwebp" 83.16 -DEPENDS="giflib libjpeg-turbo libpng libwebp tiff" 83.17 - 83.18 -# Rules to gen a SliTaz package suitable for Tazpkg. 83.19 -genpkg_rules() 83.20 -{ 83.21 - cook_copy_folders bin 83.22 -}
84.1 --- a/libwebp-dev/receipt Sat May 27 16:29:45 2017 +0300 84.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 84.3 @@ -1,18 +0,0 @@ 84.4 -# SliTaz package receipt. 84.5 - 84.6 -PACKAGE="libwebp-dev" 84.7 -VERSION="0.5.1" 84.8 -CATEGORY="development" 84.9 -SHORT_DESC="WebP image library (development files)" 84.10 -MAINTAINER="pankso@slitaz.org" 84.11 -LICENSE="BSD" 84.12 -WEB_SITE="https://www.webmproject.org/" 84.13 -HOST_ARCH="i486 arm" 84.14 - 84.15 -WANTED="libwebp" 84.16 - 84.17 -# Rules to gen a SliTaz package suitable for Tazpkg. 84.18 -genpkg_rules() 84.19 -{ 84.20 - cook_copy_files *.h *.la *.pc 84.21 -}
85.1 --- a/libwebp/receipt Sat May 27 16:29:45 2017 +0300 85.2 +++ b/libwebp/receipt Sat May 27 16:55:17 2017 +0300 85.3 @@ -1,9 +1,9 @@ 85.4 -# SliTaz package receipt. 85.5 +# SliTaz package receipt v2. 85.6 85.7 PACKAGE="libwebp" 85.8 VERSION="0.5.1" 85.9 CATEGORY="x-window" 85.10 -SHORT_DESC="WebP image library." 85.11 +SHORT_DESC="WebP image library" 85.12 MAINTAINER="devl547@gmail.com" 85.13 LICENSE="BSD" 85.14 WEB_SITE="https://www.webmproject.org/" 85.15 @@ -32,5 +32,17 @@ 85.16 # Rules to gen a SliTaz package suitable for Tazpkg. 85.17 genpkg_rules() 85.18 { 85.19 - cook_copy_files *.so* 85.20 + case $PACKAGE in 85.21 + libwebp) 85.22 + copy *.so* 85.23 + ;; 85.24 + libwebp-apps) 85.25 + copy bin/ 85.26 + CAT="x-window|applications" 85.27 + DEPENDS="giflib libjpeg-turbo libpng libwebp tiff" 85.28 + ;; 85.29 + libwebp-dev) 85.30 + copy @dev 85.31 + ;; 85.32 + esac 85.33 }
86.1 --- a/libxml2-dev/receipt Sat May 27 16:29:45 2017 +0300 86.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 86.3 @@ -1,19 +0,0 @@ 86.4 -# SliTaz package receipt. 86.5 - 86.6 -PACKAGE="libxml2-dev" 86.7 -VERSION="2.9.4" 86.8 -CATEGORY="development" 86.9 -SHORT_DESC="XML C parser and toolkit devel files." 86.10 -MAINTAINER="pankso@slitaz.org" 86.11 -LICENSE="MIT" 86.12 -WEB_SITE="http://xmlsoft.org/" 86.13 -HOST_ARCH="i486 arm" 86.14 - 86.15 -WANTED="libxml2" 86.16 -DEPENDS="libxml2-tools pkg-config zlib-dev liblzma-dev" 86.17 - 86.18 -# Rules to gen a SliTaz package suitable for Tazpkg. 86.19 -genpkg_rules() 86.20 -{ 86.21 - cook_copy_files xml2-config *.h *.cmake *.pc libxml2.la *.sh *.m4 86.22 -}
87.1 --- a/libxml2-python/receipt Sat May 27 16:29:45 2017 +0300 87.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 87.3 @@ -1,20 +0,0 @@ 87.4 -# SliTaz package receipt. 87.5 - 87.6 -PACKAGE="libxml2-python" 87.7 -VERSION="2.9.4" 87.8 -CATEGORY="development" 87.9 -SHORT_DESC="Libxml2 adapter for the Python." 87.10 -MAINTAINER="pascal.bellard@slitaz.org" 87.11 -LICENSE="MIT" 87.12 -WEB_SITE="http://xmlsoft.org/" 87.13 -#HOST_ARCH="arm i486" 87.14 - 87.15 -WANTED="libxml2" 87.16 -DEPENDS="python libxml2 libxslt" 87.17 - 87.18 -# Rules to gen a SliTaz package suitable for Tazpkg. 87.19 -genpkg_rules() 87.20 -{ 87.21 - mkdir -p $fs/usr/lib 87.22 - cp -a $install/usr/lib/python* $fs/usr/lib 87.23 -}
88.1 --- a/libxml2-tools/receipt Sat May 27 16:29:45 2017 +0300 88.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 88.3 @@ -1,19 +0,0 @@ 88.4 -# SliTaz package receipt. 88.5 - 88.6 -PACKAGE="libxml2-tools" 88.7 -VERSION="2.9.4" 88.8 -CATEGORY="system-tools" 88.9 -SHORT_DESC="The xmllint tester and xmlcatalog parser utility." 88.10 -MAINTAINER="pankso@slitaz.org" 88.11 -LICENSE="MIT" 88.12 -WEB_SITE="http://xmlsoft.org/" 88.13 -HOST_ARCH="i486 arm" 88.14 - 88.15 -WANTED="libxml2" 88.16 -DEPENDS="libxml2" 88.17 - 88.18 -# Rules to gen a SliTaz package suitable for Tazpkg. 88.19 -genpkg_rules() 88.20 -{ 88.21 - cook_copy_files xmllint xmlcatalog 88.22 -}
89.1 --- a/libxml2/receipt Sat May 27 16:29:45 2017 +0300 89.2 +++ b/libxml2/receipt Sat May 27 16:55:17 2017 +0300 89.3 @@ -1,9 +1,9 @@ 89.4 -# SliTaz package receipt. 89.5 +# SliTaz package receipt v2. 89.6 89.7 PACKAGE="libxml2" 89.8 VERSION="2.9.4" 89.9 CATEGORY="system-tools" 89.10 -SHORT_DESC="Libxml2 is the XML C parser and toolkit." 89.11 +SHORT_DESC="XML C parser and toolkit" 89.12 MAINTAINER="pankso@slitaz.org" 89.13 LICENSE="MIT" 89.14 WEB_SITE="http://xmlsoft.org/" 89.15 @@ -12,19 +12,15 @@ 89.16 TARBALL="$PACKAGE-$VERSION.tar.gz" 89.17 WGET_URL="ftp://xmlsoft.org/libxml2/$TARBALL" 89.18 89.19 -DEPENDS="zlib liblzma" 89.20 BUILD_DEPENDS="zlib-dev liblzma-dev python-dev ncurses-dev readline-dev" 89.21 -# autoconf automake libtool 89.22 +BUILD_DEPENDS_arm=" " 89.23 SPLIT="libxml2-tools libxml2-python libxml2-dev" 89.24 89.25 # When cross compiling Python is installed in chroot and is used 89.26 -# by cross tools, cook dont need to install it in /usr/cross/arm 89.27 +# by cross tools, cook don't need to install it in /usr/cross/arm 89.28 # Building with LZMA support is buggy and build fails 89.29 case "$ARCH" in 89.30 - arm) 89.31 - BUILD_DEPENDS="" 89.32 - DEPENDS="zlib" 89.33 - ARCH_ARGS="--without-lzma" ;; 89.34 + arm) ARCH_ARGS="--without-lzma" ;; 89.35 esac 89.36 89.37 # Rules to configure and make the package. 89.38 @@ -49,5 +45,26 @@ 89.39 # Rules to gen a SliTaz package suitable for Tazpkg. 89.40 genpkg_rules() 89.41 { 89.42 - cook_copy_files libxml2.so* 89.43 + case $PACKAGE in 89.44 + libxml2) 89.45 + copy libxml2.so* 89.46 + DEPENDS="zlib liblzma" 89.47 + case "$ARCH" in 89.48 + arm) DEPENDS="zlib" ;; 89.49 + esac 89.50 + ;; 89.51 + libxml2-tools) 89.52 + copy xmllint xmlcatalog 89.53 + CAT="system-tools|xmllint tester and xmlcatalog parser utility" 89.54 + ;; 89.55 + libxml2-python) 89.56 + copy python2.7/; find $fs -name '*.la' -delete 89.57 + CAT="development|adapter for the Python" 89.58 + DEPENDS="python libxml2 libxslt" 89.59 + ;; 89.60 + libxml2-dev) 89.61 + copy @dev *.sh 89.62 + DEPENDS="libxml2-tools pkg-config zlib-dev liblzma-dev" 89.63 + ;; 89.64 + esac 89.65 }