wok-next rev 20436
Update packages listed in the LFS book.
line diff
1.1 --- a/acl/receipt Wed Feb 21 18:10:55 2018 +0200 1.2 +++ b/acl/receipt Wed Feb 21 19:48:17 2018 +0200 1.3 @@ -3,23 +3,20 @@ 1.4 PACKAGE="acl" 1.5 VERSION="2.2.52" 1.6 CATEGORY="system-tools" 1.7 -SHORT_DESC="Commands for Manipulating POSIX Access Control Lists" 1.8 +SHORT_DESC="Commands for manipulating POSIX Access Control Lists" 1.9 MAINTAINER="rcx@zoominternet.net" 1.10 LICENSE="LGPL2.1 GPL2" 1.11 WEB_SITE="http://savannah.nongnu.org/projects/acl/" 1.12 -HOST_ARCH="i486 arm" 1.13 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/acl.html" 1.14 1.15 TARBALL="$PACKAGE-$VERSION.src.tar.gz" 1.16 -WGET_URL="http://download.savannah.gnu.org/releases/$PACKAGE/$TARBALL" 1.17 +WGET_URL="http://download.savannah.gnu.org/releases/acl/$TARBALL" 1.18 1.19 BUILD_DEPENDS="attr-dev bash libtool gettext" 1.20 -BUILD_DEPENDS_arm="attr-dev" 1.21 SPLIT="acl-dev" 1.22 1.23 -# Rules to configure and make the package. 1.24 -compile_rules() 1.25 -{ 1.26 - rm /bin/rpm 1.27 +compile_rules() { 1.28 + rm /bin/rpm 2>/dev/null 1.29 sed -i -e 's|/@pkg_name@|&-@pkg_version@|' include/builddefs.in 1.30 sed -i -e "/TABS-1;/a if (x > (TABS-1)) x = (TABS-1);" \ 1.31 libacl/__acl_to_any_text.c 1.32 @@ -30,24 +27,23 @@ 1.33 --libexecdir=/usr/lib \ 1.34 $CONFIGURE_ARGS && 1.35 make && 1.36 - make install install-lib install-dev DIST_ROOT=$DESTDIR 1.37 + make install install-lib install-dev DIST_ROOT=$DESTDIR || return 1 1.38 1.39 - mkdir $install/lib 1.40 + mkdir -p $install/lib 1.41 mv -v $install/usr/lib/libacl.so.* $install/lib 1.42 ln -sfv ../../lib/$(readlink $install/usr/lib/libacl.so) \ 1.43 $install/usr/lib/libacl.so 1.44 + 1.45 find $install -type f \( -name '*.so*' -o -name '*.la' \) \ 1.46 -exec chmod 755 \{\} \; 1.47 - 1.48 } 1.49 1.50 -# Rules to gen a SliTaz package suitable for Tazpkg. 1.51 -genpkg_rules() 1.52 -{ 1.53 +genpkg_rules() { 1.54 case $PACKAGE in 1.55 acl) 1.56 copy @std 1.57 DEPENDS="attr" 1.58 + TAGS="LFS" 1.59 ;; 1.60 acl-dev) 1.61 copy @dev
2.1 --- a/attr/receipt Wed Feb 21 18:10:55 2018 +0200 2.2 +++ b/attr/receipt Wed Feb 21 19:48:17 2018 +0200 2.3 @@ -3,23 +3,21 @@ 2.4 PACKAGE="attr" 2.5 VERSION="2.4.47" 2.6 CATEGORY="system-tools" 2.7 -SHORT_DESC="Commands for Manipulating Filesystem Extended Attributes" 2.8 +SHORT_DESC="Commands for manipulating filesystem extended attributes" 2.9 MAINTAINER="rcx@zoominternet.net" 2.10 LICENSE="GPL2" 2.11 WEB_SITE="http://savannah.nongnu.org/projects/attr" 2.12 -HOST_ARCH="i486 arm" 2.13 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/attr.html" 2.14 2.15 TARBALL="$PACKAGE-$VERSION.src.tar.gz" 2.16 -WGET_URL="http://download.savannah.gnu.org/releases/$PACKAGE/$TARBALL" 2.17 +WGET_URL="http://download.savannah.gnu.org/releases/attr/$TARBALL" 2.18 2.19 +BUILD_DEPENDS_arm=" " 2.20 BUILD_DEPENDS="autoconf automake m4 libtool gettext coreutils-operations" 2.21 -BUILD_DEPENDS_arm=" " 2.22 SPLIT="attr-dev" 2.23 2.24 -# Rules to configure and make the package. 2.25 -compile_rules() 2.26 -{ 2.27 - rm /bin/rpm 2.28 +compile_rules() { 2.29 + rm /bin/rpm >/dev/null 2.30 sed -i -e 's|/@pkg_name@|&-@pkg_version@|' include/builddefs.in 2.31 2.32 ./configure \ 2.33 @@ -27,21 +25,23 @@ 2.34 --disable-static \ 2.35 $CONFIGURE_ARGS && 2.36 make && 2.37 - make install install-lib install-dev DIST_ROOT=$DESTDIR 2.38 + make install install-lib install-dev DIST_ROOT=$DESTDIR || return 1 2.39 2.40 mkdir -p $install/lib 2.41 mv $install/usr/lib/libattr.so.* $install/lib 2.42 ln -sf ../../lib/$(readlink $install/usr/lib/libattr.so) \ 2.43 $install/usr/lib/libattr.so 2.44 + 2.45 find $install -type f \( -name '*.so*' -o -name '*.la' \) \ 2.46 -exec chmod 755 \{\} \; 2.47 } 2.48 2.49 -# Rules to gen a SliTaz package suitable for Tazpkg. 2.50 -genpkg_rules() 2.51 -{ 2.52 +genpkg_rules() { 2.53 case $PACKAGE in 2.54 - attr) copy @std ;; 2.55 - attr-dev) copy @dev ;; 2.56 + attr) 2.57 + copy @std 2.58 + TAGS="LFS" 2.59 + ;; 2.60 + *-dev) copy @dev;; 2.61 esac 2.62 }
3.1 --- a/autoconf/receipt Wed Feb 21 18:10:55 2018 +0200 3.2 +++ b/autoconf/receipt Wed Feb 21 19:48:17 2018 +0200 3.3 @@ -6,22 +6,21 @@ 3.4 SHORT_DESC="A GNU tool for automatically configuring source code" 3.5 MAINTAINER="pankso@slitaz.org" 3.6 LICENSE="GPL2" 3.7 -WEB_SITE="https://www.gnu.org/software/autoconf/autoconf.html" 3.8 +WEB_SITE="https://www.gnu.org/software/autoconf/" 3.9 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/autoconf.html" 3.10 +HOST_ARCH="any" 3.11 3.12 TARBALL="$PACKAGE-$VERSION.tar.xz" 3.13 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 3.14 3.15 BUILD_DEPENDS="m4 perl" 3.16 3.17 -# Rules to configure and make the package. 3.18 -compile_rules() 3.19 -{ 3.20 +compile_rules() { 3.21 ./configure $CONFIGURE_ARGS && make && make install 3.22 } 3.23 3.24 -# Rules to gen a SliTaz package suitable for Tazpkg. 3.25 -genpkg_rules() 3.26 -{ 3.27 +genpkg_rules() { 3.28 copy @std @dev 3.29 DEPENDS="m4 perl" 3.30 + TAGS="LFS" 3.31 }
4.1 --- a/automake/receipt Wed Feb 21 18:10:55 2018 +0200 4.2 +++ b/automake/receipt Wed Feb 21 19:48:17 2018 +0200 4.3 @@ -1,33 +1,26 @@ 4.4 # SliTaz package receipt v2. 4.5 4.6 PACKAGE="automake" 4.7 -VERSION="1.15" 4.8 +VERSION="1.15.1" 4.9 CATEGORY="development" 4.10 SHORT_DESC="A GNU tool for automatically creating Makefiles" 4.11 MAINTAINER="pankso@slitaz.org" 4.12 LICENSE="GPL2" 4.13 WEB_SITE="https://www.gnu.org/software/automake/" 4.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/automake.html" 4.15 +HOST_ARCH="i486 x86_64" 4.16 4.17 TARBALL="$PACKAGE-$VERSION.tar.xz" 4.18 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 4.19 4.20 BUILD_DEPENDS="autoconf bison flex gfortran" 4.21 4.22 -# Rules to configure and make the package. 4.23 -compile_rules() 4.24 -{ 4.25 - sed -i 's:/\\\${:/\\\$\\{:' bin/automake.in 4.26 - 4.27 - ./configure \ 4.28 - --docdir=/usr/share/doc/automake-$VERSION \ 4.29 - $CONFIGURE_ARGS && 4.30 - make && 4.31 - make install 4.32 +compile_rules() { 4.33 + ./configure $CONFIGURE_ARGS && make && make install 4.34 } 4.35 4.36 -# Rules to gen a SliTaz package suitable for Tazpkg. 4.37 -genpkg_rules() 4.38 -{ 4.39 +genpkg_rules() { 4.40 copy @std @dev 4.41 DEPENDS="autoconf" 4.42 + TAGS="LFS" 4.43 }
5.1 --- a/bash/receipt Wed Feb 21 18:10:55 2018 +0200 5.2 +++ b/bash/receipt Wed Feb 21 19:48:17 2018 +0200 5.3 @@ -1,14 +1,14 @@ 5.4 # SliTaz package receipt v2. 5.5 5.6 PACKAGE="bash" 5.7 -VERSION="4.4.12" 5.8 +VERSION="4.4.18" 5.9 BASEVERSION="${VERSION%.*}" 5.10 CATEGORY="shells" 5.11 SHORT_DESC="The GNU bourne shell" 5.12 MAINTAINER="pankso@slitaz.org" 5.13 LICENSE="GPL3" 5.14 WEB_SITE="https://www.gnu.org/software/bash/" 5.15 -TAGS="shell" 5.16 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/bash.html" 5.17 5.18 TARBALL="$PACKAGE-$BASEVERSION.tar.gz" 5.19 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 5.20 @@ -21,8 +21,7 @@ 5.21 BUILD_DEPENDS="ncurses-dev readline-dev texinfo gettext patch" 5.22 SPLIT="bash-dev" 5.23 5.24 -patch_bash() 5.25 -{ 5.26 +patch_bash() { 5.27 for i in $BASHPATCHES; do 5.28 [ -s "$SOURCES_REPOSITORY/$i" ] || 5.29 wget -O "$SOURCES_REPOSITORY/$i" \ 5.30 @@ -33,19 +32,17 @@ 5.31 } 5.32 5.33 # Rules to compile & install the temporary toolchain. 5.34 -cook_tmp_toolchain() 5.35 -{ 5.36 +cook_tmp_toolchain() { 5.37 cd $src 5.38 patch_bash 5.39 ./configure --without-bash-malloc && 5.40 make && make install 5.41 } 5.42 5.43 -# Rules to configure and make the package. 5.44 -compile_rules() 5.45 -{ 5.46 +compile_rules() { 5.47 # Patch and then build. 5.48 patch_bash 5.49 + 5.50 # Skip tests that can not run while cross-compiling. 5.51 cat > config.cache <<EOF 5.52 ac_cv_func_mmap_fixed_mapped=yes 5.53 @@ -61,19 +58,20 @@ 5.54 bash_cv_unusable_rtsigs=no 5.55 gt_cv_int_divbyzero_sigfpe=yes 5.56 EOF 5.57 + 5.58 ./configure \ 5.59 - $CONFIGURE_ARGS \ 5.60 --cache-file=config.cache \ 5.61 --bindir=/bin \ 5.62 --enable-history \ 5.63 - --enable-alias \ 5.64 + --enable-alias \ 5.65 --disable-nls \ 5.66 --without-bash-malloc \ 5.67 --disable-help-builtin \ 5.68 - --with-installed-readline && 5.69 + --with-installed-readline \ 5.70 + $CONFIGURE_ARGS && 5.71 make && 5.72 # Bash doesn't care about DESTDIR in environnment variable. 5.73 - make DESTDIR=$DESTDIR install 5.74 + make DESTDIR=$DESTDIR install || return 1 5.75 5.76 # Config files 5.77 cp -a $stuff/etc $install 5.78 @@ -87,23 +85,22 @@ 5.79 tee bashcheck.log 5.80 echo 5.81 grep Vulnerable bashcheck.log && echo "ERROR: Vulnerable" 5.82 + : 5.83 } 5.84 5.85 -# Rules to gen a SliTaz package suitable for Tazpkg. 5.86 -genpkg_rules() 5.87 -{ 5.88 +genpkg_rules() { 5.89 case $PACKAGE in 5.90 bash) 5.91 copy @std 5.92 DEPENDS="ncurses readline" 5.93 + TAGS="LFS shell" 5.94 ;; 5.95 *-dev) copy @dev;; 5.96 esac 5.97 } 5.98 5.99 5.100 -post_install_bash() 5.101 -{ 5.102 +post_install_bash() { 5.103 mkdir -p "$1/etc/skel"; cp -a "$1/etc/bashrc" "$1/etc/skel/.bashrc" 5.104 5.105 # Exit function in non-interactive mode (when user can't answer question) 5.106 @@ -126,8 +123,7 @@ 5.107 } 5.108 5.109 5.110 -pre_remove_bash() 5.111 -{ 5.112 +pre_remove_bash() { 5.113 echo 5.114 echo 'Setting /bin/sh as default shell for all users' 5.115 sed -i 's|:/bin/bash$|:/bin/sh|' "$1/etc/passwd"
6.1 --- a/bc/receipt Wed Feb 21 18:10:55 2018 +0200 6.2 +++ b/bc/receipt Wed Feb 21 19:48:17 2018 +0200 6.3 @@ -1,21 +1,24 @@ 6.4 # SliTaz package receipt v2. 6.5 6.6 PACKAGE="bc" 6.7 -VERSION="1.06.95" 6.8 +VERSION="1.07.1" 6.9 CATEGORY="utilities" 6.10 SHORT_DESC="Bc is a cmdline calculator" 6.11 MAINTAINER="pankso@slitaz.org" 6.12 LICENSE="GPL2 LGPL2.1" 6.13 WEB_SITE="https://www.gnu.org/software/bc/" 6.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/bc.html" 6.15 +HOST_ARCH="i486 x86_64" 6.16 6.17 -TARBALL="$PACKAGE-$VERSION.tar.bz2" 6.18 -WGET_URL="http://alpha.gnu.org/gnu/$PACKAGE/$TARBALL" 6.19 +TARBALL="$PACKAGE-$VERSION.tar.gz" 6.20 +WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 6.21 6.22 BUILD_DEPENDS="flex readline-dev texinfo" 6.23 6.24 -# Rules to configure and make the package. 6.25 -compile_rules() 6.26 -{ 6.27 +compile_rules() { 6.28 + # Change an internal script to use sed instead of ed 6.29 + install -m0755 $stuff/fix-libmath_h bc/fix-libmath_h 6.30 + 6.31 ./configure \ 6.32 --with-readline \ 6.33 $CONFIGURE_ARGS && 6.34 @@ -23,10 +26,8 @@ 6.35 make install 6.36 } 6.37 6.38 -# Rules to gen a SliTaz package suitable for Tazpkg. 6.39 -genpkg_rules() 6.40 -{ 6.41 +genpkg_rules() { 6.42 copy @std 6.43 - TAGS="calculator" 6.44 + TAGS="LFS calculator" 6.45 DEPENDS="ncurses readline" 6.46 }
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/bc/stuff/fix-libmath_h Wed Feb 21 19:48:17 2018 +0200 7.3 @@ -0,0 +1,9 @@ 7.4 +#! /bin/bash 7.5 +sed -e '1 s/^/{"/' \ 7.6 + -e 's/$/",/' \ 7.7 + -e '2,$ s/^/"/' \ 7.8 + -e '$ d' \ 7.9 + -i libmath.h 7.10 + 7.11 +sed -e '$ s/$/0}/' \ 7.12 + -i libmath.h
8.1 --- a/bc/stuff/patches/bc-1.06.95-memory_leak-1.patch Wed Feb 21 18:10:55 2018 +0200 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,41 +0,0 @@ 8.4 -Submitted By: Bruce Dubbs (bdubbs at linuxfromscratch dot org) 8.5 -Date: 2014-04-18 8.6 -Initial Package Version: 1.06.95 8.7 -Origin: Gentoo 8.8 -Description: Fixes memory leaks and an uninitialized variable 8.9 - 8.10 -diff -Naur bc-1.06.95.orig/bc/bc.y bc-1.06.95/bc/bc.y 8.11 ---- bc-1.06.95.orig/bc/bc.y 2006-09-04 21:39:31.000000000 -0500 8.12 -+++ bc-1.06.95/bc/bc.y 2014-04-09 13:27:04.602661243 -0500 8.13 -@@ -569,6 +569,7 @@ 8.14 - generate (">"); 8.15 - break; 8.16 - } 8.17 -+ free($2); 8.18 - } 8.19 - | expression '+' expression 8.20 - { 8.21 -diff -Naur bc-1.06.95.orig/bc/storage.c bc-1.06.95/bc/storage.c 8.22 ---- bc-1.06.95.orig/bc/storage.c 2006-09-04 21:39:31.000000000 -0500 8.23 -+++ bc-1.06.95/bc/storage.c 2014-04-09 13:28:11.770763410 -0500 8.24 -@@ -99,6 +99,7 @@ 8.25 - { 8.26 - f = &functions[indx]; 8.27 - f->f_defined = FALSE; 8.28 -+ f->f_void = FALSE; 8.29 - f->f_body = (char *) bc_malloc (BC_START_SIZE); 8.30 - f->f_body_size = BC_START_SIZE; 8.31 - f->f_code_size = 0; 8.32 -diff -Naur bc-1.06.95.orig/bc/util.c bc-1.06.95/bc/util.c 8.33 ---- bc-1.06.95.orig/bc/util.c 2006-09-04 21:39:31.000000000 -0500 8.34 -+++ bc-1.06.95/bc/util.c 2014-04-09 13:27:39.841190064 -0500 8.35 -@@ -602,8 +602,7 @@ 8.36 - case FUNCTDEF: 8.37 - if (id->f_name != 0) 8.38 - { 8.39 -- if (namekind != FUNCT) 8.40 -- free(name); 8.41 -+ free(name); 8.42 - /* Check to see if we are redefining a math lib function. */ 8.43 - if (use_math && namekind == FUNCTDEF && id->f_name <= 6) 8.44 - id->f_name = next_func++;
9.1 --- a/bc/stuff/patches/series Wed Feb 21 18:10:55 2018 +0200 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,1 +0,0 @@ 9.4 -bc-1.06.95-memory_leak-1.patch
10.1 --- a/binutils/receipt Wed Feb 21 18:10:55 2018 +0200 10.2 +++ b/binutils/receipt Wed Feb 21 19:48:17 2018 +0200 10.3 @@ -1,40 +1,35 @@ 10.4 # SliTaz package receipt v2. 10.5 10.6 PACKAGE="binutils" 10.7 -VERSION="2.27" 10.8 +VERSION="2.29" 10.9 CATEGORY="development" 10.10 SHORT_DESC="GNU assembler, linker and binary utilities" 10.11 MAINTAINER="pankso@slitaz.org" 10.12 LICENSE="GPL2 LGPL2 GPL3 LGPL3" 10.13 WEB_SITE="http://www.gnu.org/software/binutils/" 10.14 -TAGS="assembler linker" 10.15 -HOST_ARCH="i486 arm" 10.16 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/binutils.html" 10.17 10.18 TARBALL="$PACKAGE-$VERSION.tar.bz2" 10.19 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 10.20 10.21 +BUILD_DEPENDS_arm=" " 10.22 BUILD_DEPENDS="glibc-dev zlib-dev texinfo bison flex gettext-tools" 10.23 -BUILD_DEPENDS_arm=" " 10.24 -SPLIT="libbfd" 10.25 +SPLIT="libbfd binutils" 10.26 10.27 -# Rules to configure and make the package. 10.28 -compile_rules() 10.29 -{ 10.30 - case "$ARCH" in 10.31 - i?86) ARCH_ARGS="--disable-werror" ;; 10.32 - esac 10.33 - 10.34 - mkdir build; cd build 10.35 +compile_rules() { 10.36 + mkdir build 10.37 + cd build 10.38 10.39 $src/configure \ 10.40 --enable-gold \ 10.41 --enable-ld=default \ 10.42 --enable-plugins \ 10.43 --enable-shared \ 10.44 + --disable-werror \ 10.45 --with-system-zlib \ 10.46 - $CONFIGURE_ARGS $ARCH_ARGS && 10.47 + $CONFIGURE_ARGS && 10.48 make tooldir=/usr && 10.49 - make tooldir=/usr install 10.50 + make tooldir=/usr install || return 1 10.51 10.52 # Create prefixed version of the tools. 10.53 cd $install/usr/bin 10.54 @@ -44,27 +39,21 @@ 10.55 ln -s $TOOLPREFIX$i $i 10.56 done 10.57 10.58 - # Remove prefix from manpages name 10.59 - for i in $(find $install/usr/share/man/man1 -type f); do 10.60 - mv $i ${i/$TOOLPREFIX/} 10.61 - done 10.62 - 10.63 # # Install libiberty (-liberty flag): dependency described in *.la files 10.64 # install -o root -g root -m 644 $src/include/libiberty.h $install/usr/include 10.65 } 10.66 10.67 -# Rules to gen a SliTaz package suitable for Tazpkg. 10.68 -genpkg_rules() 10.69 -{ 10.70 +genpkg_rules() { 10.71 case $PACKAGE in 10.72 - binutils) 10.73 - copy @std @dev 10.74 - DEPENDS="glibc zlib flex libbfd" 10.75 - ;; 10.76 libbfd) 10.77 copy libbfd*.so 10.78 CAT="system-tools|Binary File Descriptor library" 10.79 DEPENDS="zlib" 10.80 ;; 10.81 + binutils) 10.82 + copy @std @dev @rm 10.83 + DEPENDS="flex libbfd glibc" 10.84 + TAGS="LFS assembler linker" 10.85 + ;; 10.86 esac 10.87 }
11.1 --- a/bison/receipt Wed Feb 21 18:10:55 2018 +0200 11.2 +++ b/bison/receipt Wed Feb 21 19:48:17 2018 +0200 11.3 @@ -7,26 +7,20 @@ 11.4 MAINTAINER="pankso@slitaz.org" 11.5 LICENSE="GPL3" 11.6 WEB_SITE="https://www.gnu.org/software/bison/" 11.7 -TAGS="parser language" 11.8 -HOST_ARCH="i486 arm" 11.9 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/bison.html" 11.10 11.11 TARBALL="$PACKAGE-$VERSION.tar.xz" 11.12 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 11.13 11.14 BUILD_DEPENDS="m4 perl libxslt gettext" 11.15 11.16 -# Rules to configure and make the package. 11.17 -compile_rules() 11.18 -{ 11.19 - ./configure \ 11.20 - --docdir=/usr/share/doc/bison-$VERSION \ 11.21 - $CONFIGURE_ARGS && 11.22 - make && make install 11.23 +compile_rules() { 11.24 + ./configure $CONFIGURE_ARGS && make && make install 11.25 } 11.26 11.27 -# Rules to gen a SliTaz package suitable for Tazpkg. 11.28 -genpkg_rules() 11.29 -{ 11.30 - copy bin/ lib/ aclocal/ bison/ 11.31 +genpkg_rules() { 11.32 + copy @std @dev 11.33 + rm -rf $fs/usr/share/doc # one *.h file copied here with @dev 11.34 DEPENDS="m4" 11.35 + TAGS="LFS parser language" 11.36 }
12.1 --- a/bzip2/receipt Wed Feb 21 18:10:55 2018 +0200 12.2 +++ b/bzip2/receipt Wed Feb 21 19:48:17 2018 +0200 12.3 @@ -7,43 +7,45 @@ 12.4 MAINTAINER="pankso@slitaz.org" 12.5 LICENSE="BSD" 12.6 WEB_SITE="http://www.bzip.org/" 12.7 -TAGS="compression archive" 12.8 -HOST_ARCH="i486 arm" 12.9 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/bzip2.html" 12.10 12.11 TARBALL="$PACKAGE-$VERSION.tar.gz" 12.12 WGET_URL="http://www.bzip.org/$VERSION/$TARBALL" 12.13 12.14 SPLIT="bzlib bzip2-apps bzip2-dev" 12.15 12.16 -# Rules to configure and make the package. 12.17 -compile_rules() 12.18 -{ 12.19 - # No configure script, we must used CC, AR and RANLIB set by cook. 12.20 +compile_rules() { 12.21 case "$ARCH" in 12.22 arm*) 12.23 - make -f Makefile-libbz2_so CC=${CC} AR=${AR} RANLIB=${RANLIB} && 12.24 - make clean && make CC=${CC} AR=${AR} RANLIB=${RANLIB} ;; 12.25 + # No configure script, we must used CC, AR and RANLIB set by cook. 12.26 + make -f Makefile-libbz2_so CC=$CC AR=$AR RANLIB=$RANLIB && 12.27 + make clean && make CC=$CC AR=$AR RANLIB=$RANLIB ;; 12.28 *) 12.29 + # add large-file support 12.30 + sed -i 's/^CFLAGS=\(.*\)$/CFLAGS=\1 \$(BIGFILES)/' ./Makefile-libbz2_so 12.31 + 12.32 make -f Makefile-libbz2_so && 12.33 make clean && make ;; 12.34 - esac 12.35 + esac && 12.36 12.37 - make install 12.38 + make install || return 1 12.39 + 12.40 + rm $install/usr/bin/bunzip2 $install/usr/bin/bzcat 12.41 + ln -s bzip2 $install/bin/bunzip2 12.42 + ln -s bzip2 $install/bin/bzcat 12.43 } 12.44 12.45 # Just to be sure when cross-compiling. 12.46 -testsuite() 12.47 -{ 12.48 +testsuite() { 12.49 readelf -h $src/bzip2-shared 12.50 } 12.51 12.52 -# Rules to gen a SliTaz package suitable for Tazpkg. 12.53 -genpkg_rules() 12.54 -{ 12.55 +genpkg_rules() { 12.56 case $PACKAGE in 12.57 bzip2) 12.58 copy bzip2 bunzip2 bzcat 12.59 DEPENDS="bzlib" 12.60 + TAGS="LFS compression archive" 12.61 ;; 12.62 bzlib) 12.63 copy *.so* 12.64 @@ -51,8 +53,7 @@ 12.65 CAT="libs|library" 12.66 ;; 12.67 bzip2-apps) 12.68 - copy bin/ 12.69 - remove_already_packed 12.70 + copy bin/ @rm 12.71 DEPENDS="bzlib" 12.72 CAT="utilities|apps" 12.73 ;;
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/bzip2/stuff/patches/bzip2-1.0.4-bzip2recover.patch Wed Feb 21 19:48:17 2018 +0200 13.3 @@ -0,0 +1,12 @@ 13.4 +--- bzip2-1.0.4/bzip2recover.c.pom 2007-01-03 03:00:55.000000000 +0100 13.5 ++++ bzip2-1.0.4/bzip2recover.c 2007-02-05 11:55:17.000000000 +0100 13.6 +@@ -309,7 +309,8 @@ 13.7 + UInt32 buffHi, buffLo, blockCRC; 13.8 + Char* p; 13.9 + 13.10 +- strcpy ( progName, argv[0] ); 13.11 ++ strncpy ( progName, argv[0], BZ_MAX_FILENAME-1); 13.12 ++ progName[BZ_MAX_FILENAME-1]='\0'; 13.13 + inFileName[0] = outFileName[0] = 0; 13.14 + 13.15 + fprintf ( stderr,
14.1 --- a/bzip2/stuff/patches/bzip2-1.0.6-fix_install.patch Wed Feb 21 18:10:55 2018 +0200 14.2 +++ b/bzip2/stuff/patches/bzip2-1.0.6-fix_install.patch Wed Feb 21 19:48:17 2018 +0200 14.3 @@ -14,7 +14,7 @@ 14.4 bzlib.o 14.5 14.6 -all: libbz2.a bzip2 bzip2recover test 14.7 -+all: libbz2.a bzip2 bzip2recover 14.8 ++all: bzip2 bzip2recover 14.9 14.10 bzip2: libbz2.a bzip2.o 14.11 $(CC) $(CFLAGS) $(LDFLAGS) -o bzip2 bzip2.o -L. -lbz2
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/bzip2/stuff/patches/bzip2recover-CVE-2016-3189.patch Wed Feb 21 19:48:17 2018 +0200 15.3 @@ -0,0 +1,11 @@ 15.4 +diff -up ./bzip2recover.c.old ./bzip2recover.c 15.5 +--- ./bzip2recover.c.old 2016-03-22 08:49:38.855620000 +0100 15.6 ++++ ./bzip2recover.c 2016-03-30 10:22:27.341430099 +0200 15.7 +@@ -458,6 +458,7 @@ Int32 main ( Int32 argc, Char** argv ) 15.8 + bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 ); 15.9 + bsPutUInt32 ( bsWr, blockCRC ); 15.10 + bsClose ( bsWr ); 15.11 ++ outFile = NULL; 15.12 + } 15.13 + if (wrBlock >= rbCtr) break; 15.14 + wrBlock++;
16.1 --- a/bzip2/stuff/patches/series Wed Feb 21 18:10:55 2018 +0200 16.2 +++ b/bzip2/stuff/patches/series Wed Feb 21 19:48:17 2018 +0200 16.3 @@ -1,2 +1,4 @@ 16.4 bzip2-1.0.6-install_docs-1.patch 16.5 -bzip2-1.0.6-fix_install.patch 16.6 +-p1|bzip2-1.0.6-fix_install.patch 16.7 +bzip2-1.0.4-bzip2recover.patch 16.8 +bzip2recover-CVE-2016-3189.patch # https://bugzilla.redhat.com/attachment.cgi?id=1169843
17.1 --- a/check/receipt Wed Feb 21 18:10:55 2018 +0200 17.2 +++ b/check/receipt Wed Feb 21 19:48:17 2018 +0200 17.3 @@ -7,27 +7,23 @@ 17.4 MAINTAINER="erjo@slitaz.org" 17.5 LICENSE="LGPL2.1" 17.6 WEB_SITE="https://libcheck.github.io/check/" 17.7 -HOST_ARCH="i486 arm" 17.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter05/check.html" 17.9 17.10 TARBALL="$PACKAGE-$VERSION.tar.gz" 17.11 WGET_URL="https://github.com/libcheck/check/releases/download/$VERSION/$TARBALL" 17.12 17.13 SPLIT="check-dev" 17.14 17.15 -# Rules to configure and make the package. 17.16 -compile_rules() 17.17 -{ 17.18 +compile_rules() { 17.19 ./configure \ 17.20 --disable-static \ 17.21 $CONFIGURE_ARGS && 17.22 make && make install 17.23 } 17.24 17.25 -# Rules to gen a SliTaz package suitable for Tazpkg. 17.26 -genpkg_rules() 17.27 -{ 17.28 +genpkg_rules() { 17.29 case $PACKAGE in 17.30 check) copy *.so* ;; 17.31 - check-dev) copy @dev checkmk ;; 17.32 + *-dev) copy @dev checkmk ;; 17.33 esac 17.34 }
18.1 --- a/coreutils-multicall/description.txt Wed Feb 21 18:10:55 2018 +0200 18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 18.3 @@ -1,108 +0,0 @@ 18.4 -Coreutils: Core GNU (file, text, shell) utilities. 18.5 - 18.6 - * [ exit with the status determined by expression 18.7 - * base32: base32 encode/decode data and print to standard output 18.8 - * base64: base64 encode/decode data and print to standard output 18.9 - * basename: strip directory and suffix from filenames 18.10 - * cat: concatenate files and print on the standard output 18.11 - * chcon: change file SELinux security context 18.12 - * chgrp: change group ownership 18.13 - * chmod: change file mode bits 18.14 - * chown: change file owner and group 18.15 - * chroot: run command or interactive shell with special root directory 18.16 - * cksum: checksum and count the bytes in a file 18.17 - * comm: compare two sorted files line by line 18.18 - * cp: copy files and directories 18.19 - * csplit: split a file into sections determined by context lines 18.20 - * cut: remove sections from each line of files 18.21 - * date: print or set the system date and time 18.22 - * dd: convert and copy a file 18.23 - * df: report file system disk space usage 18.24 - * dir: list directory contents 18.25 - * dircolors: color setup for ls 18.26 - * dirname: strip last component from file name 18.27 - * du: estimate file space usage 18.28 - * echo: display a line of text 18.29 - * env: run a program in a modified environment 18.30 - * expand: convert tabs to spaces 18.31 - * expr: evaluate expressions 18.32 - * factor: factor numbers 18.33 - * false: do nothing, unsuccessfully 18.34 - * fmt: simple optimal text formatter 18.35 - * fold: wrap each input line to fit in specified width 18.36 - * groups: print the groups a user is in 18.37 - * head: output the first part of files 18.38 - * hostid: print the numeric identifier for the current host 18.39 - * id: print real and effective user and group IDs 18.40 - * install: copy files and set attributes 18.41 - * join: join lines of two files on a common field 18.42 - * kill: send signals to processes, or list signals 18.43 - * link: call the link function to create a link to a file 18.44 - * ln: make links between files 18.45 - * logname: print user's login name 18.46 - * ls: list directory contents 18.47 - * md5sum: compute and check MD5 message digest 18.48 - * mkdir: make directories 18.49 - * mkfifo: make FIFOs (named pipes) 18.50 - * mknod: make block or character special files 18.51 - * mktemp: create a temporary file or directory 18.52 - * mv: move (rename) files 18.53 - * nice: run a program with modified scheduling priority 18.54 - * nl: number lines of files 18.55 - * nohup: run a command immune to hangups, with output to a non-tty 18.56 - * nproc: print the number of processing units available 18.57 - * numfmt: convert numbers from/to human-readable strings 18.58 - * od: dump files in octal and other formats 18.59 - * paste: merge lines of files 18.60 - * pathchk: check whether file names are valid or portable 18.61 - * pinky: lightweight finger 18.62 - * pr: convert text files for printing 18.63 - * printenv: print all or part of environment 18.64 - * printf: format and print data 18.65 - * ptx: produce a permuted index of file contents 18.66 - * pwd: print name of current/working directory 18.67 - * readlink: print resolved symbolic links or canonical file names 18.68 - * realpath: print the resolved path 18.69 - * rm: remove files or directories 18.70 - * rmdir: remove empty directories 18.71 - * runcon: run command with specified SELinux security context 18.72 - * seq: print a sequence of numbers 18.73 - * sha1sum: compute and check SHA1 message digest 18.74 - * sha224sum: compute and check SHA224 message digest 18.75 - * sha256sum: compute and check SHA256 message digest 18.76 - * sha384sum: compute and check SHA384 message digest 18.77 - * sha512sum: compute and check SHA512 message digest 18.78 - * shred: overwrite a file to hide its contents, and optionally delete it 18.79 - * shuf: generate random permutations 18.80 - * sleep: delay for a specified amount of time 18.81 - * sort: sort lines of text files 18.82 - * split: split a file into pieces 18.83 - * stat: display file or file system status 18.84 - * stdbuf: run command with modified buffering operations for its standard 18.85 - streams 18.86 - * stty: change and print terminal line settings 18.87 - * sum: checksum and count the blocks in a file 18.88 - * sync: synchronize cached writes to persistent storage 18.89 - * tac: concatenate and print files in reverse 18.90 - * tail: output the last part of files 18.91 - * tee: read from standard input and write to standard output and files 18.92 - * test: check file types and compare values 18.93 - * timeout: run a command with a time limit 18.94 - * touch: change file timestamps 18.95 - * tr: translate or delete characters 18.96 - * true: do nothing, successfully 18.97 - * truncate: shrink or extend the size of a file to the specified size 18.98 - * tsort: perform topological sort 18.99 - * tty: print the file name of the terminal connected to standard input 18.100 - * uname: print system information 18.101 - * unexpand: convert spaces to tabs 18.102 - * uniq: report or omit repeated lines 18.103 - * unlink: call the unlink function to remove the specified file 18.104 - * uptime: tell how long the system has been running 18.105 - * users: print the user names of users currently logged in to the current 18.106 - host 18.107 - * vdir: list directory contents 18.108 - * wc: print newline, word, and byte counts for each file 18.109 - * who: show who is logged on 18.110 - * whoami: print effective user ID 18.111 - * yes: output a string repeatedly until killed
19.1 --- a/coreutils-multicall/receipt Wed Feb 21 18:10:55 2018 +0200 19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 19.3 @@ -1,68 +0,0 @@ 19.4 -# SliTaz package receipt v2. 19.5 - 19.6 -PACKAGE="coreutils-multicall" 19.7 -VERSION="8.25" 19.8 -CATEGORY="system-tools" 19.9 -SHORT_DESC="Utilities for using and setting the basic system" 19.10 -MAINTAINER="al.bobylev@gmail.com" 19.11 -LICENSE="GPL3" 19.12 -WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 19.13 - 19.14 -TARBALL="coreutils-$VERSION.tar.xz" 19.15 -WGET_URL="$GNU_MIRROR/coreutils/$TARBALL" 19.16 - 19.17 -SIBLINGS="coreutils" 19.18 -BUILD_DEPENDS="automake autoconf gettext xz libcap-dev gmp-dev patch" 19.19 - 19.20 -# Rules to configure and make the package. 19.21 -compile_rules() 19.22 -{ 19.23 - # Rebuild fixed translations 19.24 - msgfmt po/nb.po -o po/nb.gmo 19.25 - msgfmt po/sl.po -o po/sl.gmo 19.26 - 19.27 - autoreconf -fi 19.28 - 19.29 - FORCE_UNSAFE_CONFIGURE=1 \ 19.30 - ./configure \ 19.31 - --enable-single-binary=symlinks \ 19.32 - $CONFIGURE_ARGS && 19.33 - make && make install 19.34 - 19.35 - # LFS: Move programs to the locations specified by the FHS 19.36 - mkdir -p \ 19.37 - $install/bin \ 19.38 - $install/usr/sbin \ 19.39 - $install/usr/share/man/man8 19.40 - for i in cat chgrp chmod chown cp date dd df echo false ln ls mkdir \ 19.41 - mknod mv pwd rm rmdir stty sync true uname; do 19.42 - rm $install/usr/bin/$i 19.43 - ln -s /usr/bin/coreutils $install/bin/$i 19.44 - done 19.45 - rm $install/usr/bin/chroot 19.46 - ln -s /usr/bin/coreutils $install/usr/sbin/chroot 19.47 - mv $install/usr/share/man/man1/chroot.1 \ 19.48 - $install/usr/share/man/man8/chroot.8 19.49 - sed -i 's|"1"|"8"|' $install/usr/share/man/man8/chroot.8 19.50 -} 19.51 - 19.52 -# Rules to gen a SliTaz package suitable for Tazpkg. 19.53 -genpkg_rules() 19.54 -{ 19.55 - copy @std 19.56 - DEPENDS="glibc-base acl attr libcap gmp" 19.57 -} 19.58 - 19.59 - # Remove Busybox applets in order to not clash with ("/bin", "/sbin", 19.60 - # "/usr/bin" and "/usr/sbin" conflicts with the same filename) 19.61 -post_install_coreutils_multicall() 19.62 -{ 19.63 - rm "$1/bin/base64" # for /usr/bin/base64 19.64 - rm "$1/bin/kill" # for /usr/bin/kill 19.65 - rm "$1/bin/mktemp" # for /usr/bin/mktemp 19.66 - rm "$1/bin/nice" # for /usr/bin/nice 19.67 - rm "$1/bin/printenv" # for /usr/bin/printenv 19.68 - rm "$1/bin/sleep" # for /usr/bin/sleep 19.69 - rm "$1/bin/stat" # for /usr/bin/stat 19.70 - rm "$1/bin/touch" # for /usr/bin/touch 19.71 -}
20.1 --- a/coreutils-multicall/stuff Wed Feb 21 18:10:55 2018 +0200 20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 20.3 @@ -1,1 +0,0 @@ 20.4 -../coreutils/stuff 20.5 \ No newline at end of file
21.1 --- a/coreutils/receipt Wed Feb 21 18:10:55 2018 +0200 21.2 +++ b/coreutils/receipt Wed Feb 21 19:48:17 2018 +0200 21.3 @@ -1,171 +1,239 @@ 21.4 # SliTaz package receipt v2. 21.5 21.6 PACKAGE="coreutils" 21.7 -VERSION="8.25" 21.8 +VERSION="8.29" 21.9 CATEGORY="meta" 21.10 SHORT_DESC="Utilities for using and setting the basic system" 21.11 MAINTAINER="pankso@slitaz.org" 21.12 LICENSE="GPL3" 21.13 WEB_SITE="https://www.gnu.org/software/coreutils/coreutils.html" 21.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter05/coreutils.html" 21.15 21.16 TARBALL="$PACKAGE-$VERSION.tar.xz" 21.17 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 21.18 21.19 -SIBLINGS="coreutils-multicall" 21.20 -BUILD_DEPENDS="automake autoconf gettext xz libcap-dev gmp-dev patch" 21.21 -SPLIT="coreutils-character coreutils-command coreutils-conditions coreutils-\ 21.22 -context-system coreutils-context-user coreutils-context-working coreutils-\ 21.23 -directory coreutils-disk coreutils-file-attributes coreutils-file-format \ 21.24 -coreutils-file-output-full coreutils-file-output-part coreutils-file-sort \ 21.25 -coreutils-file-special coreutils-file-summarize coreutils-line coreutils-\ 21.26 -numeric coreutils-operations coreutils-path coreutils-print coreutils-\ 21.27 -redirection" 21.28 +BUILD_DEPENDS="automake autoconf gettext xz libcap-dev gmp-dev patch texinfo \ 21.29 +openssl-dev" 21.30 +SPLIT="\ 21.31 +coreutils-character coreutils-command coreutils-conditions \ 21.32 +coreutils-context-system coreutils-context-user coreutils-context-working \ 21.33 +coreutils-directory coreutils-disk coreutils-file-attributes \ 21.34 +coreutils-file-format coreutils-file-output-full coreutils-file-output-part \ 21.35 +coreutils-file-sort coreutils-file-special coreutils-file-summarize \ 21.36 +coreutils-line coreutils-numeric coreutils-operations \ 21.37 +coreutils-path coreutils-print coreutils-redirection \ 21.38 +coreutils-multicall:multi" 21.39 21.40 -# Rules to configure and make the package. 21.41 -compile_rules() 21.42 -{ 21.43 +compile_rules() { 21.44 + case $SET in 21.45 + multi) SET_ARGS='--enable-single-binary=symlinks';; 21.46 + *) SET_ARGS='';; 21.47 + esac 21.48 # Rebuild fixed translations 21.49 msgfmt po/nb.po -o po/nb.gmo 21.50 msgfmt po/sl.po -o po/sl.gmo 21.51 21.52 autoreconf -fi 21.53 21.54 - FORCE_UNSAFE_CONFIGURE=1 ./configure $CONFIGURE_ARGS && 21.55 - make && make install 21.56 + FORCE_UNSAFE_CONFIGURE=1 \ 21.57 + ./configure \ 21.58 + --with-openssl \ 21.59 + $SET_ARGS \ 21.60 + $CONFIGURE_ARGS && 21.61 + make && make install || return 1 21.62 21.63 # LFS: Move programs to the locations specified by the FHS 21.64 mkdir -p \ 21.65 $install/bin \ 21.66 $install/usr/sbin \ 21.67 $install/usr/share/man/man8 21.68 - for i in cat chgrp chmod chown cp date dd df echo false ln ls mkdir \ 21.69 - mknod mv pwd rm rmdir stty sync true uname; do 21.70 - mv $install/usr/bin/$i $install/bin 21.71 - done 21.72 - mv $install/usr/bin/chroot $install/usr/sbin 21.73 + 21.74 + while read from to; do 21.75 + case $SET in 21.76 + multi) 21.77 + rm $install$from 21.78 + # make relative symlinks 21.79 + case $to in 21.80 + /bin/*) ln -s ../../usr/bin/coreutils $install$to;; 21.81 + *) ln -s ../bin/coreutils $install$to;; 21.82 + esac 21.83 + ;; 21.84 + *) 21.85 + mv $install$from $install$to 21.86 + ;; 21.87 + esac 21.88 + done <<EOT 21.89 +/usr/bin/cat /bin/cat 21.90 +/usr/bin/chgrp /bin/chgrp 21.91 +/usr/bin/chmod /bin/chmod 21.92 +/usr/bin/chown /bin/chown 21.93 +/usr/bin/cp /bin/cp 21.94 +/usr/bin/date /bin/date 21.95 +/usr/bin/dd /bin/dd 21.96 +/usr/bin/df /bin/df 21.97 +/usr/bin/echo /bin/echo 21.98 +/usr/bin/false /bin/false 21.99 +/usr/bin/kill /bin/kill 21.100 +/usr/bin/ln /bin/ln 21.101 +/usr/bin/ls /bin/ls 21.102 +/usr/bin/mkdir /bin/mkdir 21.103 +/usr/bin/mknod /bin/mknod 21.104 +/usr/bin/mv /bin/mv 21.105 +/usr/bin/pwd /bin/pwd 21.106 +/usr/bin/rm /bin/rm 21.107 +/usr/bin/rmdir /bin/rmdir 21.108 +/usr/bin/stty /bin/stty 21.109 +/usr/bin/sync /bin/sync 21.110 +/usr/bin/true /bin/true 21.111 +/usr/bin/uname /bin/uname 21.112 +/usr/bin/chroot /usr/sbin/chroot 21.113 +EOT 21.114 mv $install/usr/share/man/man1/chroot.1 \ 21.115 $install/usr/share/man/man8/chroot.8 21.116 sed -i 's|"1"|"8"|' $install/usr/share/man/man8/chroot.8 21.117 } 21.118 21.119 -# Rules to gen a SliTaz package suitable for Tazpkg. 21.120 -genpkg_rules() 21.121 -{ 21.122 +genpkg_rules() { 21.123 + DEPENDS="glibc-base" # default 21.124 case $PACKAGE in 21.125 coreutils) 21.126 - DEPENDS="$SPLIT" ;; 21.127 - coreutils-character) 21.128 + DEPENDS=${SPLIT/coreutils-multicall:multi} # all but coreutils-multicall 21.129 + TAGS="LFS" 21.130 + ;; 21.131 + *-character) 21.132 copy expand tr unexpand 21.133 CAT="system-tools|operate on characters" 21.134 - DEPENDS="glibc-base" ;; 21.135 - coreutils-command) 21.136 + ;; 21.137 + *-command) 21.138 copy env kill nice nohup sleep stdbuf timeout libstdbuf.so chroot 21.139 CAT="system-tools|commands" 21.140 - DEPENDS="glibc-base" ;; 21.141 - coreutils-conditions) 21.142 + ;; 21.143 + *-conditions) 21.144 copy false true [ expr test 21.145 CAT="system-tools|conditions" 21.146 DEPENDS="glibc-base gmp" ;; 21.147 - coreutils-context-system) 21.148 + *-context-system) 21.149 copy date uname chcon hostid nproc runcon uptime 21.150 CAT="system-tools|system context" 21.151 - DEPENDS="glibc-base" ;; 21.152 - coreutils-context-user) 21.153 + ;; 21.154 + *-context-user) 21.155 copy groups id logname pinky users who whoami 21.156 CAT="system-tools|user context" 21.157 - DEPENDS="glibc-base" ;; 21.158 - coreutils-context-working) 21.159 + ;; 21.160 + *-context-working) 21.161 copy pwd stty printenv tty 21.162 CAT="system-tools|working context" 21.163 - DEPENDS="glibc-base" ;; 21.164 - coreutils-directory) 21.165 + ;; 21.166 + *-directory) 21.167 copy ls dir dircolors vdir 21.168 CAT="system-tools|list directories" 21.169 - DEPENDS="glibc-base attr libcap" ;; 21.170 - coreutils-disk) 21.171 + DEPENDS="glibc-base libcap" ;; 21.172 + *-disk) 21.173 copy df sync du stat truncate 21.174 CAT="system-tools|work with disks" 21.175 - DEPENDS="glibc-base" ;; 21.176 - coreutils-file-attributes) 21.177 + ;; 21.178 + *-file-attributes) 21.179 copy chgrp chmod chown touch 21.180 CAT="system-tools|change file attributes" 21.181 - DEPENDS="glibc-base" ;; 21.182 - coreutils-file-format) 21.183 + ;; 21.184 + *-file-format) 21.185 copy fmt fold pr 21.186 CAT="system-tools|format file contents" 21.187 - DEPENDS="glibc-base" ;; 21.188 - coreutils-file-output-full) 21.189 + ;; 21.190 + *-file-output-full) 21.191 copy cat base32 base64 nl od tac 21.192 CAT="system-tools|output entire files" 21.193 - DEPENDS="glibc-base" ;; 21.194 - coreutils-file-output-part) 21.195 + ;; 21.196 + *-file-output-part) 21.197 copy csplit head split tail 21.198 CAT="system-tools|output file parts" 21.199 - DEPENDS="glibc-base" ;; 21.200 - coreutils-file-sort) 21.201 + ;; 21.202 + *-file-sort) 21.203 copy comm ptx shuf sort tsort uniq 21.204 CAT="system-tools|operate on sorted files" 21.205 - DEPENDS="glibc-base" ;; 21.206 - coreutils-file-special) 21.207 + DEPENDS="glibc-base openssl" # openssl for `sort` 21.208 + ;; 21.209 + *-file-special) 21.210 copy ln mkdir mknod rmdir link mkfifo mktemp readlink realpath unlink 21.211 CAT="system-tools|work with special file types" 21.212 - DEPENDS="glibc-base" ;; 21.213 - coreutils-file-summarize) 21.214 - copy cksum md5sum sha1sum sha224sum sha256sum sha384sum sha512sum sum wc 21.215 + ;; 21.216 + *-file-summarize) 21.217 + copy b2sum cksum md5sum sha1sum sha224sum sha256sum sha384sum sha512sum sum wc 21.218 CAT="system-tools|summarize files" 21.219 - DEPENDS="glibc-base" ;; 21.220 - coreutils-line) 21.221 + DEPENDS="glibc-base openssl" 21.222 + ;; 21.223 + *-line) 21.224 copy cut join paste 21.225 CAT="system-tools|operate on fields within a line" 21.226 - DEPENDS="glibc-base" ;; 21.227 - coreutils-numeric) 21.228 + ;; 21.229 + *-numeric) 21.230 copy factor seq 21.231 CAT="system-tools|numeric" 21.232 DEPENDS="glibc-base gmp" ;; 21.233 - coreutils-operations) 21.234 + *-operations) 21.235 copy cp dd mv install rm shred 21.236 CAT="system-tools|perform basic operations" 21.237 DEPENDS="glibc-base acl attr" ;; 21.238 - coreutils-path) 21.239 + *-path) 21.240 copy basename dirname pathchk 21.241 CAT="system-tools|perform path manipulation" 21.242 - DEPENDS="glibc-base" ;; 21.243 - coreutils-print) 21.244 + ;; 21.245 + *-print) 21.246 copy echo numfmt printf yes 21.247 CAT="system-tools|print text" 21.248 - DEPENDS="glibc-base" ;; 21.249 - coreutils-redirection) 21.250 + ;; 21.251 + *-redirection) 21.252 copy tee 21.253 CAT="system-tools|redirection" 21.254 - DEPENDS="glibc-base" ;; 21.255 + ;; 21.256 + *-multicall) 21.257 + copy @std 21.258 + CAT="system-tools|packed in single binary like Busybox" 21.259 + DEPENDS="glibc-base acl attr gmp libcap openssl" 21.260 + ;; 21.261 esac 21.262 } 21.263 21.264 # Remove Busybox applets in order to not clash with ("/bin", "/sbin", 21.265 # "/usr/bin" and "/usr/sbin" conflicts with the same filename) 21.266 -post_install_coreutils_command() 21.267 -{ 21.268 - rm "$1/bin/kill" # for /usr/bin/kill 21.269 - rm "$1/bin/nice" # for /usr/bin/nice 21.270 - rm "$1/bin/sleep" # for /usr/bin/sleep 21.271 + 21.272 +# for /usr/bin/nice /usr/bin/sleep 21.273 +post_install_coreutils_command() { 21.274 + for i in nice sleep; do 21.275 + readlink "$1/bin/$i" | grep -q busybox && rm "$1/bin/$i" 21.276 + done 21.277 + : 21.278 } 21.279 -post_install_coreutils_context_working() 21.280 -{ 21.281 - rm "$1/bin/printenv" # for /usr/bin/printenv 21.282 +# for /usr/bin/printenv 21.283 +post_install_coreutils_context_working() { 21.284 + readlink "$1/bin/printenv" | grep -q busybox && rm "$1/bin/printenv" 21.285 + : 21.286 } 21.287 -post_install_coreutils_disk() 21.288 -{ 21.289 - rm "$1/bin/stat" # for /usr/bin/stat 21.290 +# for /usr/bin/stat 21.291 +post_install_coreutils_disk() { 21.292 + readlink "$1/bin/stat" | grep -q busybox && rm "$1/bin/stat" 21.293 + : 21.294 } 21.295 -post_install_coreutils_file_attributes() 21.296 -{ 21.297 - rm "$1/bin/touch" # for /usr/bin/touch 21.298 +# for /usr/bin/touch 21.299 +post_install_coreutils_file_attributes() { 21.300 + readlink "$1/bin/touch" | grep -q busybox && rm "$1/bin/touch" 21.301 + : 21.302 } 21.303 -post_install_coreutils_file_output_full() 21.304 -{ 21.305 - rm "$1/bin/base64" # for /usr/bin/base64 21.306 +# for /usr/bin/base64 21.307 +post_install_coreutils_file_output_full() { 21.308 + readlink "$1/bin/base64" | grep -q busybox && rm "$1/bin/base64" 21.309 + : 21.310 } 21.311 -post_install_coreutils_file_special() 21.312 -{ 21.313 - rm "$1/bin/mktemp" # for /usr/bin/mktemp 21.314 +# for /usr/bin/mktemp 21.315 +post_install_coreutils_file_special() { 21.316 + readlink "$1/bin/mktemp" | grep -q busybox && rm "$1/bin/mktemp" 21.317 + : 21.318 } 21.319 +# for /usr/bin/base64 /usr/bin/mktemp /usr/bin/nice /usr/bin/printenv 21.320 +# /usr/bin/sleep /usr/bin/stat /usr/bin/touch 21.321 +post_install_coreutils_multicall() { 21.322 + for i in base64 mktemp nice printenv sleep stat touch; do 21.323 + readlink "$1/bin/$i" | grep -q busybox && rm "$1/bin/$i" 21.324 + done 21.325 + : 21.326 +}
22.1 --- a/coreutils/stuff/patches/README Wed Feb 21 18:10:55 2018 +0200 22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 22.3 @@ -1,3 +0,0 @@ 22.4 -coreutils-8.25-i18n-2.patch: LFS: Coreutils Internationalization Fixes Patch 22.5 -uname.u: SliTaz: show extended info touching CPU via uname 22.6 -coreutils-fix-po.patch: SliTaz: fix translations, especially deprecated symbol '\v'
23.1 --- a/coreutils/stuff/patches/coreutils-8.25-i18n-2.patch Wed Feb 21 18:10:55 2018 +0200 23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 23.3 @@ -1,4790 +0,0 @@ 23.4 -Submitted by: DJ Lucas (dj_AT_linuxfromscratch_DOT_org) 23.5 -Date: 2016-02-09 23.6 -Initial Package Version: 8.25 23.7 -Upstream Status: Rejected 23.8 -Origin: Based on Suse's i18n patches at https://build.opensuse.org/package/view_file/Base:System/coreutils/coreutils-i18n.patch 23.9 -Description: Fixes several i18n issues with various Coreutils programs 23.10 - 23.11 -diff -Naurp coreutils-8.25-orig/lib/linebuffer.h coreutils-8.25/lib/linebuffer.h 23.12 ---- coreutils-8.25-orig/lib/linebuffer.h 2016-01-01 07:45:55.000000000 -0600 23.13 -+++ coreutils-8.25/lib/linebuffer.h 2016-02-08 19:07:10.298944609 -0600 23.14 -@@ -21,6 +21,11 @@ 23.15 - 23.16 - # include <stdio.h> 23.17 - 23.18 -+/* Get mbstate_t. */ 23.19 -+# if HAVE_WCHAR_H 23.20 -+# include <wchar.h> 23.21 -+# endif 23.22 -+ 23.23 - /* A 'struct linebuffer' holds a line of text. */ 23.24 - 23.25 - struct linebuffer 23.26 -@@ -28,6 +33,9 @@ struct linebuffer 23.27 - size_t size; /* Allocated. */ 23.28 - size_t length; /* Used. */ 23.29 - char *buffer; 23.30 -+# if HAVE_WCHAR_H 23.31 -+ mbstate_t state; 23.32 -+# endif 23.33 - }; 23.34 - 23.35 - /* Initialize linebuffer LINEBUFFER for use. */ 23.36 -diff -Naurp coreutils-8.25-orig/src/cut.c coreutils-8.25/src/cut.c 23.37 ---- coreutils-8.25-orig/src/cut.c 2016-01-13 05:08:59.000000000 -0600 23.38 -+++ coreutils-8.25/src/cut.c 2016-02-08 19:07:10.300944616 -0600 23.39 -@@ -28,6 +28,11 @@ 23.40 - #include <assert.h> 23.41 - #include <getopt.h> 23.42 - #include <sys/types.h> 23.43 -+ 23.44 -+/* Get mbstate_t, mbrtowc(). */ 23.45 -+#if HAVE_WCHAR_H 23.46 -+# include <wchar.h> 23.47 -+#endif 23.48 - #include "system.h" 23.49 - 23.50 - #include "error.h" 23.51 -@@ -38,6 +43,18 @@ 23.52 - 23.53 - #include "set-fields.h" 23.54 - 23.55 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 23.56 -+ installation; work around this configuration error. */ 23.57 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 23.58 -+# undef MB_LEN_MAX 23.59 -+# define MB_LEN_MAX 16 23.60 -+#endif 23.61 -+ 23.62 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 23.63 -+#if HAVE_MBRTOWC && defined mbstate_t 23.64 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 23.65 -+#endif 23.66 -+ 23.67 - /* The official name of this program (e.g., no 'g' prefix). */ 23.68 - #define PROGRAM_NAME "cut" 23.69 - 23.70 -@@ -54,6 +71,52 @@ 23.71 - } \ 23.72 - while (0) 23.73 - 23.74 -+/* Refill the buffer BUF to get a multibyte character. */ 23.75 -+#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM) \ 23.76 -+ do \ 23.77 -+ { \ 23.78 -+ if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM)) \ 23.79 -+ { \ 23.80 -+ memmove (BUF, BUFPOS, BUFLEN); \ 23.81 -+ BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \ 23.82 -+ BUFPOS = BUF; \ 23.83 -+ } \ 23.84 -+ } \ 23.85 -+ while (0) 23.86 -+ 23.87 -+/* Get wide character on BUFPOS. BUFPOS is not included after that. 23.88 -+ If byte sequence is not valid as a character, CONVFAIL is true. Otherwise false. */ 23.89 -+#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ 23.90 -+ do \ 23.91 -+ { \ 23.92 -+ mbstate_t state_bak; \ 23.93 -+ \ 23.94 -+ if (BUFLEN < 1) \ 23.95 -+ { \ 23.96 -+ WC = WEOF; \ 23.97 -+ break; \ 23.98 -+ } \ 23.99 -+ \ 23.100 -+ /* Get a wide character. */ \ 23.101 -+ CONVFAIL = false; \ 23.102 -+ state_bak = STATE; \ 23.103 -+ MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \ 23.104 -+ \ 23.105 -+ switch (MBLENGTH) \ 23.106 -+ { \ 23.107 -+ case (size_t)-1: \ 23.108 -+ case (size_t)-2: \ 23.109 -+ CONVFAIL = true; \ 23.110 -+ STATE = state_bak; \ 23.111 -+ /* Fall througn. */ \ 23.112 -+ \ 23.113 -+ case 0: \ 23.114 -+ MBLENGTH = 1; \ 23.115 -+ break; \ 23.116 -+ } \ 23.117 -+ } \ 23.118 -+ while (0) 23.119 -+ 23.120 - 23.121 - /* Pointer inside RP. When checking if a byte or field is selected 23.122 - by a finite range, we check if it is between CURRENT_RP.LO 23.123 -@@ -61,6 +124,9 @@ 23.124 - CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ 23.125 - static struct field_range_pair *current_rp; 23.126 - 23.127 -+/* Length of the delimiter given as argument to -d. */ 23.128 -+size_t delimlen; 23.129 -+ 23.130 - /* This buffer is used to support the semantics of the -s option 23.131 - (or lack of same) when the specified field list includes (does 23.132 - not include) the first field. In both of those cases, the entire 23.133 -@@ -77,15 +143,25 @@ enum operating_mode 23.134 - { 23.135 - undefined_mode, 23.136 - 23.137 -- /* Output characters that are in the given bytes. */ 23.138 -+ /* Output bytes that are at the given positions. */ 23.139 - byte_mode, 23.140 - 23.141 -+ /* Output characters that are at the given positions. */ 23.142 -+ character_mode, 23.143 -+ 23.144 - /* Output the given delimiter-separated fields. */ 23.145 - field_mode 23.146 - }; 23.147 - 23.148 - static enum operating_mode operating_mode; 23.149 - 23.150 -+/* If nonzero, when in byte mode, don't split multibyte characters. */ 23.151 -+static int byte_mode_character_aware; 23.152 -+ 23.153 -+/* If nonzero, the function for single byte locale is work 23.154 -+ if this program runs on multibyte locale. */ 23.155 -+static int force_singlebyte_mode; 23.156 -+ 23.157 - /* If true do not output lines containing no delimiter characters. 23.158 - Otherwise, all such lines are printed. This option is valid only 23.159 - with field mode. */ 23.160 -@@ -97,6 +173,9 @@ static bool complement; 23.161 - 23.162 - /* The delimiter character for field mode. */ 23.163 - static unsigned char delim; 23.164 -+#if HAVE_WCHAR_H 23.165 -+static wchar_t wcdelim; 23.166 -+#endif 23.167 - 23.168 - /* The delimiter for each line/record. */ 23.169 - static unsigned char line_delim = '\n'; 23.170 -@@ -164,7 +243,7 @@ Print selected parts of lines from each 23.171 - -f, --fields=LIST select only these fields; also print any line\n\ 23.172 - that contains no delimiter character, unless\n\ 23.173 - the -s option is specified\n\ 23.174 -- -n (ignored)\n\ 23.175 -+ -n with -b: don't split multibyte characters\n\ 23.176 - "), stdout); 23.177 - fputs (_("\ 23.178 - --complement complement the set of selected bytes, characters\n\ 23.179 -@@ -280,6 +359,82 @@ cut_bytes (FILE *stream) 23.180 - } 23.181 - } 23.182 - 23.183 -+#if HAVE_MBRTOWC 23.184 -+/* This function is in use for the following case. 23.185 -+ 23.186 -+ 1. Read from the stream STREAM, printing to standard output any selected 23.187 -+ characters. 23.188 -+ 23.189 -+ 2. Read from stream STREAM, printing to standard output any selected bytes, 23.190 -+ without splitting multibyte characters. */ 23.191 -+ 23.192 -+static void 23.193 -+cut_characters_or_cut_bytes_no_split (FILE *stream) 23.194 -+{ 23.195 -+ size_t idx; /* number of bytes or characters in the line so far. */ 23.196 -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 23.197 -+ char *bufpos; /* Next read position of BUF. */ 23.198 -+ size_t buflen; /* The length of the byte sequence in buf. */ 23.199 -+ wint_t wc; /* A gotten wide character. */ 23.200 -+ size_t mblength; /* The byte size of a multibyte character which shows 23.201 -+ as same character as WC. */ 23.202 -+ mbstate_t state; /* State of the stream. */ 23.203 -+ bool convfail = false; /* true, when conversion failed. Otherwise false. */ 23.204 -+ /* Whether to begin printing delimiters between ranges for the current line. 23.205 -+ Set after we've begun printing data corresponding to the first range. */ 23.206 -+ bool print_delimiter = false; 23.207 -+ 23.208 -+ idx = 0; 23.209 -+ buflen = 0; 23.210 -+ bufpos = buf; 23.211 -+ memset (&state, '\0', sizeof(mbstate_t)); 23.212 -+ 23.213 -+ current_rp = frp; 23.214 -+ 23.215 -+ while (1) 23.216 -+ { 23.217 -+ REFILL_BUFFER (buf, bufpos, buflen, stream); 23.218 -+ 23.219 -+ GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); 23.220 -+ (void) convfail; /* ignore unused */ 23.221 -+ 23.222 -+ if (wc == WEOF) 23.223 -+ { 23.224 -+ if (idx > 0) 23.225 -+ putchar (line_delim); 23.226 -+ break; 23.227 -+ } 23.228 -+ else if (wc == line_delim) 23.229 -+ { 23.230 -+ putchar (line_delim); 23.231 -+ idx = 0; 23.232 -+ print_delimiter = false; 23.233 -+ current_rp = frp; 23.234 -+ } 23.235 -+ else 23.236 -+ { 23.237 -+ next_item (&idx); 23.238 -+ if (print_kth (idx)) 23.239 -+ { 23.240 -+ if (output_delimiter_specified) 23.241 -+ { 23.242 -+ if (print_delimiter && is_range_start_index (idx)) 23.243 -+ { 23.244 -+ fwrite (output_delimiter_string, sizeof (char), 23.245 -+ output_delimiter_length, stdout); 23.246 -+ } 23.247 -+ print_delimiter = true; 23.248 -+ } 23.249 -+ fwrite (bufpos, mblength, sizeof(char), stdout); 23.250 -+ } 23.251 -+ } 23.252 -+ 23.253 -+ buflen -= mblength; 23.254 -+ bufpos += mblength; 23.255 -+ } 23.256 -+} 23.257 -+#endif 23.258 -+ 23.259 - /* Read from stream STREAM, printing to standard output any selected fields. */ 23.260 - 23.261 - static void 23.262 -@@ -425,13 +580,211 @@ cut_fields (FILE *stream) 23.263 - } 23.264 - } 23.265 - 23.266 -+#if HAVE_MBRTOWC 23.267 -+static void 23.268 -+cut_fields_mb (FILE *stream) 23.269 -+{ 23.270 -+ int c; 23.271 -+ size_t field_idx; 23.272 -+ int found_any_selected_field; 23.273 -+ int buffer_first_field; 23.274 -+ int empty_input; 23.275 -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 23.276 -+ char *bufpos; /* Next read position of BUF. */ 23.277 -+ size_t buflen; /* The length of the byte sequence in buf. */ 23.278 -+ wint_t wc = 0; /* A gotten wide character. */ 23.279 -+ size_t mblength; /* The byte size of a multibyte character which shows 23.280 -+ as same character as WC. */ 23.281 -+ mbstate_t state; /* State of the stream. */ 23.282 -+ bool convfail = false; /* true, when conversion failed. Otherwise false. */ 23.283 -+ 23.284 -+ current_rp = frp; 23.285 -+ 23.286 -+ found_any_selected_field = 0; 23.287 -+ field_idx = 1; 23.288 -+ bufpos = buf; 23.289 -+ buflen = 0; 23.290 -+ memset (&state, '\0', sizeof(mbstate_t)); 23.291 -+ 23.292 -+ c = getc (stream); 23.293 -+ empty_input = (c == EOF); 23.294 -+ if (c != EOF) 23.295 -+ { 23.296 -+ ungetc (c, stream); 23.297 -+ wc = 0; 23.298 -+ } 23.299 -+ else 23.300 -+ wc = WEOF; 23.301 -+ 23.302 -+ /* To support the semantics of the -s flag, we may have to buffer 23.303 -+ all of the first field to determine whether it is `delimited.' 23.304 -+ But that is unnecessary if all non-delimited lines must be printed 23.305 -+ and the first field has been selected, or if non-delimited lines 23.306 -+ must be suppressed and the first field has *not* been selected. 23.307 -+ That is because a non-delimited line has exactly one field. */ 23.308 -+ buffer_first_field = (suppress_non_delimited ^ !print_kth (1)); 23.309 -+ 23.310 -+ while (1) 23.311 -+ { 23.312 -+ if (field_idx == 1 && buffer_first_field) 23.313 -+ { 23.314 -+ int len = 0; 23.315 -+ 23.316 -+ while (1) 23.317 -+ { 23.318 -+ REFILL_BUFFER (buf, bufpos, buflen, stream); 23.319 -+ 23.320 -+ GET_NEXT_WC_FROM_BUFFER 23.321 -+ (wc, bufpos, buflen, mblength, state, convfail); 23.322 -+ 23.323 -+ if (wc == WEOF) 23.324 -+ break; 23.325 -+ 23.326 -+ field_1_buffer = xrealloc (field_1_buffer, len + mblength); 23.327 -+ memcpy (field_1_buffer + len, bufpos, mblength); 23.328 -+ len += mblength; 23.329 -+ buflen -= mblength; 23.330 -+ bufpos += mblength; 23.331 -+ 23.332 -+ if (!convfail && (wc == line_delim || wc == wcdelim)) 23.333 -+ break; 23.334 -+ } 23.335 -+ 23.336 -+ if (len <= 0 && wc == WEOF) 23.337 -+ break; 23.338 -+ 23.339 -+ /* If the first field extends to the end of line (it is not 23.340 -+ delimited) and we are printing all non-delimited lines, 23.341 -+ print this one. */ 23.342 -+ if (convfail || (!convfail && wc != wcdelim)) 23.343 -+ { 23.344 -+ if (suppress_non_delimited) 23.345 -+ { 23.346 -+ /* Empty. */ 23.347 -+ } 23.348 -+ else 23.349 -+ { 23.350 -+ fwrite (field_1_buffer, sizeof (char), len, stdout); 23.351 -+ /* Make sure the output line is newline terminated. */ 23.352 -+ if (convfail || (!convfail && wc != line_delim)) 23.353 -+ putchar (line_delim); 23.354 -+ } 23.355 -+ continue; 23.356 -+ } 23.357 -+ 23.358 -+ if (print_kth (1)) 23.359 -+ { 23.360 -+ /* Print the field, but not the trailing delimiter. */ 23.361 -+ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); 23.362 -+ found_any_selected_field = 1; 23.363 -+ } 23.364 -+ next_item (&field_idx); 23.365 -+ } 23.366 -+ 23.367 -+ if (wc != WEOF) 23.368 -+ { 23.369 -+ if (print_kth (field_idx)) 23.370 -+ { 23.371 -+ if (found_any_selected_field) 23.372 -+ { 23.373 -+ fwrite (output_delimiter_string, sizeof (char), 23.374 -+ output_delimiter_length, stdout); 23.375 -+ } 23.376 -+ found_any_selected_field = 1; 23.377 -+ } 23.378 -+ 23.379 -+ while (1) 23.380 -+ { 23.381 -+ REFILL_BUFFER (buf, bufpos, buflen, stream); 23.382 -+ 23.383 -+ GET_NEXT_WC_FROM_BUFFER 23.384 -+ (wc, bufpos, buflen, mblength, state, convfail); 23.385 -+ 23.386 -+ if (wc == WEOF) 23.387 -+ break; 23.388 -+ else if (!convfail && (wc == wcdelim || wc == line_delim)) 23.389 -+ { 23.390 -+ buflen -= mblength; 23.391 -+ bufpos += mblength; 23.392 -+ break; 23.393 -+ } 23.394 -+ 23.395 -+ if (print_kth (field_idx)) 23.396 -+ fwrite (bufpos, mblength, sizeof(char), stdout); 23.397 -+ 23.398 -+ buflen -= mblength; 23.399 -+ bufpos += mblength; 23.400 -+ } 23.401 -+ } 23.402 -+ 23.403 -+ if ((!convfail || wc == line_delim) && buflen < 1) 23.404 -+ wc = WEOF; 23.405 -+ 23.406 -+ if (!convfail && wc == wcdelim) 23.407 -+ next_item (&field_idx); 23.408 -+ else if (wc == WEOF || (!convfail && wc == line_delim)) 23.409 -+ { 23.410 -+ if (found_any_selected_field 23.411 -+ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) 23.412 -+ putchar (line_delim); 23.413 -+ if (wc == WEOF) 23.414 -+ break; 23.415 -+ field_idx = 1; 23.416 -+ current_rp = frp; 23.417 -+ found_any_selected_field = 0; 23.418 -+ } 23.419 -+ } 23.420 -+} 23.421 -+#endif 23.422 -+ 23.423 - static void 23.424 - cut_stream (FILE *stream) 23.425 - { 23.426 -- if (operating_mode == byte_mode) 23.427 -- cut_bytes (stream); 23.428 -+#if HAVE_MBRTOWC 23.429 -+ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) 23.430 -+ { 23.431 -+ switch (operating_mode) 23.432 -+ { 23.433 -+ case byte_mode: 23.434 -+ if (byte_mode_character_aware) 23.435 -+ cut_characters_or_cut_bytes_no_split (stream); 23.436 -+ else 23.437 -+ cut_bytes (stream); 23.438 -+ break; 23.439 -+ 23.440 -+ case character_mode: 23.441 -+ cut_characters_or_cut_bytes_no_split (stream); 23.442 -+ break; 23.443 -+ 23.444 -+ case field_mode: 23.445 -+ if (delimlen == 1) 23.446 -+ { 23.447 -+ /* Check if we have utf8 multibyte locale, so we can use this 23.448 -+ optimization because of uniqueness of characters, which is 23.449 -+ not true for e.g. SJIS */ 23.450 -+ char * loc = setlocale(LC_CTYPE, NULL); 23.451 -+ if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") || 23.452 -+ strstr (loc, "UTF8") || strstr (loc, "utf8"))) 23.453 -+ { 23.454 -+ cut_fields (stream); 23.455 -+ break; 23.456 -+ } 23.457 -+ } 23.458 -+ cut_fields_mb (stream); 23.459 -+ break; 23.460 -+ 23.461 -+ default: 23.462 -+ abort (); 23.463 -+ } 23.464 -+ } 23.465 - else 23.466 -- cut_fields (stream); 23.467 -+#endif 23.468 -+ { 23.469 -+ if (operating_mode == field_mode) 23.470 -+ cut_fields (stream); 23.471 -+ else 23.472 -+ cut_bytes (stream); 23.473 -+ } 23.474 - } 23.475 - 23.476 - /* Process file FILE to standard output. 23.477 -@@ -483,6 +836,7 @@ main (int argc, char **argv) 23.478 - bool ok; 23.479 - bool delim_specified = false; 23.480 - char *spec_list_string IF_LINT ( = NULL); 23.481 -+ char mbdelim[MB_LEN_MAX + 1]; 23.482 - 23.483 - initialize_main (&argc, &argv); 23.484 - set_program_name (argv[0]); 23.485 -@@ -505,7 +859,6 @@ main (int argc, char **argv) 23.486 - switch (optc) 23.487 - { 23.488 - case 'b': 23.489 -- case 'c': 23.490 - /* Build the byte list. */ 23.491 - if (operating_mode != undefined_mode) 23.492 - FATAL_ERROR (_("only one type of list may be specified")); 23.493 -@@ -513,6 +866,14 @@ main (int argc, char **argv) 23.494 - spec_list_string = optarg; 23.495 - break; 23.496 - 23.497 -+ case 'c': 23.498 -+ /* Build the character list. */ 23.499 -+ if (operating_mode != undefined_mode) 23.500 -+ FATAL_ERROR (_("only one type of list may be specified")); 23.501 -+ operating_mode = character_mode; 23.502 -+ spec_list_string = optarg; 23.503 -+ break; 23.504 -+ 23.505 - case 'f': 23.506 - /* Build the field list. */ 23.507 - if (operating_mode != undefined_mode) 23.508 -@@ -524,10 +885,38 @@ main (int argc, char **argv) 23.509 - case 'd': 23.510 - /* New delimiter. */ 23.511 - /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ 23.512 -- if (optarg[0] != '\0' && optarg[1] != '\0') 23.513 -- FATAL_ERROR (_("the delimiter must be a single character")); 23.514 -- delim = optarg[0]; 23.515 -- delim_specified = true; 23.516 -+ { 23.517 -+#if HAVE_MBRTOWC 23.518 -+ if(MB_CUR_MAX > 1) 23.519 -+ { 23.520 -+ mbstate_t state; 23.521 -+ 23.522 -+ memset (&state, '\0', sizeof(mbstate_t)); 23.523 -+ delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state); 23.524 -+ 23.525 -+ if (delimlen == (size_t)-1 || delimlen == (size_t)-2) 23.526 -+ ++force_singlebyte_mode; 23.527 -+ else 23.528 -+ { 23.529 -+ delimlen = (delimlen < 1) ? 1 : delimlen; 23.530 -+ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') 23.531 -+ FATAL_ERROR (_("the delimiter must be a single character")); 23.532 -+ memcpy (mbdelim, optarg, delimlen); 23.533 -+ mbdelim[delimlen] = '\0'; 23.534 -+ if (delimlen == 1) 23.535 -+ delim = *optarg; 23.536 -+ } 23.537 -+ } 23.538 -+ 23.539 -+ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) 23.540 -+#endif 23.541 -+ { 23.542 -+ if (optarg[0] != '\0' && optarg[1] != '\0') 23.543 -+ FATAL_ERROR (_("the delimiter must be a single character")); 23.544 -+ delim = (unsigned char) optarg[0]; 23.545 -+ } 23.546 -+ delim_specified = true; 23.547 -+ } 23.548 - break; 23.549 - 23.550 - case OUTPUT_DELIMITER_OPTION: 23.551 -@@ -540,6 +929,7 @@ main (int argc, char **argv) 23.552 - break; 23.553 - 23.554 - case 'n': 23.555 -+ byte_mode_character_aware = 1; 23.556 - break; 23.557 - 23.558 - case 's': 23.559 -@@ -579,15 +969,34 @@ main (int argc, char **argv) 23.560 - | (complement ? SETFLD_COMPLEMENT : 0) ); 23.561 - 23.562 - if (!delim_specified) 23.563 -- delim = '\t'; 23.564 -+ { 23.565 -+ delim = '\t'; 23.566 -+#ifdef HAVE_MBRTOWC 23.567 -+ wcdelim = L'\t'; 23.568 -+ mbdelim[0] = '\t'; 23.569 -+ mbdelim[1] = '\0'; 23.570 -+ delimlen = 1; 23.571 -+#endif 23.572 -+ } 23.573 - 23.574 - if (output_delimiter_string == NULL) 23.575 - { 23.576 -- static char dummy[2]; 23.577 -- dummy[0] = delim; 23.578 -- dummy[1] = '\0'; 23.579 -- output_delimiter_string = dummy; 23.580 -- output_delimiter_length = 1; 23.581 -+#ifdef HAVE_MBRTOWC 23.582 -+ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) 23.583 -+ { 23.584 -+ output_delimiter_string = xstrdup(mbdelim); 23.585 -+ output_delimiter_length = delimlen; 23.586 -+ } 23.587 -+ 23.588 -+ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) 23.589 -+#endif 23.590 -+ { 23.591 -+ static char dummy[2]; 23.592 -+ dummy[0] = delim; 23.593 -+ dummy[1] = '\0'; 23.594 -+ output_delimiter_string = dummy; 23.595 -+ output_delimiter_length = 1; 23.596 -+ } 23.597 - } 23.598 - 23.599 - if (optind == argc) 23.600 -diff -Naurp coreutils-8.25-orig/src/expand.c coreutils-8.25/src/expand.c 23.601 ---- coreutils-8.25-orig/src/expand.c 2016-01-01 07:48:50.000000000 -0600 23.602 -+++ coreutils-8.25/src/expand.c 2016-02-08 19:07:10.301944619 -0600 23.603 -@@ -37,12 +37,34 @@ 23.604 - #include <stdio.h> 23.605 - #include <getopt.h> 23.606 - #include <sys/types.h> 23.607 -+ 23.608 -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ 23.609 -+#if HAVE_WCHAR_H 23.610 -+# include <wchar.h> 23.611 -+#endif 23.612 -+ 23.613 -+/* Get iswblank(). */ 23.614 -+#if HAVE_WCTYPE_H 23.615 -+# include <wctype.h> 23.616 -+#endif 23.617 -+ 23.618 - #include "system.h" 23.619 - #include "error.h" 23.620 - #include "fadvise.h" 23.621 - #include "quote.h" 23.622 - #include "xstrndup.h" 23.623 - 23.624 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 23.625 -+ installation; work around this configuration error. */ 23.626 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 23.627 -+# define MB_LEN_MAX 16 23.628 -+#endif 23.629 -+ 23.630 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 23.631 -+#if HAVE_MBRTOWC && defined mbstate_t 23.632 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 23.633 -+#endif 23.634 -+ 23.635 - /* The official name of this program (e.g., no 'g' prefix). */ 23.636 - #define PROGRAM_NAME "expand" 23.637 - 23.638 -@@ -357,6 +379,142 @@ expand (void) 23.639 - } 23.640 - } 23.641 - 23.642 -+#if HAVE_MBRTOWC 23.643 -+static void 23.644 -+expand_multibyte (void) 23.645 -+{ 23.646 -+ FILE *fp; /* Input strem. */ 23.647 -+ mbstate_t i_state; /* Current shift state of the input stream. */ 23.648 -+ mbstate_t i_state_bak; /* Back up the I_STATE. */ 23.649 -+ mbstate_t o_state; /* Current shift state of the output stream. */ 23.650 -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 23.651 -+ char *bufpos = buf; /* Next read position of BUF. */ 23.652 -+ size_t buflen = 0; /* The length of the byte sequence in buf. */ 23.653 -+ wchar_t wc; /* A gotten wide character. */ 23.654 -+ size_t mblength; /* The byte size of a multibyte character 23.655 -+ which shows as same character as WC. */ 23.656 -+ int tab_index = 0; /* Index in `tab_list' of next tabstop. */ 23.657 -+ int column = 0; /* Column on screen of the next char. */ 23.658 -+ int next_tab_column; /* Column the next tab stop is on. */ 23.659 -+ int convert = 1; /* If nonzero, perform translations. */ 23.660 -+ 23.661 -+ fp = next_file ((FILE *) NULL); 23.662 -+ if (fp == NULL) 23.663 -+ return; 23.664 -+ 23.665 -+ memset (&o_state, '\0', sizeof(mbstate_t)); 23.666 -+ memset (&i_state, '\0', sizeof(mbstate_t)); 23.667 -+ 23.668 -+ for (;;) 23.669 -+ { 23.670 -+ /* Refill the buffer BUF. */ 23.671 -+ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) 23.672 -+ { 23.673 -+ memmove (buf, bufpos, buflen); 23.674 -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); 23.675 -+ bufpos = buf; 23.676 -+ } 23.677 -+ 23.678 -+ /* No character is left in BUF. */ 23.679 -+ if (buflen < 1) 23.680 -+ { 23.681 -+ fp = next_file (fp); 23.682 -+ 23.683 -+ if (fp == NULL) 23.684 -+ break; /* No more files. */ 23.685 -+ else 23.686 -+ { 23.687 -+ memset (&i_state, '\0', sizeof(mbstate_t)); 23.688 -+ continue; 23.689 -+ } 23.690 -+ } 23.691 -+ 23.692 -+ /* Get a wide character. */ 23.693 -+ i_state_bak = i_state; 23.694 -+ mblength = mbrtowc (&wc, bufpos, buflen, &i_state); 23.695 -+ 23.696 -+ switch (mblength) 23.697 -+ { 23.698 -+ case (size_t)-1: /* illegal byte sequence. */ 23.699 -+ case (size_t)-2: 23.700 -+ mblength = 1; 23.701 -+ i_state = i_state_bak; 23.702 -+ if (convert) 23.703 -+ { 23.704 -+ ++column; 23.705 -+ if (convert_entire_line == 0 && !isblank(*bufpos)) 23.706 -+ convert = 0; 23.707 -+ } 23.708 -+ putchar (*bufpos); 23.709 -+ break; 23.710 -+ 23.711 -+ case 0: /* null. */ 23.712 -+ mblength = 1; 23.713 -+ if (convert && convert_entire_line == 0) 23.714 -+ convert = 0; 23.715 -+ putchar ('\0'); 23.716 -+ break; 23.717 -+ 23.718 -+ default: 23.719 -+ if (wc == L'\n') /* LF. */ 23.720 -+ { 23.721 -+ tab_index = 0; 23.722 -+ column = 0; 23.723 -+ convert = 1; 23.724 -+ putchar ('\n'); 23.725 -+ } 23.726 -+ else if (wc == L'\t' && convert) /* Tab. */ 23.727 -+ { 23.728 -+ if (tab_size == 0) 23.729 -+ { 23.730 -+ /* Do not let tab_index == first_free_tab; 23.731 -+ stop when it is 1 less. */ 23.732 -+ while (tab_index < first_free_tab - 1 23.733 -+ && column >= tab_list[tab_index]) 23.734 -+ tab_index++; 23.735 -+ next_tab_column = tab_list[tab_index]; 23.736 -+ if (tab_index < first_free_tab - 1) 23.737 -+ tab_index++; 23.738 -+ if (column >= next_tab_column) 23.739 -+ next_tab_column = column + 1; 23.740 -+ } 23.741 -+ else 23.742 -+ next_tab_column = column + tab_size - column % tab_size; 23.743 -+ 23.744 -+ while (column < next_tab_column) 23.745 -+ { 23.746 -+ putchar (' '); 23.747 -+ ++column; 23.748 -+ } 23.749 -+ } 23.750 -+ else /* Others. */ 23.751 -+ { 23.752 -+ if (convert) 23.753 -+ { 23.754 -+ if (wc == L'\b') 23.755 -+ { 23.756 -+ if (column > 0) 23.757 -+ --column; 23.758 -+ } 23.759 -+ else 23.760 -+ { 23.761 -+ int width; /* The width of WC. */ 23.762 -+ 23.763 -+ width = wcwidth (wc); 23.764 -+ column += (width > 0) ? width : 0; 23.765 -+ if (convert_entire_line == 0 && !iswblank(wc)) 23.766 -+ convert = 0; 23.767 -+ } 23.768 -+ } 23.769 -+ fwrite (bufpos, sizeof(char), mblength, stdout); 23.770 -+ } 23.771 -+ } 23.772 -+ buflen -= mblength; 23.773 -+ bufpos += mblength; 23.774 -+ } 23.775 -+} 23.776 -+#endif 23.777 -+ 23.778 - int 23.779 - main (int argc, char **argv) 23.780 - { 23.781 -@@ -421,7 +579,12 @@ main (int argc, char **argv) 23.782 - 23.783 - file_list = (optind < argc ? &argv[optind] : stdin_argv); 23.784 - 23.785 -- expand (); 23.786 -+#if HAVE_MBRTOWC 23.787 -+ if (MB_CUR_MAX > 1) 23.788 -+ expand_multibyte (); 23.789 -+ else 23.790 -+#endif 23.791 -+ expand (); 23.792 - 23.793 - if (have_read_stdin && fclose (stdin) != 0) 23.794 - error (EXIT_FAILURE, errno, "-"); 23.795 -diff -Naurp coreutils-8.25-orig/src/fold.c coreutils-8.25/src/fold.c 23.796 ---- coreutils-8.25-orig/src/fold.c 2016-01-01 07:48:50.000000000 -0600 23.797 -+++ coreutils-8.25/src/fold.c 2016-02-08 19:07:10.302944622 -0600 23.798 -@@ -22,11 +22,33 @@ 23.799 - #include <getopt.h> 23.800 - #include <sys/types.h> 23.801 - 23.802 -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ 23.803 -+#if HAVE_WCHAR_H 23.804 -+# include <wchar.h> 23.805 -+#endif 23.806 -+ 23.807 -+/* Get iswprint(), iswblank(), wcwidth(). */ 23.808 -+#if HAVE_WCTYPE_H 23.809 -+# include <wctype.h> 23.810 -+#endif 23.811 -+ 23.812 - #include "system.h" 23.813 - #include "error.h" 23.814 - #include "fadvise.h" 23.815 - #include "xdectoint.h" 23.816 - 23.817 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 23.818 -+ installation; work around this configuration error. */ 23.819 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 23.820 -+# undef MB_LEN_MAX 23.821 -+# define MB_LEN_MAX 16 23.822 -+#endif 23.823 -+ 23.824 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 23.825 -+#if HAVE_MBRTOWC && defined mbstate_t 23.826 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 23.827 -+#endif 23.828 -+ 23.829 - #define TAB_WIDTH 8 23.830 - 23.831 - /* The official name of this program (e.g., no 'g' prefix). */ 23.832 -@@ -34,20 +56,41 @@ 23.833 - 23.834 - #define AUTHORS proper_name ("David MacKenzie") 23.835 - 23.836 -+#define FATAL_ERROR(Message) \ 23.837 -+ do \ 23.838 -+ { \ 23.839 -+ error (0, 0, (Message)); \ 23.840 -+ usage (2); \ 23.841 -+ } \ 23.842 -+ while (0) 23.843 -+ 23.844 -+enum operating_mode 23.845 -+{ 23.846 -+ /* Fold texts by columns that are at the given positions. */ 23.847 -+ column_mode, 23.848 -+ 23.849 -+ /* Fold texts by bytes that are at the given positions. */ 23.850 -+ byte_mode, 23.851 -+ 23.852 -+ /* Fold texts by characters that are at the given positions. */ 23.853 -+ character_mode, 23.854 -+}; 23.855 -+ 23.856 -+/* The argument shows current mode. (Default: column_mode) */ 23.857 -+static enum operating_mode operating_mode; 23.858 -+ 23.859 - /* If nonzero, try to break on whitespace. */ 23.860 - static bool break_spaces; 23.861 - 23.862 --/* If nonzero, count bytes, not column positions. */ 23.863 --static bool count_bytes; 23.864 -- 23.865 - /* If nonzero, at least one of the files we read was standard input. */ 23.866 - static bool have_read_stdin; 23.867 - 23.868 --static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::"; 23.869 -+static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::"; 23.870 - 23.871 - static struct option const longopts[] = 23.872 - { 23.873 - {"bytes", no_argument, NULL, 'b'}, 23.874 -+ {"characters", no_argument, NULL, 'c'}, 23.875 - {"spaces", no_argument, NULL, 's'}, 23.876 - {"width", required_argument, NULL, 'w'}, 23.877 - {GETOPT_HELP_OPTION_DECL}, 23.878 -@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing t 23.879 - 23.880 - fputs (_("\ 23.881 - -b, --bytes count bytes rather than columns\n\ 23.882 -+ -c, --characters count characters rather than columns\n\ 23.883 - -s, --spaces break at spaces\n\ 23.884 - -w, --width=WIDTH use WIDTH columns instead of 80\n\ 23.885 - "), stdout); 23.886 -@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing t 23.887 - static size_t 23.888 - adjust_column (size_t column, char c) 23.889 - { 23.890 -- if (!count_bytes) 23.891 -+ if (operating_mode != byte_mode) 23.892 - { 23.893 - if (c == '\b') 23.894 - { 23.895 -@@ -115,30 +159,14 @@ adjust_column (size_t column, char c) 23.896 - to stdout, with maximum line length WIDTH. 23.897 - Return true if successful. */ 23.898 - 23.899 --static bool 23.900 --fold_file (char const *filename, size_t width) 23.901 -+static void 23.902 -+fold_text (FILE *istream, size_t width, int *saved_errno) 23.903 - { 23.904 -- FILE *istream; 23.905 - int c; 23.906 - size_t column = 0; /* Screen column where next char will go. */ 23.907 - size_t offset_out = 0; /* Index in 'line_out' for next char. */ 23.908 - static char *line_out = NULL; 23.909 - static size_t allocated_out = 0; 23.910 -- int saved_errno; 23.911 -- 23.912 -- if (STREQ (filename, "-")) 23.913 -- { 23.914 -- istream = stdin; 23.915 -- have_read_stdin = true; 23.916 -- } 23.917 -- else 23.918 -- istream = fopen (filename, "r"); 23.919 -- 23.920 -- if (istream == NULL) 23.921 -- { 23.922 -- error (0, errno, "%s", quotef (filename)); 23.923 -- return false; 23.924 -- } 23.925 - 23.926 - fadvise (istream, FADVISE_SEQUENTIAL); 23.927 - 23.928 -@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t 23.929 - bool found_blank = false; 23.930 - size_t logical_end = offset_out; 23.931 - 23.932 -+ /* If LINE_OUT has no wide character, 23.933 -+ put a new wide character in LINE_OUT 23.934 -+ if column is bigger than width. */ 23.935 -+ if (offset_out == 0) 23.936 -+ { 23.937 -+ line_out[offset_out++] = c; 23.938 -+ continue; 23.939 -+ } 23.940 -+ 23.941 - /* Look for the last blank. */ 23.942 - while (logical_end) 23.943 - { 23.944 -@@ -214,11 +251,221 @@ fold_file (char const *filename, size_t 23.945 - line_out[offset_out++] = c; 23.946 - } 23.947 - 23.948 -- saved_errno = errno; 23.949 -+ *saved_errno = errno; 23.950 -+ 23.951 -+ if (offset_out) 23.952 -+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); 23.953 -+ 23.954 -+} 23.955 -+ 23.956 -+#if HAVE_MBRTOWC 23.957 -+static void 23.958 -+fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) 23.959 -+{ 23.960 -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 23.961 -+ size_t buflen = 0; /* The length of the byte sequence in buf. */ 23.962 -+ char *bufpos = buf; /* Next read position of BUF. */ 23.963 -+ wint_t wc; /* A gotten wide character. */ 23.964 -+ size_t mblength; /* The byte size of a multibyte character which shows 23.965 -+ as same character as WC. */ 23.966 -+ mbstate_t state, state_bak; /* State of the stream. */ 23.967 -+ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ 23.968 -+ 23.969 -+ static char *line_out = NULL; 23.970 -+ size_t offset_out = 0; /* Index in `line_out' for next char. */ 23.971 -+ static size_t allocated_out = 0; 23.972 -+ 23.973 -+ int increment; 23.974 -+ size_t column = 0; 23.975 -+ 23.976 -+ size_t last_blank_pos; 23.977 -+ size_t last_blank_column; 23.978 -+ int is_blank_seen; 23.979 -+ int last_blank_increment = 0; 23.980 -+ int is_bs_following_last_blank; 23.981 -+ size_t bs_following_last_blank_num; 23.982 -+ int is_cr_after_last_blank; 23.983 -+ 23.984 -+#define CLEAR_FLAGS \ 23.985 -+ do \ 23.986 -+ { \ 23.987 -+ last_blank_pos = 0; \ 23.988 -+ last_blank_column = 0; \ 23.989 -+ is_blank_seen = 0; \ 23.990 -+ is_bs_following_last_blank = 0; \ 23.991 -+ bs_following_last_blank_num = 0; \ 23.992 -+ is_cr_after_last_blank = 0; \ 23.993 -+ } \ 23.994 -+ while (0) 23.995 -+ 23.996 -+#define START_NEW_LINE \ 23.997 -+ do \ 23.998 -+ { \ 23.999 -+ putchar ('\n'); \ 23.1000 -+ column = 0; \ 23.1001 -+ offset_out = 0; \ 23.1002 -+ CLEAR_FLAGS; \ 23.1003 -+ } \ 23.1004 -+ while (0) 23.1005 -+ 23.1006 -+ CLEAR_FLAGS; 23.1007 -+ memset (&state, '\0', sizeof(mbstate_t)); 23.1008 -+ 23.1009 -+ for (;; bufpos += mblength, buflen -= mblength) 23.1010 -+ { 23.1011 -+ if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream)) 23.1012 -+ { 23.1013 -+ memmove (buf, bufpos, buflen); 23.1014 -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream); 23.1015 -+ bufpos = buf; 23.1016 -+ } 23.1017 -+ 23.1018 -+ if (buflen < 1) 23.1019 -+ break; 23.1020 -+ 23.1021 -+ /* Get a wide character. */ 23.1022 -+ state_bak = state; 23.1023 -+ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state); 23.1024 -+ 23.1025 -+ switch (mblength) 23.1026 -+ { 23.1027 -+ case (size_t)-1: 23.1028 -+ case (size_t)-2: 23.1029 -+ convfail++; 23.1030 -+ state = state_bak; 23.1031 -+ /* Fall through. */ 23.1032 -+ 23.1033 -+ case 0: 23.1034 -+ mblength = 1; 23.1035 -+ break; 23.1036 -+ } 23.1037 -+ 23.1038 -+rescan: 23.1039 -+ if (operating_mode == byte_mode) /* byte mode */ 23.1040 -+ increment = mblength; 23.1041 -+ else if (operating_mode == character_mode) /* character mode */ 23.1042 -+ increment = 1; 23.1043 -+ else /* column mode */ 23.1044 -+ { 23.1045 -+ if (convfail) 23.1046 -+ increment = 1; 23.1047 -+ else 23.1048 -+ { 23.1049 -+ switch (wc) 23.1050 -+ { 23.1051 -+ case L'\n': 23.1052 -+ fwrite (line_out, sizeof(char), offset_out, stdout); 23.1053 -+ START_NEW_LINE; 23.1054 -+ continue; 23.1055 -+ 23.1056 -+ case L'\b': 23.1057 -+ increment = (column > 0) ? -1 : 0; 23.1058 -+ break; 23.1059 -+ 23.1060 -+ case L'\r': 23.1061 -+ increment = -1 * column; 23.1062 -+ break; 23.1063 -+ 23.1064 -+ case L'\t': 23.1065 -+ increment = 8 - column % 8; 23.1066 -+ break; 23.1067 -+ 23.1068 -+ default: 23.1069 -+ increment = wcwidth (wc); 23.1070 -+ increment = (increment < 0) ? 0 : increment; 23.1071 -+ } 23.1072 -+ } 23.1073 -+ } 23.1074 -+ 23.1075 -+ if (column + increment > width && break_spaces && last_blank_pos) 23.1076 -+ { 23.1077 -+ fwrite (line_out, sizeof(char), last_blank_pos, stdout); 23.1078 -+ putchar ('\n'); 23.1079 -+ 23.1080 -+ offset_out = offset_out - last_blank_pos; 23.1081 -+ column = column - last_blank_column + ((is_cr_after_last_blank) 23.1082 -+ ? last_blank_increment : bs_following_last_blank_num); 23.1083 -+ memmove (line_out, line_out + last_blank_pos, offset_out); 23.1084 -+ CLEAR_FLAGS; 23.1085 -+ goto rescan; 23.1086 -+ } 23.1087 -+ 23.1088 -+ if (column + increment > width && column != 0) 23.1089 -+ { 23.1090 -+ fwrite (line_out, sizeof(char), offset_out, stdout); 23.1091 -+ START_NEW_LINE; 23.1092 -+ goto rescan; 23.1093 -+ } 23.1094 -+ 23.1095 -+ if (allocated_out < offset_out + mblength) 23.1096 -+ { 23.1097 -+ line_out = X2REALLOC (line_out, &allocated_out); 23.1098 -+ } 23.1099 -+ 23.1100 -+ memcpy (line_out + offset_out, bufpos, mblength); 23.1101 -+ offset_out += mblength; 23.1102 -+ column += increment; 23.1103 -+ 23.1104 -+ if (is_blank_seen && !convfail && wc == L'\r') 23.1105 -+ is_cr_after_last_blank = 1; 23.1106 -+ 23.1107 -+ if (is_bs_following_last_blank && !convfail && wc == L'\b') 23.1108 -+ ++bs_following_last_blank_num; 23.1109 -+ else 23.1110 -+ is_bs_following_last_blank = 0; 23.1111 -+ 23.1112 -+ if (break_spaces && !convfail && iswblank (wc)) 23.1113 -+ { 23.1114 -+ last_blank_pos = offset_out; 23.1115 -+ last_blank_column = column; 23.1116 -+ is_blank_seen = 1; 23.1117 -+ last_blank_increment = increment; 23.1118 -+ is_bs_following_last_blank = 1; 23.1119 -+ bs_following_last_blank_num = 0; 23.1120 -+ is_cr_after_last_blank = 0; 23.1121 -+ } 23.1122 -+ } 23.1123 -+ 23.1124 -+ *saved_errno = errno; 23.1125 - 23.1126 - if (offset_out) 23.1127 - fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); 23.1128 - 23.1129 -+} 23.1130 -+#endif 23.1131 -+ 23.1132 -+/* Fold file FILENAME, or standard input if FILENAME is "-", 23.1133 -+ to stdout, with maximum line length WIDTH. 23.1134 -+ Return 0 if successful, 1 if an error occurs. */ 23.1135 -+ 23.1136 -+static bool 23.1137 -+fold_file (char const *filename, size_t width) 23.1138 -+{ 23.1139 -+ FILE *istream; 23.1140 -+ int saved_errno; 23.1141 -+ 23.1142 -+ if (STREQ (filename, "-")) 23.1143 -+ { 23.1144 -+ istream = stdin; 23.1145 -+ have_read_stdin = 1; 23.1146 -+ } 23.1147 -+ else 23.1148 -+ istream = fopen (filename, "r"); 23.1149 -+ 23.1150 -+ if (istream == NULL) 23.1151 -+ { 23.1152 -+ error (0, errno, "%s", quotef (filename)); 23.1153 -+ return 1; 23.1154 -+ } 23.1155 -+ 23.1156 -+ /* Define how ISTREAM is being folded. */ 23.1157 -+#if HAVE_MBRTOWC 23.1158 -+ if (MB_CUR_MAX > 1) 23.1159 -+ fold_multibyte_text (istream, width, &saved_errno); 23.1160 -+ else 23.1161 -+#endif 23.1162 -+ fold_text (istream, width, &saved_errno); 23.1163 -+ 23.1164 - if (ferror (istream)) 23.1165 - { 23.1166 - error (0, saved_errno, "%s", quotef (filename)); 23.1167 -@@ -251,7 +498,8 @@ main (int argc, char **argv) 23.1168 - 23.1169 - atexit (close_stdout); 23.1170 - 23.1171 -- break_spaces = count_bytes = have_read_stdin = false; 23.1172 -+ operating_mode = column_mode; 23.1173 -+ break_spaces = have_read_stdin = false; 23.1174 - 23.1175 - while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) 23.1176 - { 23.1177 -@@ -260,7 +508,15 @@ main (int argc, char **argv) 23.1178 - switch (optc) 23.1179 - { 23.1180 - case 'b': /* Count bytes rather than columns. */ 23.1181 -- count_bytes = true; 23.1182 -+ if (operating_mode != column_mode) 23.1183 -+ FATAL_ERROR (_("only one way of folding may be specified")); 23.1184 -+ operating_mode = byte_mode; 23.1185 -+ break; 23.1186 -+ 23.1187 -+ case 'c': 23.1188 -+ if (operating_mode != column_mode) 23.1189 -+ FATAL_ERROR (_("only one way of folding may be specified")); 23.1190 -+ operating_mode = character_mode; 23.1191 - break; 23.1192 - 23.1193 - case 's': /* Break at word boundaries. */ 23.1194 -diff -Naurp coreutils-8.25-orig/src/join.c coreutils-8.25/src/join.c 23.1195 ---- coreutils-8.25-orig/src/join.c 2016-01-13 05:08:59.000000000 -0600 23.1196 -+++ coreutils-8.25/src/join.c 2016-02-08 19:07:10.303944625 -0600 23.1197 -@@ -22,18 +22,32 @@ 23.1198 - #include <sys/types.h> 23.1199 - #include <getopt.h> 23.1200 - 23.1201 -+/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth(). */ 23.1202 -+#if HAVE_WCHAR_H 23.1203 -+# include <wchar.h> 23.1204 -+#endif 23.1205 -+ 23.1206 -+/* Get iswblank(), towupper. */ 23.1207 -+#if HAVE_WCTYPE_H 23.1208 -+# include <wctype.h> 23.1209 -+#endif 23.1210 -+ 23.1211 - #include "system.h" 23.1212 - #include "error.h" 23.1213 - #include "fadvise.h" 23.1214 - #include "hard-locale.h" 23.1215 - #include "linebuffer.h" 23.1216 --#include "memcasecmp.h" 23.1217 - #include "quote.h" 23.1218 - #include "stdio--.h" 23.1219 - #include "xmemcoll.h" 23.1220 - #include "xstrtol.h" 23.1221 - #include "argmatch.h" 23.1222 - 23.1223 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 23.1224 -+#if HAVE_MBRTOWC && defined mbstate_t 23.1225 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 23.1226 -+#endif 23.1227 -+ 23.1228 - /* The official name of this program (e.g., no 'g' prefix). */ 23.1229 - #define PROGRAM_NAME "join" 23.1230 - 23.1231 -@@ -135,10 +149,12 @@ static struct outlist outlist_head; 23.1232 - /* Last element in 'outlist', where a new element can be added. */ 23.1233 - static struct outlist *outlist_end = &outlist_head; 23.1234 - 23.1235 --/* Tab character separating fields. If negative, fields are separated 23.1236 -- by any nonempty string of blanks, otherwise by exactly one 23.1237 -- tab character whose value (when cast to unsigned char) equals TAB. */ 23.1238 --static int tab = -1; 23.1239 -+/* Tab character separating fields. If NULL, fields are separated 23.1240 -+ by any nonempty string of blanks. */ 23.1241 -+static char *tab = NULL; 23.1242 -+ 23.1243 -+/* The number of bytes used for tab. */ 23.1244 -+static size_t tablen = 0; 23.1245 - 23.1246 - /* If nonzero, check that the input is correctly ordered. */ 23.1247 - static enum 23.1248 -@@ -275,13 +291,14 @@ xfields (struct line *line) 23.1249 - if (ptr == lim) 23.1250 - return; 23.1251 - 23.1252 -- if (0 <= tab && tab != '\n') 23.1253 -+ if (tab != NULL) 23.1254 - { 23.1255 -+ unsigned char t = tab[0]; 23.1256 - char *sep; 23.1257 -- for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1) 23.1258 -+ for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1) 23.1259 - extract_field (line, ptr, sep - ptr); 23.1260 - } 23.1261 -- else if (tab < 0) 23.1262 -+ else 23.1263 - { 23.1264 - /* Skip leading blanks before the first field. */ 23.1265 - while (field_sep (*ptr)) 23.1266 -@@ -305,6 +322,147 @@ xfields (struct line *line) 23.1267 - extract_field (line, ptr, lim - ptr); 23.1268 - } 23.1269 - 23.1270 -+#if HAVE_MBRTOWC 23.1271 -+static void 23.1272 -+xfields_multibyte (struct line *line) 23.1273 -+{ 23.1274 -+ char *ptr = line->buf.buffer; 23.1275 -+ char const *lim = ptr + line->buf.length - 1; 23.1276 -+ wchar_t wc = 0; 23.1277 -+ size_t mblength = 1; 23.1278 -+ mbstate_t state, state_bak; 23.1279 -+ 23.1280 -+ memset (&state, 0, sizeof (mbstate_t)); 23.1281 -+ 23.1282 -+ if (ptr >= lim) 23.1283 -+ return; 23.1284 -+ 23.1285 -+ if (tab != NULL) 23.1286 -+ { 23.1287 -+ char *sep = ptr; 23.1288 -+ for (; ptr < lim; ptr = sep + mblength) 23.1289 -+ { 23.1290 -+ sep = ptr; 23.1291 -+ while (sep < lim) 23.1292 -+ { 23.1293 -+ state_bak = state; 23.1294 -+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 23.1295 -+ 23.1296 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 23.1297 -+ { 23.1298 -+ mblength = 1; 23.1299 -+ state = state_bak; 23.1300 -+ } 23.1301 -+ mblength = (mblength < 1) ? 1 : mblength; 23.1302 -+ 23.1303 -+ if (mblength == tablen && !memcmp (sep, tab, mblength)) 23.1304 -+ break; 23.1305 -+ else 23.1306 -+ { 23.1307 -+ sep += mblength; 23.1308 -+ continue; 23.1309 -+ } 23.1310 -+ } 23.1311 -+ 23.1312 -+ if (sep >= lim) 23.1313 -+ break; 23.1314 -+ 23.1315 -+ extract_field (line, ptr, sep - ptr); 23.1316 -+ } 23.1317 -+ } 23.1318 -+ else 23.1319 -+ { 23.1320 -+ /* Skip leading blanks before the first field. */ 23.1321 -+ while(ptr < lim) 23.1322 -+ { 23.1323 -+ state_bak = state; 23.1324 -+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 23.1325 -+ 23.1326 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 23.1327 -+ { 23.1328 -+ mblength = 1; 23.1329 -+ state = state_bak; 23.1330 -+ break; 23.1331 -+ } 23.1332 -+ mblength = (mblength < 1) ? 1 : mblength; 23.1333 -+ 23.1334 -+ if (!iswblank(wc) && wc != '\n') 23.1335 -+ break; 23.1336 -+ ptr += mblength; 23.1337 -+ } 23.1338 -+ 23.1339 -+ do 23.1340 -+ { 23.1341 -+ char *sep; 23.1342 -+ state_bak = state; 23.1343 -+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 23.1344 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 23.1345 -+ { 23.1346 -+ mblength = 1; 23.1347 -+ state = state_bak; 23.1348 -+ break; 23.1349 -+ } 23.1350 -+ mblength = (mblength < 1) ? 1 : mblength; 23.1351 -+ 23.1352 -+ sep = ptr + mblength; 23.1353 -+ while (sep < lim) 23.1354 -+ { 23.1355 -+ state_bak = state; 23.1356 -+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 23.1357 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 23.1358 -+ { 23.1359 -+ mblength = 1; 23.1360 -+ state = state_bak; 23.1361 -+ break; 23.1362 -+ } 23.1363 -+ mblength = (mblength < 1) ? 1 : mblength; 23.1364 -+ 23.1365 -+ if (iswblank (wc) || wc == '\n') 23.1366 -+ break; 23.1367 -+ 23.1368 -+ sep += mblength; 23.1369 -+ } 23.1370 -+ 23.1371 -+ extract_field (line, ptr, sep - ptr); 23.1372 -+ if (sep >= lim) 23.1373 -+ return; 23.1374 -+ 23.1375 -+ state_bak = state; 23.1376 -+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 23.1377 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 23.1378 -+ { 23.1379 -+ mblength = 1; 23.1380 -+ state = state_bak; 23.1381 -+ break; 23.1382 -+ } 23.1383 -+ mblength = (mblength < 1) ? 1 : mblength; 23.1384 -+ 23.1385 -+ ptr = sep + mblength; 23.1386 -+ while (ptr < lim) 23.1387 -+ { 23.1388 -+ state_bak = state; 23.1389 -+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 23.1390 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 23.1391 -+ { 23.1392 -+ mblength = 1; 23.1393 -+ state = state_bak; 23.1394 -+ break; 23.1395 -+ } 23.1396 -+ mblength = (mblength < 1) ? 1 : mblength; 23.1397 -+ 23.1398 -+ if (!iswblank (wc) && wc != '\n') 23.1399 -+ break; 23.1400 -+ 23.1401 -+ ptr += mblength; 23.1402 -+ } 23.1403 -+ } 23.1404 -+ while (ptr < lim); 23.1405 -+ } 23.1406 -+ 23.1407 -+ extract_field (line, ptr, lim - ptr); 23.1408 -+} 23.1409 -+#endif 23.1410 -+ 23.1411 - static void 23.1412 - freeline (struct line *line) 23.1413 - { 23.1414 -@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct 23.1415 - size_t jf_1, size_t jf_2) 23.1416 - { 23.1417 - /* Start of field to compare in each file. */ 23.1418 -- char *beg1; 23.1419 -- char *beg2; 23.1420 -- 23.1421 -- size_t len1; 23.1422 -- size_t len2; /* Length of fields to compare. */ 23.1423 -+ char *beg[2]; 23.1424 -+ char *copy[2]; 23.1425 -+ size_t len[2]; /* Length of fields to compare. */ 23.1426 - int diff; 23.1427 -+ int i, j; 23.1428 -+ int mallocd = 0; 23.1429 - 23.1430 - if (jf_1 < line1->nfields) 23.1431 - { 23.1432 -- beg1 = line1->fields[jf_1].beg; 23.1433 -- len1 = line1->fields[jf_1].len; 23.1434 -+ beg[0] = line1->fields[jf_1].beg; 23.1435 -+ len[0] = line1->fields[jf_1].len; 23.1436 - } 23.1437 - else 23.1438 - { 23.1439 -- beg1 = NULL; 23.1440 -- len1 = 0; 23.1441 -+ beg[0] = NULL; 23.1442 -+ len[0] = 0; 23.1443 - } 23.1444 - 23.1445 - if (jf_2 < line2->nfields) 23.1446 - { 23.1447 -- beg2 = line2->fields[jf_2].beg; 23.1448 -- len2 = line2->fields[jf_2].len; 23.1449 -+ beg[1] = line2->fields[jf_2].beg; 23.1450 -+ len[1] = line2->fields[jf_2].len; 23.1451 - } 23.1452 - else 23.1453 - { 23.1454 -- beg2 = NULL; 23.1455 -- len2 = 0; 23.1456 -+ beg[1] = NULL; 23.1457 -+ len[1] = 0; 23.1458 - } 23.1459 - 23.1460 -- if (len1 == 0) 23.1461 -- return len2 == 0 ? 0 : -1; 23.1462 -- if (len2 == 0) 23.1463 -+ if (len[0] == 0) 23.1464 -+ return len[1] == 0 ? 0 : -1; 23.1465 -+ if (len[1] == 0) 23.1466 - return 1; 23.1467 - 23.1468 - if (ignore_case) 23.1469 - { 23.1470 -- /* FIXME: ignore_case does not work with NLS (in particular, 23.1471 -- with multibyte chars). */ 23.1472 -- diff = memcasecmp (beg1, beg2, MIN (len1, len2)); 23.1473 -+#ifdef HAVE_MBRTOWC 23.1474 -+ if (MB_CUR_MAX > 1) 23.1475 -+ { 23.1476 -+ size_t mblength; 23.1477 -+ wchar_t wc, uwc; 23.1478 -+ mbstate_t state, state_bak; 23.1479 -+ 23.1480 -+ memset (&state, '\0', sizeof (mbstate_t)); 23.1481 -+ 23.1482 -+ for (i = 0; i < 2; i++) 23.1483 -+ { 23.1484 -+ mallocd = 1; 23.1485 -+ copy[i] = xmalloc (len[i] + 1); 23.1486 -+ memset (copy[i], '\0',len[i] + 1); 23.1487 -+ 23.1488 -+ for (j = 0; j < MIN (len[0], len[1]);) 23.1489 -+ { 23.1490 -+ state_bak = state; 23.1491 -+ mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state); 23.1492 -+ 23.1493 -+ switch (mblength) 23.1494 -+ { 23.1495 -+ case (size_t) -1: 23.1496 -+ case (size_t) -2: 23.1497 -+ state = state_bak; 23.1498 -+ /* Fall through */ 23.1499 -+ case 0: 23.1500 -+ mblength = 1; 23.1501 -+ break; 23.1502 -+ 23.1503 -+ default: 23.1504 -+ uwc = towupper (wc); 23.1505 -+ 23.1506 -+ if (uwc != wc) 23.1507 -+ { 23.1508 -+ mbstate_t state_wc; 23.1509 -+ size_t mblen; 23.1510 -+ 23.1511 -+ memset (&state_wc, '\0', sizeof (mbstate_t)); 23.1512 -+ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); 23.1513 -+ assert (mblen != (size_t)-1); 23.1514 -+ } 23.1515 -+ else 23.1516 -+ memcpy (copy[i] + j, beg[i] + j, mblength); 23.1517 -+ } 23.1518 -+ j += mblength; 23.1519 -+ } 23.1520 -+ copy[i][j] = '\0'; 23.1521 -+ } 23.1522 -+ } 23.1523 -+ else 23.1524 -+#endif 23.1525 -+ { 23.1526 -+ for (i = 0; i < 2; i++) 23.1527 -+ { 23.1528 -+ mallocd = 1; 23.1529 -+ copy[i] = xmalloc (len[i] + 1); 23.1530 -+ 23.1531 -+ for (j = 0; j < MIN (len[0], len[1]); j++) 23.1532 -+ copy[i][j] = toupper (beg[i][j]); 23.1533 -+ 23.1534 -+ copy[i][j] = '\0'; 23.1535 -+ } 23.1536 -+ } 23.1537 - } 23.1538 - else 23.1539 - { 23.1540 -- if (hard_LC_COLLATE) 23.1541 -- return xmemcoll (beg1, len1, beg2, len2); 23.1542 -- diff = memcmp (beg1, beg2, MIN (len1, len2)); 23.1543 -+ copy[0] = beg[0]; 23.1544 -+ copy[1] = beg[1]; 23.1545 -+ } 23.1546 -+ 23.1547 -+ if (hard_LC_COLLATE) 23.1548 -+ { 23.1549 -+ diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); 23.1550 -+ 23.1551 -+ if (mallocd) 23.1552 -+ for (i = 0; i < 2; i++) 23.1553 -+ free (copy[i]); 23.1554 -+ 23.1555 -+ return diff; 23.1556 - } 23.1557 -+ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); 23.1558 -+ 23.1559 -+ if (mallocd) 23.1560 -+ for (i = 0; i < 2; i++) 23.1561 -+ free (copy[i]); 23.1562 -+ 23.1563 - 23.1564 - if (diff) 23.1565 - return diff; 23.1566 -- return len1 < len2 ? -1 : len1 != len2; 23.1567 -+ return len[0] - len[1]; 23.1568 - } 23.1569 - 23.1570 - /* Check that successive input lines PREV and CURRENT from input file 23.1571 -@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep, 23.1572 - } 23.1573 - ++line_no[which - 1]; 23.1574 - 23.1575 -+#if HAVE_MBRTOWC 23.1576 -+ if (MB_CUR_MAX > 1) 23.1577 -+ xfields_multibyte (line); 23.1578 -+ else 23.1579 -+#endif 23.1580 - xfields (line); 23.1581 - 23.1582 - if (prevline[which - 1]) 23.1583 -@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *li 23.1584 - 23.1585 - /* Output all the fields in line, other than the join field. */ 23.1586 - 23.1587 -+#define PUT_TAB_CHAR \ 23.1588 -+ do \ 23.1589 -+ { \ 23.1590 -+ (tab != NULL) ? \ 23.1591 -+ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ 23.1592 -+ } \ 23.1593 -+ while (0) 23.1594 -+ 23.1595 - static void 23.1596 - prfields (struct line const *line, size_t join_field, size_t autocount) 23.1597 - { 23.1598 - size_t i; 23.1599 - size_t nfields = autoformat ? autocount : line->nfields; 23.1600 -- char output_separator = tab < 0 ? ' ' : tab; 23.1601 - 23.1602 - for (i = 0; i < join_field && i < nfields; ++i) 23.1603 - { 23.1604 -- putchar (output_separator); 23.1605 -+ PUT_TAB_CHAR; 23.1606 - prfield (i, line); 23.1607 - } 23.1608 - for (i = join_field + 1; i < nfields; ++i) 23.1609 - { 23.1610 -- putchar (output_separator); 23.1611 -+ PUT_TAB_CHAR; 23.1612 - prfield (i, line); 23.1613 - } 23.1614 - } 23.1615 -@@ -591,7 +838,6 @@ static void 23.1616 - prjoin (struct line const *line1, struct line const *line2) 23.1617 - { 23.1618 - const struct outlist *outlist; 23.1619 -- char output_separator = tab < 0 ? ' ' : tab; 23.1620 - size_t field; 23.1621 - struct line const *line; 23.1622 - 23.1623 -@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct 23.1624 - o = o->next; 23.1625 - if (o == NULL) 23.1626 - break; 23.1627 -- putchar (output_separator); 23.1628 -+ PUT_TAB_CHAR; 23.1629 - } 23.1630 - putchar (eolchar); 23.1631 - } 23.1632 -@@ -1103,21 +1349,46 @@ main (int argc, char **argv) 23.1633 - 23.1634 - case 't': 23.1635 - { 23.1636 -- unsigned char newtab = optarg[0]; 23.1637 -+ char *newtab = NULL; 23.1638 -+ size_t newtablen; 23.1639 -+ newtab = xstrdup (optarg); 23.1640 -+#if HAVE_MBRTOWC 23.1641 -+ if (MB_CUR_MAX > 1) 23.1642 -+ { 23.1643 -+ mbstate_t state; 23.1644 -+ 23.1645 -+ memset (&state, 0, sizeof (mbstate_t)); 23.1646 -+ newtablen = mbrtowc (NULL, newtab, 23.1647 -+ strnlen (newtab, MB_LEN_MAX), 23.1648 -+ &state); 23.1649 -+ if (newtablen == (size_t) 0 23.1650 -+ || newtablen == (size_t) -1 23.1651 -+ || newtablen == (size_t) -2) 23.1652 -+ newtablen = 1; 23.1653 -+ } 23.1654 -+ else 23.1655 -+#endif 23.1656 -+ newtablen = 1; 23.1657 - if (! newtab) 23.1658 -- newtab = '\n'; /* '' => process the whole line. */ 23.1659 -+ { 23.1660 -+ newtab = (char*)"\n"; /* '' => process the whole line. */ 23.1661 -+ } 23.1662 - else if (optarg[1]) 23.1663 - { 23.1664 -- if (STREQ (optarg, "\\0")) 23.1665 -- newtab = '\0'; 23.1666 -- else 23.1667 -- error (EXIT_FAILURE, 0, _("multi-character tab %s"), 23.1668 -- quote (optarg)); 23.1669 -+ if (newtablen == 1 && newtab[1]) 23.1670 -+ { 23.1671 -+ if (STREQ (newtab, "\\0")) 23.1672 -+ newtab[0] = '\0'; 23.1673 -+ } 23.1674 -+ } 23.1675 -+ if (tab != NULL && strcmp (tab, newtab)) 23.1676 -+ { 23.1677 -+ free (newtab); 23.1678 -+ error (EXIT_FAILURE, 0, _("incompatible tabs")); 23.1679 - } 23.1680 -- if (0 <= tab && tab != newtab) 23.1681 -- error (EXIT_FAILURE, 0, _("incompatible tabs")); 23.1682 - tab = newtab; 23.1683 -- } 23.1684 -+ tablen = newtablen; 23.1685 -+ } 23.1686 - break; 23.1687 - 23.1688 - case 'z': 23.1689 -diff -Naurp coreutils-8.25-orig/src/pr.c coreutils-8.25/src/pr.c 23.1690 ---- coreutils-8.25-orig/src/pr.c 2016-01-01 07:48:50.000000000 -0600 23.1691 -+++ coreutils-8.25/src/pr.c 2016-02-08 19:07:10.306944635 -0600 23.1692 -@@ -311,6 +311,24 @@ 23.1693 - 23.1694 - #include <getopt.h> 23.1695 - #include <sys/types.h> 23.1696 -+ 23.1697 -+/* Get MB_LEN_MAX. */ 23.1698 -+#include <limits.h> 23.1699 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 23.1700 -+ installation; work around this configuration error. */ 23.1701 -+#if !defined MB_LEN_MAX || MB_LEN_MAX == 1 23.1702 -+# define MB_LEN_MAX 16 23.1703 -+#endif 23.1704 -+ 23.1705 -+/* Get MB_CUR_MAX. */ 23.1706 -+#include <stdlib.h> 23.1707 -+ 23.1708 -+/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */ 23.1709 -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ 23.1710 -+#if HAVE_WCHAR_H 23.1711 -+# include <wchar.h> 23.1712 -+#endif 23.1713 -+ 23.1714 - #include "system.h" 23.1715 - #include "error.h" 23.1716 - #include "fadvise.h" 23.1717 -@@ -323,6 +341,18 @@ 23.1718 - #include "xstrtol.h" 23.1719 - #include "xdectoint.h" 23.1720 - 23.1721 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 23.1722 -+#if HAVE_MBRTOWC && defined mbstate_t 23.1723 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 23.1724 -+#endif 23.1725 -+ 23.1726 -+#ifndef HAVE_DECL_WCWIDTH 23.1727 -+"this configure-time declaration test was not run" 23.1728 -+#endif 23.1729 -+#if !HAVE_DECL_WCWIDTH 23.1730 -+extern int wcwidth (); 23.1731 -+#endif 23.1732 -+ 23.1733 - /* The official name of this program (e.g., no 'g' prefix). */ 23.1734 - #define PROGRAM_NAME "pr" 23.1735 - 23.1736 -@@ -415,7 +445,20 @@ struct COLUMN 23.1737 - 23.1738 - typedef struct COLUMN COLUMN; 23.1739 - 23.1740 --static int char_to_clump (char c); 23.1741 -+/* Funtion pointers to switch functions for single byte locale or for 23.1742 -+ multibyte locale. If multibyte functions do not exist in your sysytem, 23.1743 -+ these pointers always point the function for single byte locale. */ 23.1744 -+static void (*print_char) (char c); 23.1745 -+static int (*char_to_clump) (char c); 23.1746 -+ 23.1747 -+/* Functions for single byte locale. */ 23.1748 -+static void print_char_single (char c); 23.1749 -+static int char_to_clump_single (char c); 23.1750 -+ 23.1751 -+/* Functions for multibyte locale. */ 23.1752 -+static void print_char_multi (char c); 23.1753 -+static int char_to_clump_multi (char c); 23.1754 -+ 23.1755 - static bool read_line (COLUMN *p); 23.1756 - static bool print_page (void); 23.1757 - static bool print_stored (COLUMN *p); 23.1758 -@@ -427,6 +470,7 @@ static void add_line_number (COLUMN *p); 23.1759 - static void getoptnum (const char *n_str, int min, int *num, 23.1760 - const char *errfmt); 23.1761 - static void getoptarg (char *arg, char switch_char, char *character, 23.1762 -+ int *character_length, int *character_width, 23.1763 - int *number); 23.1764 - static void print_files (int number_of_files, char **av); 23.1765 - static void init_parameters (int number_of_files); 23.1766 -@@ -440,7 +484,6 @@ static void store_char (char c); 23.1767 - static void pad_down (unsigned int lines); 23.1768 - static void read_rest_of_line (COLUMN *p); 23.1769 - static void skip_read (COLUMN *p, int column_number); 23.1770 --static void print_char (char c); 23.1771 - static void cleanup (void); 23.1772 - static void print_sep_string (void); 23.1773 - static void separator_string (const char *optarg_S); 23.1774 -@@ -452,7 +495,7 @@ static COLUMN *column_vector; 23.1775 - we store the leftmost columns contiguously in buff. 23.1776 - To print a line from buff, get the index of the first character 23.1777 - from line_vector[i], and print up to line_vector[i + 1]. */ 23.1778 --static char *buff; 23.1779 -+static unsigned char *buff; 23.1780 - 23.1781 - /* Index of the position in buff where the next character 23.1782 - will be stored. */ 23.1783 -@@ -556,7 +599,7 @@ static int chars_per_column; 23.1784 - static bool untabify_input = false; 23.1785 - 23.1786 - /* (-e) The input tab character. */ 23.1787 --static char input_tab_char = '\t'; 23.1788 -+static char input_tab_char[MB_LEN_MAX] = "\t"; 23.1789 - 23.1790 - /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... 23.1791 - where the leftmost column is 1. */ 23.1792 -@@ -566,7 +609,10 @@ static int chars_per_input_tab = 8; 23.1793 - static bool tabify_output = false; 23.1794 - 23.1795 - /* (-i) The output tab character. */ 23.1796 --static char output_tab_char = '\t'; 23.1797 -+static char output_tab_char[MB_LEN_MAX] = "\t"; 23.1798 -+ 23.1799 -+/* (-i) The byte length of output tab character. */ 23.1800 -+static int output_tab_char_length = 1; 23.1801 - 23.1802 - /* (-i) The width of the output tab. */ 23.1803 - static int chars_per_output_tab = 8; 23.1804 -@@ -636,7 +682,13 @@ static int line_number; 23.1805 - static bool numbered_lines = false; 23.1806 - 23.1807 - /* (-n) Character which follows each line number. */ 23.1808 --static char number_separator = '\t'; 23.1809 -+static char number_separator[MB_LEN_MAX] = "\t"; 23.1810 -+ 23.1811 -+/* (-n) The byte length of the character which follows each line number. */ 23.1812 -+static int number_separator_length = 1; 23.1813 -+ 23.1814 -+/* (-n) The character width of the character which follows each line number. */ 23.1815 -+static int number_separator_width = 0; 23.1816 - 23.1817 - /* (-n) line counting starts with 1st line of input file (not with 1st 23.1818 - line of 1st page printed). */ 23.1819 -@@ -689,6 +741,7 @@ static bool use_col_separator = false; 23.1820 - -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ 23.1821 - static char *col_sep_string = (char *) ""; 23.1822 - static int col_sep_length = 0; 23.1823 -+static int col_sep_width = 0; 23.1824 - static char *column_separator = (char *) " "; 23.1825 - static char *line_separator = (char *) "\t"; 23.1826 - 23.1827 -@@ -839,6 +892,13 @@ separator_string (const char *optarg_S) 23.1828 - col_sep_length = (int) strlen (optarg_S); 23.1829 - col_sep_string = xmalloc (col_sep_length + 1); 23.1830 - strcpy (col_sep_string, optarg_S); 23.1831 -+ 23.1832 -+#if HAVE_MBRTOWC 23.1833 -+ if (MB_CUR_MAX > 1) 23.1834 -+ col_sep_width = mbswidth (col_sep_string, 0); 23.1835 -+ else 23.1836 -+#endif 23.1837 -+ col_sep_width = col_sep_length; 23.1838 - } 23.1839 - 23.1840 - int 23.1841 -@@ -863,6 +923,21 @@ main (int argc, char **argv) 23.1842 - 23.1843 - atexit (close_stdout); 23.1844 - 23.1845 -+/* Define which functions are used, the ones for single byte locale or the ones 23.1846 -+ for multibyte locale. */ 23.1847 -+#if HAVE_MBRTOWC 23.1848 -+ if (MB_CUR_MAX > 1) 23.1849 -+ { 23.1850 -+ print_char = print_char_multi; 23.1851 -+ char_to_clump = char_to_clump_multi; 23.1852 -+ } 23.1853 -+ else 23.1854 -+#endif 23.1855 -+ { 23.1856 -+ print_char = print_char_single; 23.1857 -+ char_to_clump = char_to_clump_single; 23.1858 -+ } 23.1859 -+ 23.1860 - n_files = 0; 23.1861 - file_names = (argc > 1 23.1862 - ? xmalloc ((argc - 1) * sizeof (char *)) 23.1863 -@@ -939,8 +1014,12 @@ main (int argc, char **argv) 23.1864 - break; 23.1865 - case 'e': 23.1866 - if (optarg) 23.1867 -- getoptarg (optarg, 'e', &input_tab_char, 23.1868 -- &chars_per_input_tab); 23.1869 -+ { 23.1870 -+ int dummy_length, dummy_width; 23.1871 -+ 23.1872 -+ getoptarg (optarg, 'e', input_tab_char, &dummy_length, 23.1873 -+ &dummy_width, &chars_per_input_tab); 23.1874 -+ } 23.1875 - /* Could check tab width > 0. */ 23.1876 - untabify_input = true; 23.1877 - break; 23.1878 -@@ -953,8 +1032,12 @@ main (int argc, char **argv) 23.1879 - break; 23.1880 - case 'i': 23.1881 - if (optarg) 23.1882 -- getoptarg (optarg, 'i', &output_tab_char, 23.1883 -- &chars_per_output_tab); 23.1884 -+ { 23.1885 -+ int dummy_width; 23.1886 -+ 23.1887 -+ getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length, 23.1888 -+ &dummy_width, &chars_per_output_tab); 23.1889 -+ } 23.1890 - /* Could check tab width > 0. */ 23.1891 - tabify_output = true; 23.1892 - break; 23.1893 -@@ -972,8 +1055,8 @@ main (int argc, char **argv) 23.1894 - case 'n': 23.1895 - numbered_lines = true; 23.1896 - if (optarg) 23.1897 -- getoptarg (optarg, 'n', &number_separator, 23.1898 -- &chars_per_number); 23.1899 -+ getoptarg (optarg, 'n', number_separator, &number_separator_length, 23.1900 -+ &number_separator_width, &chars_per_number); 23.1901 - break; 23.1902 - case 'N': 23.1903 - skip_count = false; 23.1904 -@@ -997,7 +1080,7 @@ main (int argc, char **argv) 23.1905 - old_s = false; 23.1906 - /* Reset an additional input of -s, -S dominates -s */ 23.1907 - col_sep_string = bad_cast (""); 23.1908 -- col_sep_length = 0; 23.1909 -+ col_sep_length = col_sep_width = 0; 23.1910 - use_col_separator = true; 23.1911 - if (optarg) 23.1912 - separator_string (optarg); 23.1913 -@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, i 23.1914 - a number. */ 23.1915 - 23.1916 - static void 23.1917 --getoptarg (char *arg, char switch_char, char *character, int *number) 23.1918 -+getoptarg (char *arg, char switch_char, char *character, int *character_length, 23.1919 -+ int *character_width, int *number) 23.1920 - { 23.1921 - if (!ISDIGIT (*arg)) 23.1922 -- *character = *arg++; 23.1923 -+ { 23.1924 -+#ifdef HAVE_MBRTOWC 23.1925 -+ if (MB_CUR_MAX > 1) /* for multibyte locale. */ 23.1926 -+ { 23.1927 -+ wchar_t wc; 23.1928 -+ size_t mblength; 23.1929 -+ int width; 23.1930 -+ mbstate_t state = {'\0'}; 23.1931 -+ 23.1932 -+ mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state); 23.1933 -+ 23.1934 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 23.1935 -+ { 23.1936 -+ *character_length = 1; 23.1937 -+ *character_width = 1; 23.1938 -+ } 23.1939 -+ else 23.1940 -+ { 23.1941 -+ *character_length = (mblength < 1) ? 1 : mblength; 23.1942 -+ width = wcwidth (wc); 23.1943 -+ *character_width = (width < 0) ? 0 : width; 23.1944 -+ } 23.1945 -+ 23.1946 -+ strncpy (character, arg, *character_length); 23.1947 -+ arg += *character_length; 23.1948 -+ } 23.1949 -+ else /* for single byte locale. */ 23.1950 -+#endif 23.1951 -+ { 23.1952 -+ *character = *arg++; 23.1953 -+ *character_length = 1; 23.1954 -+ *character_width = 1; 23.1955 -+ } 23.1956 -+ } 23.1957 -+ 23.1958 - if (*arg) 23.1959 - { 23.1960 - long int tmp_long; 23.1961 -@@ -1177,6 +1295,11 @@ static void 23.1962 - init_parameters (int number_of_files) 23.1963 - { 23.1964 - int chars_used_by_number = 0; 23.1965 -+ int mb_len = 1; 23.1966 -+#if HAVE_MBRTOWC 23.1967 -+ if (MB_CUR_MAX > 1) 23.1968 -+ mb_len = MB_LEN_MAX; 23.1969 -+#endif 23.1970 - 23.1971 - lines_per_body = lines_per_page - lines_per_header - lines_per_footer; 23.1972 - if (lines_per_body <= 0) 23.1973 -@@ -1214,7 +1337,7 @@ init_parameters (int number_of_files) 23.1974 - else 23.1975 - col_sep_string = column_separator; 23.1976 - 23.1977 -- col_sep_length = 1; 23.1978 -+ col_sep_length = col_sep_width = 1; 23.1979 - use_col_separator = true; 23.1980 - } 23.1981 - /* It's rather pointless to define a TAB separator with column 23.1982 -@@ -1244,11 +1367,11 @@ init_parameters (int number_of_files) 23.1983 - + TAB_WIDTH (chars_per_input_tab, chars_per_number); */ 23.1984 - 23.1985 - /* Estimate chars_per_text without any margin and keep it constant. */ 23.1986 -- if (number_separator == '\t') 23.1987 -+ if (number_separator[0] == '\t') 23.1988 - number_width = (chars_per_number 23.1989 - + TAB_WIDTH (chars_per_default_tab, chars_per_number)); 23.1990 - else 23.1991 -- number_width = chars_per_number + 1; 23.1992 -+ number_width = chars_per_number + number_separator_width; 23.1993 - 23.1994 - /* The number is part of the column width unless we are 23.1995 - printing files in parallel. */ 23.1996 -@@ -1257,7 +1380,7 @@ init_parameters (int number_of_files) 23.1997 - } 23.1998 - 23.1999 - chars_per_column = (chars_per_line - chars_used_by_number 23.2000 -- - (columns - 1) * col_sep_length) / columns; 23.2001 -+ - (columns - 1) * col_sep_width) / columns; 23.2002 - 23.2003 - if (chars_per_column < 1) 23.2004 - error (EXIT_FAILURE, 0, _("page width too narrow")); 23.2005 -@@ -1275,7 +1398,7 @@ init_parameters (int number_of_files) 23.2006 - We've to use 8 as the lower limit, if we use chars_per_default_tab = 8 23.2007 - to expand a tab which is not an input_tab-char. */ 23.2008 - free (clump_buff); 23.2009 -- clump_buff = xmalloc (MAX (8, chars_per_input_tab)); 23.2010 -+ clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab)); 23.2011 - } 23.2012 - 23.2013 - /* Open the necessary files, 23.2014 -@@ -1383,7 +1506,7 @@ init_funcs (void) 23.2015 - 23.2016 - /* Enlarge p->start_position of first column to use the same form of 23.2017 - padding_not_printed with all columns. */ 23.2018 -- h = h + col_sep_length; 23.2019 -+ h = h + col_sep_width; 23.2020 - 23.2021 - /* This loop takes care of all but the rightmost column. */ 23.2022 - 23.2023 -@@ -1417,7 +1540,7 @@ init_funcs (void) 23.2024 - } 23.2025 - else 23.2026 - { 23.2027 -- h = h_next + col_sep_length; 23.2028 -+ h = h_next + col_sep_width; 23.2029 - h_next = h + chars_per_column; 23.2030 - } 23.2031 - } 23.2032 -@@ -1708,9 +1831,9 @@ static void 23.2033 - align_column (COLUMN *p) 23.2034 - { 23.2035 - padding_not_printed = p->start_position; 23.2036 -- if (padding_not_printed - col_sep_length > 0) 23.2037 -+ if (padding_not_printed - col_sep_width > 0) 23.2038 - { 23.2039 -- pad_across_to (padding_not_printed - col_sep_length); 23.2040 -+ pad_across_to (padding_not_printed - col_sep_width); 23.2041 - padding_not_printed = ANYWHERE; 23.2042 - } 23.2043 - 23.2044 -@@ -1981,13 +2104,13 @@ store_char (char c) 23.2045 - /* May be too generous. */ 23.2046 - buff = X2REALLOC (buff, &buff_allocated); 23.2047 - } 23.2048 -- buff[buff_current++] = c; 23.2049 -+ buff[buff_current++] = (unsigned char) c; 23.2050 - } 23.2051 - 23.2052 - static void 23.2053 - add_line_number (COLUMN *p) 23.2054 - { 23.2055 -- int i; 23.2056 -+ int i, j; 23.2057 - char *s; 23.2058 - int num_width; 23.2059 - 23.2060 -@@ -2004,22 +2127,24 @@ add_line_number (COLUMN *p) 23.2061 - /* Tabification is assumed for multiple columns, also for n-separators, 23.2062 - but 'default n-separator = TAB' hasn't been given priority over 23.2063 - equal column_width also specified by POSIX. */ 23.2064 -- if (number_separator == '\t') 23.2065 -+ if (number_separator[0] == '\t') 23.2066 - { 23.2067 - i = number_width - chars_per_number; 23.2068 - while (i-- > 0) 23.2069 - (p->char_func) (' '); 23.2070 - } 23.2071 - else 23.2072 -- (p->char_func) (number_separator); 23.2073 -+ for (j = 0; j < number_separator_length; j++) 23.2074 -+ (p->char_func) (number_separator[j]); 23.2075 - } 23.2076 - else 23.2077 - /* To comply with POSIX, we avoid any expansion of default TAB 23.2078 - separator with a single column output. No column_width requirement 23.2079 - has to be considered. */ 23.2080 - { 23.2081 -- (p->char_func) (number_separator); 23.2082 -- if (number_separator == '\t') 23.2083 -+ for (j = 0; j < number_separator_length; j++) 23.2084 -+ (p->char_func) (number_separator[j]); 23.2085 -+ if (number_separator[0] == '\t') 23.2086 - output_position = POS_AFTER_TAB (chars_per_output_tab, 23.2087 - output_position); 23.2088 - } 23.2089 -@@ -2180,7 +2305,7 @@ print_white_space (void) 23.2090 - while (goal - h_old > 1 23.2091 - && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) 23.2092 - { 23.2093 -- putchar (output_tab_char); 23.2094 -+ fwrite (output_tab_char, sizeof(char), output_tab_char_length, stdout); 23.2095 - h_old = h_new; 23.2096 - } 23.2097 - while (++h_old <= goal) 23.2098 -@@ -2200,6 +2325,7 @@ print_sep_string (void) 23.2099 - { 23.2100 - char *s; 23.2101 - int l = col_sep_length; 23.2102 -+ int not_space_flag; 23.2103 - 23.2104 - s = col_sep_string; 23.2105 - 23.2106 -@@ -2213,6 +2339,7 @@ print_sep_string (void) 23.2107 - { 23.2108 - for (; separators_not_printed > 0; --separators_not_printed) 23.2109 - { 23.2110 -+ not_space_flag = 0; 23.2111 - while (l-- > 0) 23.2112 - { 23.2113 - /* 3 types of sep_strings: spaces only, spaces and chars, 23.2114 -@@ -2226,12 +2353,15 @@ print_sep_string (void) 23.2115 - } 23.2116 - else 23.2117 - { 23.2118 -+ not_space_flag = 1; 23.2119 - if (spaces_not_printed > 0) 23.2120 - print_white_space (); 23.2121 - putchar (*s++); 23.2122 -- ++output_position; 23.2123 - } 23.2124 - } 23.2125 -+ if (not_space_flag) 23.2126 -+ output_position += col_sep_width; 23.2127 -+ 23.2128 - /* sep_string ends with some spaces */ 23.2129 - if (spaces_not_printed > 0) 23.2130 - print_white_space (); 23.2131 -@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clu 23.2132 - required number of tabs and spaces. */ 23.2133 - 23.2134 - static void 23.2135 --print_char (char c) 23.2136 -+print_char_single (char c) 23.2137 - { 23.2138 - if (tabify_output) 23.2139 - { 23.2140 -@@ -2283,6 +2413,74 @@ print_char (char c) 23.2141 - putchar (c); 23.2142 - } 23.2143 - 23.2144 -+#ifdef HAVE_MBRTOWC 23.2145 -+static void 23.2146 -+print_char_multi (char c) 23.2147 -+{ 23.2148 -+ static size_t mbc_pos = 0; 23.2149 -+ static char mbc[MB_LEN_MAX] = {'\0'}; 23.2150 -+ static mbstate_t state = {'\0'}; 23.2151 -+ mbstate_t state_bak; 23.2152 -+ wchar_t wc; 23.2153 -+ size_t mblength; 23.2154 -+ int width; 23.2155 -+ 23.2156 -+ if (tabify_output) 23.2157 -+ { 23.2158 -+ state_bak = state; 23.2159 -+ mbc[mbc_pos++] = c; 23.2160 -+ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); 23.2161 -+ 23.2162 -+ while (mbc_pos > 0) 23.2163 -+ { 23.2164 -+ switch (mblength) 23.2165 -+ { 23.2166 -+ case (size_t)-2: 23.2167 -+ state = state_bak; 23.2168 -+ return; 23.2169 -+ 23.2170 -+ case (size_t)-1: 23.2171 -+ state = state_bak; 23.2172 -+ ++output_position; 23.2173 -+ putchar (mbc[0]); 23.2174 -+ memmove (mbc, mbc + 1, MB_CUR_MAX - 1); 23.2175 -+ --mbc_pos; 23.2176 -+ break; 23.2177 -+ 23.2178 -+ case 0: 23.2179 -+ mblength = 1; 23.2180 -+ 23.2181 -+ default: 23.2182 -+ if (wc == L' ') 23.2183 -+ { 23.2184 -+ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 23.2185 -+ --mbc_pos; 23.2186 -+ ++spaces_not_printed; 23.2187 -+ return; 23.2188 -+ } 23.2189 -+ else if (spaces_not_printed > 0) 23.2190 -+ print_white_space (); 23.2191 -+ 23.2192 -+ /* Nonprintables are assumed to have width 0, except L'\b'. */ 23.2193 -+ if ((width = wcwidth (wc)) < 1) 23.2194 -+ { 23.2195 -+ if (wc == L'\b') 23.2196 -+ --output_position; 23.2197 -+ } 23.2198 -+ else 23.2199 -+ output_position += width; 23.2200 -+ 23.2201 -+ fwrite (mbc, sizeof(char), mblength, stdout); 23.2202 -+ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 23.2203 -+ mbc_pos -= mblength; 23.2204 -+ } 23.2205 -+ } 23.2206 -+ return; 23.2207 -+ } 23.2208 -+ putchar (c); 23.2209 -+} 23.2210 -+#endif 23.2211 -+ 23.2212 - /* Skip to page PAGE before printing. 23.2213 - PAGE may be larger than total number of pages. */ 23.2214 - 23.2215 -@@ -2462,9 +2660,9 @@ read_line (COLUMN *p) 23.2216 - align_empty_cols = false; 23.2217 - } 23.2218 - 23.2219 -- if (padding_not_printed - col_sep_length > 0) 23.2220 -+ if (padding_not_printed - col_sep_width > 0) 23.2221 - { 23.2222 -- pad_across_to (padding_not_printed - col_sep_length); 23.2223 -+ pad_across_to (padding_not_printed - col_sep_width); 23.2224 - padding_not_printed = ANYWHERE; 23.2225 - } 23.2226 - 23.2227 -@@ -2534,7 +2732,7 @@ print_stored (COLUMN *p) 23.2228 - int i; 23.2229 - 23.2230 - int line = p->current_line++; 23.2231 -- char *first = &buff[line_vector[line]]; 23.2232 -+ unsigned char *first = &buff[line_vector[line]]; 23.2233 - /* FIXME 23.2234 - UMR: Uninitialized memory read: 23.2235 - * This is occurring while in: 23.2236 -@@ -2546,7 +2744,7 @@ print_stored (COLUMN *p) 23.2237 - xmalloc [xmalloc.c:94] 23.2238 - init_store_cols [pr.c:1648] 23.2239 - */ 23.2240 -- char *last = &buff[line_vector[line + 1]]; 23.2241 -+ unsigned char *last = &buff[line_vector[line + 1]]; 23.2242 - 23.2243 - pad_vertically = true; 23.2244 - 23.2245 -@@ -2565,9 +2763,9 @@ print_stored (COLUMN *p) 23.2246 - } 23.2247 - } 23.2248 - 23.2249 -- if (padding_not_printed - col_sep_length > 0) 23.2250 -+ if (padding_not_printed - col_sep_width > 0) 23.2251 - { 23.2252 -- pad_across_to (padding_not_printed - col_sep_length); 23.2253 -+ pad_across_to (padding_not_printed - col_sep_width); 23.2254 - padding_not_printed = ANYWHERE; 23.2255 - } 23.2256 - 23.2257 -@@ -2580,8 +2778,8 @@ print_stored (COLUMN *p) 23.2258 - if (spaces_not_printed == 0) 23.2259 - { 23.2260 - output_position = p->start_position + end_vector[line]; 23.2261 -- if (p->start_position - col_sep_length == chars_per_margin) 23.2262 -- output_position -= col_sep_length; 23.2263 -+ if (p->start_position - col_sep_width == chars_per_margin) 23.2264 -+ output_position -= col_sep_width; 23.2265 - } 23.2266 - 23.2267 - return true; 23.2268 -@@ -2600,7 +2798,7 @@ print_stored (COLUMN *p) 23.2269 - number of characters is 1.) */ 23.2270 - 23.2271 - static int 23.2272 --char_to_clump (char c) 23.2273 -+char_to_clump_single (char c) 23.2274 - { 23.2275 - unsigned char uc = c; 23.2276 - char *s = clump_buff; 23.2277 -@@ -2610,10 +2808,10 @@ char_to_clump (char c) 23.2278 - int chars; 23.2279 - int chars_per_c = 8; 23.2280 - 23.2281 -- if (c == input_tab_char) 23.2282 -+ if (c == input_tab_char[0]) 23.2283 - chars_per_c = chars_per_input_tab; 23.2284 - 23.2285 -- if (c == input_tab_char || c == '\t') 23.2286 -+ if (c == input_tab_char[0] || c == '\t') 23.2287 - { 23.2288 - width = TAB_WIDTH (chars_per_c, input_position); 23.2289 - 23.2290 -@@ -2694,6 +2892,164 @@ char_to_clump (char c) 23.2291 - return chars; 23.2292 - } 23.2293 - 23.2294 -+#ifdef HAVE_MBRTOWC 23.2295 -+static int 23.2296 -+char_to_clump_multi (char c) 23.2297 -+{ 23.2298 -+ static size_t mbc_pos = 0; 23.2299 -+ static char mbc[MB_LEN_MAX] = {'\0'}; 23.2300 -+ static mbstate_t state = {'\0'}; 23.2301 -+ mbstate_t state_bak; 23.2302 -+ wchar_t wc; 23.2303 -+ size_t mblength; 23.2304 -+ int wc_width; 23.2305 -+ register char *s = clump_buff; 23.2306 -+ register int i, j; 23.2307 -+ char esc_buff[4]; 23.2308 -+ int width; 23.2309 -+ int chars; 23.2310 -+ int chars_per_c = 8; 23.2311 -+ 23.2312 -+ state_bak = state; 23.2313 -+ mbc[mbc_pos++] = c; 23.2314 -+ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); 23.2315 -+ 23.2316 -+ width = 0; 23.2317 -+ chars = 0; 23.2318 -+ while (mbc_pos > 0) 23.2319 -+ { 23.2320 -+ switch (mblength) 23.2321 -+ { 23.2322 -+ case (size_t)-2: 23.2323 -+ state = state_bak; 23.2324 -+ return 0; 23.2325 -+ 23.2326 -+ case (size_t)-1: 23.2327 -+ state = state_bak; 23.2328 -+ mblength = 1; 23.2329 -+ 23.2330 -+ if (use_esc_sequence || use_cntrl_prefix) 23.2331 -+ { 23.2332 -+ width = +4; 23.2333 -+ chars = +4; 23.2334 -+ *s++ = '\\'; 23.2335 -+ sprintf (esc_buff, "%03o", (unsigned char) mbc[0]); 23.2336 -+ for (i = 0; i <= 2; ++i) 23.2337 -+ *s++ = (int) esc_buff[i]; 23.2338 -+ } 23.2339 -+ else 23.2340 -+ { 23.2341 -+ width += 1; 23.2342 -+ chars += 1; 23.2343 -+ *s++ = mbc[0]; 23.2344 -+ } 23.2345 -+ break; 23.2346 -+ 23.2347 -+ case 0: 23.2348 -+ mblength = 1; 23.2349 -+ /* Fall through */ 23.2350 -+ 23.2351 -+ default: 23.2352 -+ if (memcmp (mbc, input_tab_char, mblength) == 0) 23.2353 -+ chars_per_c = chars_per_input_tab; 23.2354 -+ 23.2355 -+ if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t') 23.2356 -+ { 23.2357 -+ int width_inc; 23.2358 -+ 23.2359 -+ width_inc = TAB_WIDTH (chars_per_c, input_position); 23.2360 -+ width += width_inc; 23.2361 -+ 23.2362 -+ if (untabify_input) 23.2363 -+ { 23.2364 -+ for (i = width_inc; i; --i) 23.2365 -+ *s++ = ' '; 23.2366 -+ chars += width_inc; 23.2367 -+ } 23.2368 -+ else 23.2369 -+ { 23.2370 -+ for (i = 0; i < mblength; i++) 23.2371 -+ *s++ = mbc[i]; 23.2372 -+ chars += mblength; 23.2373 -+ } 23.2374 -+ } 23.2375 -+ else if ((wc_width = wcwidth (wc)) < 1) 23.2376 -+ { 23.2377 -+ if (use_esc_sequence) 23.2378 -+ { 23.2379 -+ for (i = 0; i < mblength; i++) 23.2380 -+ { 23.2381 -+ width += 4; 23.2382 -+ chars += 4; 23.2383 -+ *s++ = '\\'; 23.2384 -+ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); 23.2385 -+ for (j = 0; j <= 2; ++j) 23.2386 -+ *s++ = (int) esc_buff[j]; 23.2387 -+ } 23.2388 -+ } 23.2389 -+ else if (use_cntrl_prefix) 23.2390 -+ { 23.2391 -+ if (wc < 0200) 23.2392 -+ { 23.2393 -+ width += 2; 23.2394 -+ chars += 2; 23.2395 -+ *s++ = '^'; 23.2396 -+ *s++ = wc ^ 0100; 23.2397 -+ } 23.2398 -+ else 23.2399 -+ { 23.2400 -+ for (i = 0; i < mblength; i++) 23.2401 -+ { 23.2402 -+ width += 4; 23.2403 -+ chars += 4; 23.2404 -+ *s++ = '\\'; 23.2405 -+ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); 23.2406 -+ for (j = 0; j <= 2; ++j) 23.2407 -+ *s++ = (int) esc_buff[j]; 23.2408 -+ } 23.2409 -+ } 23.2410 -+ } 23.2411 -+ else if (wc == L'\b') 23.2412 -+ { 23.2413 -+ width += -1; 23.2414 -+ chars += 1; 23.2415 -+ *s++ = c; 23.2416 -+ } 23.2417 -+ else 23.2418 -+ { 23.2419 -+ width += 0; 23.2420 -+ chars += mblength; 23.2421 -+ for (i = 0; i < mblength; i++) 23.2422 -+ *s++ = mbc[i]; 23.2423 -+ } 23.2424 -+ } 23.2425 -+ else 23.2426 -+ { 23.2427 -+ width += wc_width; 23.2428 -+ chars += mblength; 23.2429 -+ for (i = 0; i < mblength; i++) 23.2430 -+ *s++ = mbc[i]; 23.2431 -+ } 23.2432 -+ } 23.2433 -+ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 23.2434 -+ mbc_pos -= mblength; 23.2435 -+ } 23.2436 -+ 23.2437 -+ /* Too many backspaces must put us in position 0 -- never negative. */ 23.2438 -+ if (width < 0 && input_position == 0) 23.2439 -+ { 23.2440 -+ chars = 0; 23.2441 -+ input_position = 0; 23.2442 -+ } 23.2443 -+ else if (width < 0 && input_position <= -width) 23.2444 -+ input_position = 0; 23.2445 -+ else 23.2446 -+ input_position += width; 23.2447 -+ 23.2448 -+ return chars; 23.2449 -+} 23.2450 -+#endif 23.2451 -+ 23.2452 - /* We've just printed some files and need to clean up things before 23.2453 - looking for more options and printing the next batch of files. 23.2454 - 23.2455 -diff -Naurp coreutils-8.25-orig/src/sort.c coreutils-8.25/src/sort.c 23.2456 ---- coreutils-8.25-orig/src/sort.c 2016-01-16 13:09:33.000000000 -0600 23.2457 -+++ coreutils-8.25/src/sort.c 2016-02-08 19:07:10.310944648 -0600 23.2458 -@@ -29,6 +29,14 @@ 23.2459 - #include <sys/wait.h> 23.2460 - #include <signal.h> 23.2461 - #include <assert.h> 23.2462 -+#if HAVE_WCHAR_H 23.2463 -+# include <wchar.h> 23.2464 -+#endif 23.2465 -+/* Get isw* functions. */ 23.2466 -+#if HAVE_WCTYPE_H 23.2467 -+# include <wctype.h> 23.2468 -+#endif 23.2469 -+ 23.2470 - #include "system.h" 23.2471 - #include "argmatch.h" 23.2472 - #include "error.h" 23.2473 -@@ -163,14 +171,39 @@ static int decimal_point; 23.2474 - /* Thousands separator; if -1, then there isn't one. */ 23.2475 - static int thousands_sep; 23.2476 - 23.2477 -+/* True if -f is specified. */ 23.2478 -+static bool folding; 23.2479 -+ 23.2480 - /* Nonzero if the corresponding locales are hard. */ 23.2481 - static bool hard_LC_COLLATE; 23.2482 --#if HAVE_NL_LANGINFO 23.2483 -+#if HAVE_LANGINFO_CODESET 23.2484 - static bool hard_LC_TIME; 23.2485 - #endif 23.2486 - 23.2487 - #define NONZERO(x) ((x) != 0) 23.2488 - 23.2489 -+/* get a multibyte character's byte length. */ 23.2490 -+#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE) \ 23.2491 -+ do \ 23.2492 -+ { \ 23.2493 -+ wchar_t wc; \ 23.2494 -+ mbstate_t state_bak; \ 23.2495 -+ \ 23.2496 -+ state_bak = STATE; \ 23.2497 -+ mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE); \ 23.2498 -+ \ 23.2499 -+ switch (MBLENGTH) \ 23.2500 -+ { \ 23.2501 -+ case (size_t)-1: \ 23.2502 -+ case (size_t)-2: \ 23.2503 -+ STATE = state_bak; \ 23.2504 -+ /* Fall through. */ \ 23.2505 -+ case 0: \ 23.2506 -+ MBLENGTH = 1; \ 23.2507 -+ } \ 23.2508 -+ } \ 23.2509 -+ while (0) 23.2510 -+ 23.2511 - /* The kind of blanks for '-b' to skip in various options. */ 23.2512 - enum blanktype { bl_start, bl_end, bl_both }; 23.2513 - 23.2514 -@@ -344,13 +377,11 @@ static bool reverse; 23.2515 - they were read if all keys compare equal. */ 23.2516 - static bool stable; 23.2517 - 23.2518 --/* If TAB has this value, blanks separate fields. */ 23.2519 --enum { TAB_DEFAULT = CHAR_MAX + 1 }; 23.2520 -- 23.2521 --/* Tab character separating fields. If TAB_DEFAULT, then fields are 23.2522 -+/* Tab character separating fields. If tab_length is 0, then fields are 23.2523 - separated by the empty string between a non-blank character and a blank 23.2524 - character. */ 23.2525 --static int tab = TAB_DEFAULT; 23.2526 -+static char tab[MB_LEN_MAX + 1]; 23.2527 -+static size_t tab_length = 0; 23.2528 - 23.2529 - /* Flag to remove consecutive duplicate lines from the output. 23.2530 - Only the last of a sequence of equal lines will be output. */ 23.2531 -@@ -810,6 +841,46 @@ reap_all (void) 23.2532 - reap (-1); 23.2533 - } 23.2534 - 23.2535 -+/* Function pointers. */ 23.2536 -+static void 23.2537 -+(*inittables) (void); 23.2538 -+static char * 23.2539 -+(*begfield) (const struct line*, const struct keyfield *); 23.2540 -+static char * 23.2541 -+(*limfield) (const struct line*, const struct keyfield *); 23.2542 -+static void 23.2543 -+(*skipblanks) (char **ptr, char *lim); 23.2544 -+static int 23.2545 -+(*getmonth) (char const *, size_t, char **); 23.2546 -+static int 23.2547 -+(*keycompare) (const struct line *, const struct line *); 23.2548 -+static int 23.2549 -+(*numcompare) (const char *, const char *); 23.2550 -+ 23.2551 -+/* Test for white space multibyte character. 23.2552 -+ Set LENGTH the byte length of investigated multibyte character. */ 23.2553 -+#if HAVE_MBRTOWC 23.2554 -+static int 23.2555 -+ismbblank (const char *str, size_t len, size_t *length) 23.2556 -+{ 23.2557 -+ size_t mblength; 23.2558 -+ wchar_t wc; 23.2559 -+ mbstate_t state; 23.2560 -+ 23.2561 -+ memset (&state, '\0', sizeof(mbstate_t)); 23.2562 -+ mblength = mbrtowc (&wc, str, len, &state); 23.2563 -+ 23.2564 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 23.2565 -+ { 23.2566 -+ *length = 1; 23.2567 -+ return 0; 23.2568 -+ } 23.2569 -+ 23.2570 -+ *length = (mblength < 1) ? 1 : mblength; 23.2571 -+ return iswblank (wc) || wc == '\n'; 23.2572 -+} 23.2573 -+#endif 23.2574 -+ 23.2575 - /* Clean up any remaining temporary files. */ 23.2576 - 23.2577 - static void 23.2578 -@@ -1254,7 +1325,7 @@ zaptemp (char const *name) 23.2579 - free (node); 23.2580 - } 23.2581 - 23.2582 --#if HAVE_NL_LANGINFO 23.2583 -+#if HAVE_LANGINFO_CODESET 23.2584 - 23.2585 - static int 23.2586 - struct_month_cmp (void const *m1, void const *m2) 23.2587 -@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void c 23.2588 - /* Initialize the character class tables. */ 23.2589 - 23.2590 - static void 23.2591 --inittables (void) 23.2592 -+inittables_uni (void) 23.2593 - { 23.2594 - size_t i; 23.2595 - 23.2596 -@@ -1281,7 +1352,7 @@ inittables (void) 23.2597 - fold_toupper[i] = toupper (i); 23.2598 - } 23.2599 - 23.2600 --#if HAVE_NL_LANGINFO 23.2601 -+#if HAVE_LANGINFO_CODESET 23.2602 - /* If we're not in the "C" locale, read different names for months. */ 23.2603 - if (hard_LC_TIME) 23.2604 - { 23.2605 -@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char con 23.2606 - xstrtol_fatal (e, oi, c, long_options, s); 23.2607 - } 23.2608 - 23.2609 -+#if HAVE_MBRTOWC 23.2610 -+static void 23.2611 -+inittables_mb (void) 23.2612 -+{ 23.2613 -+ int i, j, k, l; 23.2614 -+ char *name, *s, *lc_time, *lc_ctype; 23.2615 -+ size_t s_len, mblength; 23.2616 -+ char mbc[MB_LEN_MAX]; 23.2617 -+ wchar_t wc, pwc; 23.2618 -+ mbstate_t state_mb, state_wc; 23.2619 -+ 23.2620 -+ lc_time = setlocale (LC_TIME, ""); 23.2621 -+ if (lc_time) 23.2622 -+ lc_time = xstrdup (lc_time); 23.2623 -+ 23.2624 -+ lc_ctype = setlocale (LC_CTYPE, ""); 23.2625 -+ if (lc_ctype) 23.2626 -+ lc_ctype = xstrdup (lc_ctype); 23.2627 -+ 23.2628 -+ if (lc_time && lc_ctype) 23.2629 -+ /* temporarily set LC_CTYPE to match LC_TIME, so that we can convert 23.2630 -+ * the names of months to upper case */ 23.2631 -+ setlocale (LC_CTYPE, lc_time); 23.2632 -+ 23.2633 -+ for (i = 0; i < MONTHS_PER_YEAR; i++) 23.2634 -+ { 23.2635 -+ s = (char *) nl_langinfo (ABMON_1 + i); 23.2636 -+ s_len = strlen (s); 23.2637 -+ monthtab[i].name = name = (char *) xmalloc (s_len + 1); 23.2638 -+ monthtab[i].val = i + 1; 23.2639 -+ 23.2640 -+ memset (&state_mb, '\0', sizeof (mbstate_t)); 23.2641 -+ memset (&state_wc, '\0', sizeof (mbstate_t)); 23.2642 -+ 23.2643 -+ for (j = 0; j < s_len;) 23.2644 -+ { 23.2645 -+ if (!ismbblank (s + j, s_len - j, &mblength)) 23.2646 -+ break; 23.2647 -+ j += mblength; 23.2648 -+ } 23.2649 -+ 23.2650 -+ for (k = 0; j < s_len;) 23.2651 -+ { 23.2652 -+ mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb); 23.2653 -+ assert (mblength != (size_t)-1 && mblength != (size_t)-2); 23.2654 -+ if (mblength == 0) 23.2655 -+ break; 23.2656 -+ 23.2657 -+ pwc = towupper (wc); 23.2658 -+ if (pwc == wc) 23.2659 -+ { 23.2660 -+ memcpy (mbc, s + j, mblength); 23.2661 -+ j += mblength; 23.2662 -+ } 23.2663 -+ else 23.2664 -+ { 23.2665 -+ j += mblength; 23.2666 -+ mblength = wcrtomb (mbc, pwc, &state_wc); 23.2667 -+ assert (mblength != (size_t)0 && mblength != (size_t)-1); 23.2668 -+ } 23.2669 -+ 23.2670 -+ for (l = 0; l < mblength; l++) 23.2671 -+ name[k++] = mbc[l]; 23.2672 -+ } 23.2673 -+ name[k] = '\0'; 23.2674 -+ } 23.2675 -+ qsort ((void *) monthtab, MONTHS_PER_YEAR, 23.2676 -+ sizeof (struct month), struct_month_cmp); 23.2677 -+ 23.2678 -+ if (lc_time && lc_ctype) 23.2679 -+ /* restore the original locales */ 23.2680 -+ setlocale (LC_CTYPE, lc_ctype); 23.2681 -+ 23.2682 -+ free (lc_ctype); 23.2683 -+ free (lc_time); 23.2684 -+} 23.2685 -+#endif 23.2686 -+ 23.2687 - /* Specify the amount of main memory to use when sorting. */ 23.2688 - static void 23.2689 - specify_sort_size (int oi, char c, char const *s) 23.2690 -@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf 23.2691 - by KEY in LINE. */ 23.2692 - 23.2693 - static char * 23.2694 --begfield (struct line const *line, struct keyfield const *key) 23.2695 -+begfield_uni (const struct line *line, const struct keyfield *key) 23.2696 - { 23.2697 - char *ptr = line->text, *lim = ptr + line->length - 1; 23.2698 - size_t sword = key->sword; 23.2699 -@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struc 23.2700 - /* The leading field separator itself is included in a field when -t 23.2701 - is absent. */ 23.2702 - 23.2703 -- if (tab != TAB_DEFAULT) 23.2704 -+ if (tab_length) 23.2705 - while (ptr < lim && sword--) 23.2706 - { 23.2707 -- while (ptr < lim && *ptr != tab) 23.2708 -+ while (ptr < lim && *ptr != tab[0]) 23.2709 - ++ptr; 23.2710 - if (ptr < lim) 23.2711 - ++ptr; 23.2712 -@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struc 23.2713 - return ptr; 23.2714 - } 23.2715 - 23.2716 -+#if HAVE_MBRTOWC 23.2717 -+static char * 23.2718 -+begfield_mb (const struct line *line, const struct keyfield *key) 23.2719 -+{ 23.2720 -+ int i; 23.2721 -+ char *ptr = line->text, *lim = ptr + line->length - 1; 23.2722 -+ size_t sword = key->sword; 23.2723 -+ size_t schar = key->schar; 23.2724 -+ size_t mblength; 23.2725 -+ mbstate_t state; 23.2726 -+ 23.2727 -+ memset (&state, '\0', sizeof(mbstate_t)); 23.2728 -+ 23.2729 -+ if (tab_length) 23.2730 -+ while (ptr < lim && sword--) 23.2731 -+ { 23.2732 -+ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) 23.2733 -+ { 23.2734 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 23.2735 -+ ptr += mblength; 23.2736 -+ } 23.2737 -+ if (ptr < lim) 23.2738 -+ { 23.2739 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 23.2740 -+ ptr += mblength; 23.2741 -+ } 23.2742 -+ } 23.2743 -+ else 23.2744 -+ while (ptr < lim && sword--) 23.2745 -+ { 23.2746 -+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 23.2747 -+ ptr += mblength; 23.2748 -+ if (ptr < lim) 23.2749 -+ { 23.2750 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 23.2751 -+ ptr += mblength; 23.2752 -+ } 23.2753 -+ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) 23.2754 -+ ptr += mblength; 23.2755 -+ } 23.2756 -+ 23.2757 -+ if (key->skipsblanks) 23.2758 -+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 23.2759 -+ ptr += mblength; 23.2760 -+ 23.2761 -+ for (i = 0; i < schar; i++) 23.2762 -+ { 23.2763 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 23.2764 -+ 23.2765 -+ if (ptr + mblength > lim) 23.2766 -+ break; 23.2767 -+ else 23.2768 -+ ptr += mblength; 23.2769 -+ } 23.2770 -+ 23.2771 -+ return ptr; 23.2772 -+} 23.2773 -+#endif 23.2774 -+ 23.2775 - /* Return the limit of (a pointer to the first character after) the field 23.2776 - in LINE specified by KEY. */ 23.2777 - 23.2778 - static char * 23.2779 --limfield (struct line const *line, struct keyfield const *key) 23.2780 -+limfield_uni (const struct line *line, const struct keyfield *key) 23.2781 - { 23.2782 - char *ptr = line->text, *lim = ptr + line->length - 1; 23.2783 - size_t eword = key->eword, echar = key->echar; 23.2784 -@@ -1653,10 +1861,10 @@ limfield (struct line const *line, struc 23.2785 - 'beginning' is the first character following the delimiting TAB. 23.2786 - Otherwise, leave PTR pointing at the first 'blank' character after 23.2787 - the preceding field. */ 23.2788 -- if (tab != TAB_DEFAULT) 23.2789 -+ if (tab_length) 23.2790 - while (ptr < lim && eword--) 23.2791 - { 23.2792 -- while (ptr < lim && *ptr != tab) 23.2793 -+ while (ptr < lim && *ptr != tab[0]) 23.2794 - ++ptr; 23.2795 - if (ptr < lim && (eword || echar)) 23.2796 - ++ptr; 23.2797 -@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struc 23.2798 - */ 23.2799 - 23.2800 - /* Make LIM point to the end of (one byte past) the current field. */ 23.2801 -- if (tab != TAB_DEFAULT) 23.2802 -+ if (tab_length) 23.2803 - { 23.2804 - char *newlim; 23.2805 -- newlim = memchr (ptr, tab, lim - ptr); 23.2806 -+ newlim = memchr (ptr, tab[0], lim - ptr); 23.2807 - if (newlim) 23.2808 - lim = newlim; 23.2809 - } 23.2810 -@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struc 23.2811 - return ptr; 23.2812 - } 23.2813 - 23.2814 -+#if HAVE_MBRTOWC 23.2815 -+static char * 23.2816 -+limfield_mb (const struct line *line, const struct keyfield *key) 23.2817 -+{ 23.2818 -+ char *ptr = line->text, *lim = ptr + line->length - 1; 23.2819 -+ size_t eword = key->eword, echar = key->echar; 23.2820 -+ int i; 23.2821 -+ size_t mblength; 23.2822 -+ mbstate_t state; 23.2823 -+ 23.2824 -+ if (echar == 0) 23.2825 -+ eword++; /* skip all of end field. */ 23.2826 -+ 23.2827 -+ memset (&state, '\0', sizeof(mbstate_t)); 23.2828 -+ 23.2829 -+ if (tab_length) 23.2830 -+ while (ptr < lim && eword--) 23.2831 -+ { 23.2832 -+ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) 23.2833 -+ { 23.2834 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 23.2835 -+ ptr += mblength; 23.2836 -+ } 23.2837 -+ if (ptr < lim && (eword | echar)) 23.2838 -+ { 23.2839 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 23.2840 -+ ptr += mblength; 23.2841 -+ } 23.2842 -+ } 23.2843 -+ else 23.2844 -+ while (ptr < lim && eword--) 23.2845 -+ { 23.2846 -+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 23.2847 -+ ptr += mblength; 23.2848 -+ if (ptr < lim) 23.2849 -+ { 23.2850 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 23.2851 -+ ptr += mblength; 23.2852 -+ } 23.2853 -+ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) 23.2854 -+ ptr += mblength; 23.2855 -+ } 23.2856 -+ 23.2857 -+ 23.2858 -+# ifdef POSIX_UNSPECIFIED 23.2859 -+ /* Make LIM point to the end of (one byte past) the current field. */ 23.2860 -+ if (tab_length) 23.2861 -+ { 23.2862 -+ char *newlim, *p; 23.2863 -+ 23.2864 -+ newlim = NULL; 23.2865 -+ for (p = ptr; p < lim;) 23.2866 -+ { 23.2867 -+ if (memcmp (p, tab, tab_length) == 0) 23.2868 -+ { 23.2869 -+ newlim = p; 23.2870 -+ break; 23.2871 -+ } 23.2872 -+ 23.2873 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 23.2874 -+ p += mblength; 23.2875 -+ } 23.2876 -+ } 23.2877 -+ else 23.2878 -+ { 23.2879 -+ char *newlim; 23.2880 -+ newlim = ptr; 23.2881 -+ 23.2882 -+ while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength)) 23.2883 -+ newlim += mblength; 23.2884 -+ if (ptr < lim) 23.2885 -+ { 23.2886 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 23.2887 -+ ptr += mblength; 23.2888 -+ } 23.2889 -+ while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength)) 23.2890 -+ newlim += mblength; 23.2891 -+ lim = newlim; 23.2892 -+ } 23.2893 -+# endif 23.2894 -+ 23.2895 -+ if (echar != 0) 23.2896 -+ { 23.2897 -+ /* If we're skipping leading blanks, don't start counting characters 23.2898 -+ * until after skipping past any leading blanks. */ 23.2899 -+ if (key->skipeblanks) 23.2900 -+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 23.2901 -+ ptr += mblength; 23.2902 -+ 23.2903 -+ memset (&state, '\0', sizeof(mbstate_t)); 23.2904 -+ 23.2905 -+ /* Advance PTR by ECHAR (if possible), but no further than LIM. */ 23.2906 -+ for (i = 0; i < echar; i++) 23.2907 -+ { 23.2908 -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 23.2909 -+ 23.2910 -+ if (ptr + mblength > lim) 23.2911 -+ break; 23.2912 -+ else 23.2913 -+ ptr += mblength; 23.2914 -+ } 23.2915 -+ } 23.2916 -+ 23.2917 -+ return ptr; 23.2918 -+} 23.2919 -+#endif 23.2920 -+ 23.2921 -+static void 23.2922 -+skipblanks_uni (char **ptr, char *lim) 23.2923 -+{ 23.2924 -+ while (*ptr < lim && blanks[to_uchar (**ptr)]) 23.2925 -+ ++(*ptr); 23.2926 -+} 23.2927 -+ 23.2928 -+#if HAVE_MBRTOWC 23.2929 -+static void 23.2930 -+skipblanks_mb (char **ptr, char *lim) 23.2931 -+{ 23.2932 -+ size_t mblength; 23.2933 -+ while (*ptr < lim && ismbblank (*ptr, lim - *ptr, &mblength)) 23.2934 -+ (*ptr) += mblength; 23.2935 -+} 23.2936 -+#endif 23.2937 -+ 23.2938 - /* Fill BUF reading from FP, moving buf->left bytes from the end 23.2939 - of buf->buf to the beginning first. If EOF is reached and the 23.2940 - file wasn't terminated by a newline, supply one. Set up BUF's line 23.2941 -@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, c 23.2942 - else 23.2943 - { 23.2944 - if (key->skipsblanks) 23.2945 -- while (blanks[to_uchar (*line_start)]) 23.2946 -- line_start++; 23.2947 -+ { 23.2948 -+#if HAVE_MBRTOWC 23.2949 -+ if (MB_CUR_MAX > 1) 23.2950 -+ { 23.2951 -+ size_t mblength; 23.2952 -+ while (line_start < line->keylim && 23.2953 -+ ismbblank (line_start, 23.2954 -+ line->keylim - line_start, 23.2955 -+ &mblength)) 23.2956 -+ line_start += mblength; 23.2957 -+ } 23.2958 -+ else 23.2959 -+#endif 23.2960 -+ while (blanks[to_uchar (*line_start)]) 23.2961 -+ line_start++; 23.2962 -+ } 23.2963 - line->keybeg = line_start; 23.2964 - } 23.2965 - } 23.2966 -@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char co 23.2967 - hideously fast. */ 23.2968 - 23.2969 - static int 23.2970 --numcompare (char const *a, char const *b) 23.2971 -+numcompare_uni (const char *a, const char *b) 23.2972 - { 23.2973 - while (blanks[to_uchar (*a)]) 23.2974 - a++; 23.2975 -@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b 23.2976 - return strnumcmp (a, b, decimal_point, thousands_sep); 23.2977 - } 23.2978 - 23.2979 -+#if HAVE_MBRTOWC 23.2980 -+static int 23.2981 -+numcompare_mb (const char *a, const char *b) 23.2982 -+{ 23.2983 -+ size_t mblength, len; 23.2984 -+ len = strlen (a); /* okay for UTF-8 */ 23.2985 -+ while (*a && ismbblank (a, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) 23.2986 -+ { 23.2987 -+ a += mblength; 23.2988 -+ len -= mblength; 23.2989 -+ } 23.2990 -+ len = strlen (b); /* okay for UTF-8 */ 23.2991 -+ while (*b && ismbblank (b, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) 23.2992 -+ b += mblength; 23.2993 -+ 23.2994 -+ return strnumcmp (a, b, decimal_point, thousands_sep); 23.2995 -+} 23.2996 -+#endif /* HAV_EMBRTOWC */ 23.2997 -+ 23.2998 - /* Work around a problem whereby the long double value returned by glibc's 23.2999 - strtold ("NaN", ...) contains uninitialized bits: clear all bytes of 23.3000 - A and B before calling strtold. FIXME: remove this function once 23.3001 -@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char 23.3002 - Return 0 if the name in S is not recognized. */ 23.3003 - 23.3004 - static int 23.3005 --getmonth (char const *month, char **ea) 23.3006 -+getmonth_uni (char const *month, size_t len, char **ea) 23.3007 - { 23.3008 - size_t lo = 0; 23.3009 - size_t hi = MONTHS_PER_YEAR; 23.3010 -@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, stru 23.3011 - char saved = *lim; 23.3012 - *lim = '\0'; 23.3013 - 23.3014 -- while (blanks[to_uchar (*beg)]) 23.3015 -- beg++; 23.3016 -+ skipblanks (&beg, lim); 23.3017 - 23.3018 - char *tighter_lim = beg; 23.3019 - 23.3020 - if (lim < beg) 23.3021 - tighter_lim = lim; 23.3022 - else if (key->month) 23.3023 -- getmonth (beg, &tighter_lim); 23.3024 -+ getmonth (beg, lim-beg, &tighter_lim); 23.3025 - else if (key->general_numeric) 23.3026 - ignore_value (strtold (beg, &tighter_lim)); 23.3027 - else if (key->numeric || key->human_numeric) 23.3028 -@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gke 23.3029 - bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) 23.3030 - && !(key->schar || key->echar); 23.3031 - bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ 23.3032 -- if (!gkey_only && tab == TAB_DEFAULT && !line_offset 23.3033 -+ if (!gkey_only && !tab_length && !line_offset 23.3034 - && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) 23.3035 - || (!key->skipsblanks && key->schar) 23.3036 - || (!key->skipeblanks && key->echar))) 23.3037 -@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gke 23.3038 - error (0, 0, _("option '-r' only applies to last-resort comparison")); 23.3039 - } 23.3040 - 23.3041 -+#if HAVE_MBRTOWC 23.3042 -+static int 23.3043 -+getmonth_mb (const char *s, size_t len, char **ea) 23.3044 -+{ 23.3045 -+ char *month; 23.3046 -+ register size_t i; 23.3047 -+ register int lo = 0, hi = MONTHS_PER_YEAR, result; 23.3048 -+ char *tmp; 23.3049 -+ size_t wclength, mblength; 23.3050 -+ const char *pp; 23.3051 -+ const wchar_t *wpp; 23.3052 -+ wchar_t *month_wcs; 23.3053 -+ mbstate_t state; 23.3054 -+ 23.3055 -+ while (len > 0 && ismbblank (s, len, &mblength)) 23.3056 -+ { 23.3057 -+ s += mblength; 23.3058 -+ len -= mblength; 23.3059 -+ } 23.3060 -+ 23.3061 -+ if (len == 0) 23.3062 -+ return 0; 23.3063 -+ 23.3064 -+ if (SIZE_MAX - len < 1) 23.3065 -+ xalloc_die (); 23.3066 -+ 23.3067 -+ month = (char *) xnmalloc (len + 1, MB_CUR_MAX); 23.3068 -+ 23.3069 -+ pp = tmp = (char *) xnmalloc (len + 1, MB_CUR_MAX); 23.3070 -+ memcpy (tmp, s, len); 23.3071 -+ tmp[len] = '\0'; 23.3072 -+ wpp = month_wcs = (wchar_t *) xnmalloc (len + 1, sizeof (wchar_t)); 23.3073 -+ memset (&state, '\0', sizeof (mbstate_t)); 23.3074 -+ 23.3075 -+ wclength = mbsrtowcs (month_wcs, &pp, len + 1, &state); 23.3076 -+ if (wclength == (size_t)-1 || pp != NULL) 23.3077 -+ error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s)); 23.3078 -+ 23.3079 -+ for (i = 0; i < wclength; i++) 23.3080 -+ { 23.3081 -+ month_wcs[i] = towupper(month_wcs[i]); 23.3082 -+ if (iswblank (month_wcs[i])) 23.3083 -+ { 23.3084 -+ month_wcs[i] = L'\0'; 23.3085 -+ break; 23.3086 -+ } 23.3087 -+ } 23.3088 -+ 23.3089 -+ mblength = wcsrtombs (month, &wpp, (len + 1) * MB_CUR_MAX, &state); 23.3090 -+ assert (mblength != (-1) && wpp == NULL); 23.3091 -+ 23.3092 -+ do 23.3093 -+ { 23.3094 -+ int ix = (lo + hi) / 2; 23.3095 -+ 23.3096 -+ if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0) 23.3097 -+ hi = ix; 23.3098 -+ else 23.3099 -+ lo = ix; 23.3100 -+ } 23.3101 -+ while (hi - lo > 1); 23.3102 -+ 23.3103 -+ result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name)) 23.3104 -+ ? monthtab[lo].val : 0); 23.3105 -+ 23.3106 -+ if (ea && result) 23.3107 -+ *ea = (char*) s + strlen (monthtab[lo].name); 23.3108 -+ 23.3109 -+ free (month); 23.3110 -+ free (tmp); 23.3111 -+ free (month_wcs); 23.3112 -+ 23.3113 -+ return result; 23.3114 -+} 23.3115 -+#endif 23.3116 -+ 23.3117 - /* Compare two lines A and B trying every key in sequence until there 23.3118 - are no more keys or a difference is found. */ 23.3119 - 23.3120 - static int 23.3121 --keycompare (struct line const *a, struct line const *b) 23.3122 -+keycompare_uni (const struct line *a, const struct line *b) 23.3123 - { 23.3124 - struct keyfield *key = keylist; 23.3125 - 23.3126 -@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct 23.3127 - else if (key->human_numeric) 23.3128 - diff = human_numcompare (ta, tb); 23.3129 - else if (key->month) 23.3130 -- diff = getmonth (ta, NULL) - getmonth (tb, NULL); 23.3131 -+ diff = getmonth (ta, tlena, NULL) - getmonth (tb, tlenb, NULL); 23.3132 - else if (key->random) 23.3133 - diff = compare_random (ta, tlena, tb, tlenb); 23.3134 - else if (key->version) 23.3135 -@@ -2695,6 +3135,211 @@ keycompare (struct line const *a, struct 23.3136 - return key->reverse ? -diff : diff; 23.3137 - } 23.3138 - 23.3139 -+#if HAVE_MBRTOWC 23.3140 -+static int 23.3141 -+keycompare_mb (const struct line *a, const struct line *b) 23.3142 -+{ 23.3143 -+ struct keyfield *key = keylist; 23.3144 -+ 23.3145 -+ /* For the first iteration only, the key positions have been 23.3146 -+ precomputed for us. */ 23.3147 -+ char *texta = a->keybeg; 23.3148 -+ char *textb = b->keybeg; 23.3149 -+ char *lima = a->keylim; 23.3150 -+ char *limb = b->keylim; 23.3151 -+ 23.3152 -+ size_t mblength_a, mblength_b; 23.3153 -+ wchar_t wc_a, wc_b; 23.3154 -+ mbstate_t state_a, state_b; 23.3155 -+ 23.3156 -+ int diff = 0; 23.3157 -+ 23.3158 -+ memset (&state_a, '\0', sizeof(mbstate_t)); 23.3159 -+ memset (&state_b, '\0', sizeof(mbstate_t)); 23.3160 -+ /* Ignore keys with start after end. */ 23.3161 -+ if (a->keybeg - a->keylim > 0) 23.3162 -+ return 0; 23.3163 -+ 23.3164 -+ 23.3165 -+ /* Ignore and/or translate chars before comparing. */ 23.3166 -+# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \ 23.3167 -+ do \ 23.3168 -+ { \ 23.3169 -+ wchar_t uwc; \ 23.3170 -+ char mbc[MB_LEN_MAX]; \ 23.3171 -+ mbstate_t state_wc; \ 23.3172 -+ \ 23.3173 -+ for (NEW_LEN = i = 0; i < LEN;) \ 23.3174 -+ { \ 23.3175 -+ mbstate_t state_bak; \ 23.3176 -+ \ 23.3177 -+ state_bak = STATE; \ 23.3178 -+ MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE); \ 23.3179 -+ \ 23.3180 -+ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1 \ 23.3181 -+ || MBLENGTH == 0) \ 23.3182 -+ { \ 23.3183 -+ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \ 23.3184 -+ STATE = state_bak; \ 23.3185 -+ if (!ignore) \ 23.3186 -+ COPY[NEW_LEN++] = TEXT[i]; \ 23.3187 -+ i++; \ 23.3188 -+ continue; \ 23.3189 -+ } \ 23.3190 -+ \ 23.3191 -+ if (ignore) \ 23.3192 -+ { \ 23.3193 -+ if ((ignore == nonprinting && !iswprint (WC)) \ 23.3194 -+ || (ignore == nondictionary \ 23.3195 -+ && !iswalnum (WC) && !iswblank (WC))) \ 23.3196 -+ { \ 23.3197 -+ i += MBLENGTH; \ 23.3198 -+ continue; \ 23.3199 -+ } \ 23.3200 -+ } \ 23.3201 -+ \ 23.3202 -+ if (translate) \ 23.3203 -+ { \ 23.3204 -+ \ 23.3205 -+ uwc = towupper(WC); \ 23.3206 -+ if (WC == uwc) \ 23.3207 -+ { \ 23.3208 -+ memcpy (mbc, TEXT + i, MBLENGTH); \ 23.3209 -+ i += MBLENGTH; \ 23.3210 -+ } \ 23.3211 -+ else \ 23.3212 -+ { \ 23.3213 -+ i += MBLENGTH; \ 23.3214 -+ WC = uwc; \ 23.3215 -+ memset (&state_wc, '\0', sizeof (mbstate_t)); \ 23.3216 -+ \ 23.3217 -+ MBLENGTH = wcrtomb (mbc, WC, &state_wc); \ 23.3218 -+ assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0); \ 23.3219 -+ } \ 23.3220 -+ \ 23.3221 -+ for (j = 0; j < MBLENGTH; j++) \ 23.3222 -+ COPY[NEW_LEN++] = mbc[j]; \ 23.3223 -+ } \ 23.3224 -+ else \ 23.3225 -+ for (j = 0; j < MBLENGTH; j++) \ 23.3226 -+ COPY[NEW_LEN++] = TEXT[i++]; \ 23.3227 -+ } \ 23.3228 -+ COPY[NEW_LEN] = '\0'; \ 23.3229 -+ } \ 23.3230 -+ while (0) 23.3231 -+ 23.3232 -+ /* Actually compare the fields. */ 23.3233 -+ 23.3234 -+ for (;;) 23.3235 -+ { 23.3236 -+ /* Find the lengths. */ 23.3237 -+ size_t lena = lima <= texta ? 0 : lima - texta; 23.3238 -+ size_t lenb = limb <= textb ? 0 : limb - textb; 23.3239 -+ 23.3240 -+ char enda IF_LINT (= 0); 23.3241 -+ char endb IF_LINT (= 0); 23.3242 -+ 23.3243 -+ char const *translate = key->translate; 23.3244 -+ bool const *ignore = key->ignore; 23.3245 -+ 23.3246 -+ if (ignore || translate) 23.3247 -+ { 23.3248 -+ if (SIZE_MAX - lenb - 2 < lena) 23.3249 -+ xalloc_die (); 23.3250 -+ char *copy_a = (char *) xnmalloc (lena + lenb + 2, MB_CUR_MAX); 23.3251 -+ char *copy_b = copy_a + lena * MB_CUR_MAX + 1; 23.3252 -+ size_t new_len_a, new_len_b; 23.3253 -+ size_t i, j; 23.3254 -+ 23.3255 -+ IGNORE_CHARS (new_len_a, lena, texta, copy_a, 23.3256 -+ wc_a, mblength_a, state_a); 23.3257 -+ IGNORE_CHARS (new_len_b, lenb, textb, copy_b, 23.3258 -+ wc_b, mblength_b, state_b); 23.3259 -+ texta = copy_a; textb = copy_b; 23.3260 -+ lena = new_len_a; lenb = new_len_b; 23.3261 -+ } 23.3262 -+ else 23.3263 -+ { 23.3264 -+ /* Use the keys in-place, temporarily null-terminated. */ 23.3265 -+ enda = texta[lena]; texta[lena] = '\0'; 23.3266 -+ endb = textb[lenb]; textb[lenb] = '\0'; 23.3267 -+ } 23.3268 -+ 23.3269 -+ if (key->random) 23.3270 -+ diff = compare_random (texta, lena, textb, lenb); 23.3271 -+ else if (key->numeric | key->general_numeric | key->human_numeric) 23.3272 -+ { 23.3273 -+ char savea = *lima, saveb = *limb; 23.3274 -+ 23.3275 -+ *lima = *limb = '\0'; 23.3276 -+ diff = (key->numeric ? numcompare (texta, textb) 23.3277 -+ : key->general_numeric ? general_numcompare (texta, textb) 23.3278 -+ : human_numcompare (texta, textb)); 23.3279 -+ *lima = savea, *limb = saveb; 23.3280 -+ } 23.3281 -+ else if (key->version) 23.3282 -+ diff = filevercmp (texta, textb); 23.3283 -+ else if (key->month) 23.3284 -+ diff = getmonth (texta, lena, NULL) - getmonth (textb, lenb, NULL); 23.3285 -+ else if (lena == 0) 23.3286 -+ diff = - NONZERO (lenb); 23.3287 -+ else if (lenb == 0) 23.3288 -+ diff = 1; 23.3289 -+ else if (hard_LC_COLLATE && !folding) 23.3290 -+ { 23.3291 -+ diff = xmemcoll0 (texta, lena + 1, textb, lenb + 1); 23.3292 -+ } 23.3293 -+ else 23.3294 -+ { 23.3295 -+ diff = memcmp (texta, textb, MIN (lena, lenb)); 23.3296 -+ if (diff == 0) 23.3297 -+ diff = lena < lenb ? -1 : lena != lenb; 23.3298 -+ } 23.3299 -+ 23.3300 -+ if (ignore || translate) 23.3301 -+ free (texta); 23.3302 -+ else 23.3303 -+ { 23.3304 -+ texta[lena] = enda; 23.3305 -+ textb[lenb] = endb; 23.3306 -+ } 23.3307 -+ 23.3308 -+ if (diff) 23.3309 -+ goto not_equal; 23.3310 -+ 23.3311 -+ key = key->next; 23.3312 -+ if (! key) 23.3313 -+ break; 23.3314 -+ 23.3315 -+ /* Find the beginning and limit of the next field. */ 23.3316 -+ if (key->eword != -1) 23.3317 -+ lima = limfield (a, key), limb = limfield (b, key); 23.3318 -+ else 23.3319 -+ lima = a->text + a->length - 1, limb = b->text + b->length - 1; 23.3320 -+ 23.3321 -+ if (key->sword != -1) 23.3322 -+ texta = begfield (a, key), textb = begfield (b, key); 23.3323 -+ else 23.3324 -+ { 23.3325 -+ texta = a->text, textb = b->text; 23.3326 -+ if (key->skipsblanks) 23.3327 -+ { 23.3328 -+ while (texta < lima && ismbblank (texta, lima - texta, &mblength_a)) 23.3329 -+ texta += mblength_a; 23.3330 -+ while (textb < limb && ismbblank (textb, limb - textb, &mblength_b)) 23.3331 -+ textb += mblength_b; 23.3332 -+ } 23.3333 -+ } 23.3334 -+ } 23.3335 -+ 23.3336 -+not_equal: 23.3337 -+ if (key && key->reverse) 23.3338 -+ return -diff; 23.3339 -+ else 23.3340 -+ return diff; 23.3341 -+} 23.3342 -+#endif 23.3343 -+ 23.3344 - /* Compare two lines A and B, returning negative, zero, or positive 23.3345 - depending on whether A compares less than, equal to, or greater than B. */ 23.3346 - 23.3347 -@@ -2722,7 +3367,7 @@ compare (struct line const *a, struct li 23.3348 - diff = - NONZERO (blen); 23.3349 - else if (blen == 0) 23.3350 - diff = 1; 23.3351 -- else if (hard_LC_COLLATE) 23.3352 -+ else if (hard_LC_COLLATE && !folding) 23.3353 - { 23.3354 - /* Note xmemcoll0 is a performance enhancement as 23.3355 - it will not unconditionally write '\0' after the 23.3356 -@@ -4121,6 +4766,7 @@ set_ordering (char const *s, struct keyf 23.3357 - break; 23.3358 - case 'f': 23.3359 - key->translate = fold_toupper; 23.3360 -+ folding = true; 23.3361 - break; 23.3362 - case 'g': 23.3363 - key->general_numeric = true; 23.3364 -@@ -4199,7 +4845,7 @@ main (int argc, char **argv) 23.3365 - initialize_exit_failure (SORT_FAILURE); 23.3366 - 23.3367 - hard_LC_COLLATE = hard_locale (LC_COLLATE); 23.3368 --#if HAVE_NL_LANGINFO 23.3369 -+#if HAVE_LANGINFO_CODESET 23.3370 - hard_LC_TIME = hard_locale (LC_TIME); 23.3371 - #endif 23.3372 - 23.3373 -@@ -4220,6 +4866,29 @@ main (int argc, char **argv) 23.3374 - thousands_sep = -1; 23.3375 - } 23.3376 - 23.3377 -+#if HAVE_MBRTOWC 23.3378 -+ if (MB_CUR_MAX > 1) 23.3379 -+ { 23.3380 -+ inittables = inittables_mb; 23.3381 -+ begfield = begfield_mb; 23.3382 -+ limfield = limfield_mb; 23.3383 -+ skipblanks = skipblanks_mb; 23.3384 -+ getmonth = getmonth_mb; 23.3385 -+ keycompare = keycompare_mb; 23.3386 -+ numcompare = numcompare_mb; 23.3387 -+ } 23.3388 -+ else 23.3389 -+#endif 23.3390 -+ { 23.3391 -+ inittables = inittables_uni; 23.3392 -+ begfield = begfield_uni; 23.3393 -+ limfield = limfield_uni; 23.3394 -+ skipblanks = skipblanks_uni; 23.3395 -+ getmonth = getmonth_uni; 23.3396 -+ keycompare = keycompare_uni; 23.3397 -+ numcompare = numcompare_uni; 23.3398 -+ } 23.3399 -+ 23.3400 - have_read_stdin = false; 23.3401 - inittables (); 23.3402 - 23.3403 -@@ -4494,13 +5163,34 @@ main (int argc, char **argv) 23.3404 - 23.3405 - case 't': 23.3406 - { 23.3407 -- char newtab = optarg[0]; 23.3408 -- if (! newtab) 23.3409 -+ char newtab[MB_LEN_MAX + 1]; 23.3410 -+ size_t newtab_length = 1; 23.3411 -+ strncpy (newtab, optarg, MB_LEN_MAX); 23.3412 -+ if (! newtab[0]) 23.3413 - error (SORT_FAILURE, 0, _("empty tab")); 23.3414 -- if (optarg[1]) 23.3415 -+#if HAVE_MBRTOWC 23.3416 -+ if (MB_CUR_MAX > 1) 23.3417 -+ { 23.3418 -+ wchar_t wc; 23.3419 -+ mbstate_t state; 23.3420 -+ 23.3421 -+ memset (&state, '\0', sizeof (mbstate_t)); 23.3422 -+ newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, 23.3423 -+ MB_LEN_MAX), 23.3424 -+ &state); 23.3425 -+ switch (newtab_length) 23.3426 -+ { 23.3427 -+ case (size_t) -1: 23.3428 -+ case (size_t) -2: 23.3429 -+ case 0: 23.3430 -+ newtab_length = 1; 23.3431 -+ } 23.3432 -+ } 23.3433 -+#endif 23.3434 -+ if (newtab_length == 1 && optarg[1]) 23.3435 - { 23.3436 - if (STREQ (optarg, "\\0")) 23.3437 -- newtab = '\0'; 23.3438 -+ newtab[0] = '\0'; 23.3439 - else 23.3440 - { 23.3441 - /* Provoke with 'sort -txx'. Complain about 23.3442 -@@ -4511,9 +5201,12 @@ main (int argc, char **argv) 23.3443 - quote (optarg)); 23.3444 - } 23.3445 - } 23.3446 -- if (tab != TAB_DEFAULT && tab != newtab) 23.3447 -+ if (tab_length 23.3448 -+ && (tab_length != newtab_length 23.3449 -+ || memcmp (tab, newtab, tab_length) != 0)) 23.3450 - error (SORT_FAILURE, 0, _("incompatible tabs")); 23.3451 -- tab = newtab; 23.3452 -+ memcpy (tab, newtab, newtab_length); 23.3453 -+ tab_length = newtab_length; 23.3454 - } 23.3455 - break; 23.3456 - 23.3457 -@@ -4751,12 +5444,10 @@ main (int argc, char **argv) 23.3458 - sort (files, nfiles, outfile, nthreads); 23.3459 - } 23.3460 - 23.3461 --#ifdef lint 23.3462 - if (files_from) 23.3463 - readtokens0_free (&tok); 23.3464 - else 23.3465 - free (files); 23.3466 --#endif 23.3467 - 23.3468 - if (have_read_stdin && fclose (stdin) == EOF) 23.3469 - die (_("close failed"), "-"); 23.3470 -diff -Naurp coreutils-8.25-orig/src/unexpand.c coreutils-8.25/src/unexpand.c 23.3471 ---- coreutils-8.25-orig/src/unexpand.c 2016-01-01 07:48:50.000000000 -0600 23.3472 -+++ coreutils-8.25/src/unexpand.c 2016-02-08 19:07:10.311944651 -0600 23.3473 -@@ -38,12 +38,29 @@ 23.3474 - #include <stdio.h> 23.3475 - #include <getopt.h> 23.3476 - #include <sys/types.h> 23.3477 -+ 23.3478 -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ 23.3479 -+#if HAVE_WCHAR_H 23.3480 -+# include <wchar.h> 23.3481 -+#endif 23.3482 -+ 23.3483 - #include "system.h" 23.3484 - #include "error.h" 23.3485 - #include "fadvise.h" 23.3486 - #include "quote.h" 23.3487 - #include "xstrndup.h" 23.3488 - 23.3489 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 23.3490 -+ installation; work around this configuration error. */ 23.3491 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 23.3492 -+# define MB_LEN_MAX 16 23.3493 -+#endif 23.3494 -+ 23.3495 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 23.3496 -+#if HAVE_MBRTOWC && defined mbstate_t 23.3497 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 23.3498 -+#endif 23.3499 -+ 23.3500 - /* The official name of this program (e.g., no 'g' prefix). */ 23.3501 - #define PROGRAM_NAME "unexpand" 23.3502 - 23.3503 -@@ -103,6 +120,210 @@ static struct option const longopts[] = 23.3504 - {NULL, 0, NULL, 0} 23.3505 - }; 23.3506 - 23.3507 -+static FILE *next_file (FILE *fp); 23.3508 -+ 23.3509 -+#if HAVE_MBRTOWC 23.3510 -+static void 23.3511 -+unexpand_multibyte (void) 23.3512 -+{ 23.3513 -+ FILE *fp; /* Input stream. */ 23.3514 -+ mbstate_t i_state; /* Current shift state of the input stream. */ 23.3515 -+ mbstate_t i_state_bak; /* Back up the I_STATE. */ 23.3516 -+ mbstate_t o_state; /* Current shift state of the output stream. */ 23.3517 -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 23.3518 -+ char *bufpos = buf; /* Next read position of BUF. */ 23.3519 -+ size_t buflen = 0; /* The length of the byte sequence in buf. */ 23.3520 -+ wint_t wc; /* A gotten wide character. */ 23.3521 -+ size_t mblength; /* The byte size of a multibyte character 23.3522 -+ which shows as same character as WC. */ 23.3523 -+ bool prev_tab = false; 23.3524 -+ 23.3525 -+ /* Index in `tab_list' of next tabstop: */ 23.3526 -+ int tab_index = 0; /* For calculating width of pending tabs. */ 23.3527 -+ int print_tab_index = 0; /* For printing as many tabs as possible. */ 23.3528 -+ unsigned int column = 0; /* Column on screen of next char. */ 23.3529 -+ int next_tab_column; /* Column the next tab stop is on. */ 23.3530 -+ int convert = 1; /* If nonzero, perform translations. */ 23.3531 -+ unsigned int pending = 0; /* Pending columns of blanks. */ 23.3532 -+ 23.3533 -+ fp = next_file ((FILE *) NULL); 23.3534 -+ if (fp == NULL) 23.3535 -+ return; 23.3536 -+ 23.3537 -+ memset (&o_state, '\0', sizeof(mbstate_t)); 23.3538 -+ memset (&i_state, '\0', sizeof(mbstate_t)); 23.3539 -+ 23.3540 -+ for (;;) 23.3541 -+ { 23.3542 -+ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) 23.3543 -+ { 23.3544 -+ memmove (buf, bufpos, buflen); 23.3545 -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); 23.3546 -+ bufpos = buf; 23.3547 -+ } 23.3548 -+ 23.3549 -+ /* Get a wide character. */ 23.3550 -+ if (buflen < 1) 23.3551 -+ { 23.3552 -+ mblength = 1; 23.3553 -+ wc = WEOF; 23.3554 -+ } 23.3555 -+ else 23.3556 -+ { 23.3557 -+ i_state_bak = i_state; 23.3558 -+ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &i_state); 23.3559 -+ } 23.3560 -+ 23.3561 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 23.3562 -+ { 23.3563 -+ i_state = i_state_bak; 23.3564 -+ wc = L'\0'; 23.3565 -+ } 23.3566 -+ 23.3567 -+ if (wc == L' ' && convert && column < INT_MAX) 23.3568 -+ { 23.3569 -+ ++pending; 23.3570 -+ ++column; 23.3571 -+ } 23.3572 -+ else if (wc == L'\t' && convert) 23.3573 -+ { 23.3574 -+ if (tab_size == 0) 23.3575 -+ { 23.3576 -+ /* Do not let tab_index == first_free_tab; 23.3577 -+ stop when it is 1 less. */ 23.3578 -+ while (tab_index < first_free_tab - 1 23.3579 -+ && column >= tab_list[tab_index]) 23.3580 -+ tab_index++; 23.3581 -+ next_tab_column = tab_list[tab_index]; 23.3582 -+ if (tab_index < first_free_tab - 1) 23.3583 -+ tab_index++; 23.3584 -+ if (column >= next_tab_column) 23.3585 -+ { 23.3586 -+ convert = 0; /* Ran out of tab stops. */ 23.3587 -+ goto flush_pend_mb; 23.3588 -+ } 23.3589 -+ } 23.3590 -+ else 23.3591 -+ { 23.3592 -+ next_tab_column = column + tab_size - column % tab_size; 23.3593 -+ } 23.3594 -+ pending += next_tab_column - column; 23.3595 -+ column = next_tab_column; 23.3596 -+ } 23.3597 -+ else 23.3598 -+ { 23.3599 -+flush_pend_mb: 23.3600 -+ /* Flush pending spaces. Print as many tabs as possible, 23.3601 -+ then print the rest as spaces. */ 23.3602 -+ if (pending == 1 && column != 1 && !prev_tab) 23.3603 -+ { 23.3604 -+ putchar (' '); 23.3605 -+ pending = 0; 23.3606 -+ } 23.3607 -+ column -= pending; 23.3608 -+ while (pending > 0) 23.3609 -+ { 23.3610 -+ if (tab_size == 0) 23.3611 -+ { 23.3612 -+ /* Do not let print_tab_index == first_free_tab; 23.3613 -+ stop when it is 1 less. */ 23.3614 -+ while (print_tab_index < first_free_tab - 1 23.3615 -+ && column >= tab_list[print_tab_index]) 23.3616 -+ print_tab_index++; 23.3617 -+ next_tab_column = tab_list[print_tab_index]; 23.3618 -+ if (print_tab_index < first_free_tab - 1) 23.3619 -+ print_tab_index++; 23.3620 -+ } 23.3621 -+ else 23.3622 -+ { 23.3623 -+ next_tab_column = 23.3624 -+ column + tab_size - column % tab_size; 23.3625 -+ } 23.3626 -+ if (next_tab_column - column <= pending) 23.3627 -+ { 23.3628 -+ putchar ('\t'); 23.3629 -+ pending -= next_tab_column - column; 23.3630 -+ column = next_tab_column; 23.3631 -+ } 23.3632 -+ else 23.3633 -+ { 23.3634 -+ --print_tab_index; 23.3635 -+ column += pending; 23.3636 -+ while (pending != 0) 23.3637 -+ { 23.3638 -+ putchar (' '); 23.3639 -+ pending--; 23.3640 -+ } 23.3641 -+ } 23.3642 -+ } 23.3643 -+ 23.3644 -+ if (wc == WEOF) 23.3645 -+ { 23.3646 -+ fp = next_file (fp); 23.3647 -+ if (fp == NULL) 23.3648 -+ break; /* No more files. */ 23.3649 -+ else 23.3650 -+ { 23.3651 -+ memset (&i_state, '\0', sizeof(mbstate_t)); 23.3652 -+ continue; 23.3653 -+ } 23.3654 -+ } 23.3655 -+ 23.3656 -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) 23.3657 -+ { 23.3658 -+ if (convert) 23.3659 -+ { 23.3660 -+ ++column; 23.3661 -+ if (convert_entire_line == 0) 23.3662 -+ convert = 0; 23.3663 -+ } 23.3664 -+ mblength = 1; 23.3665 -+ putchar (buf[0]); 23.3666 -+ } 23.3667 -+ else if (mblength == 0) 23.3668 -+ { 23.3669 -+ if (convert && convert_entire_line == 0) 23.3670 -+ convert = 0; 23.3671 -+ mblength = 1; 23.3672 -+ putchar ('\0'); 23.3673 -+ } 23.3674 -+ else 23.3675 -+ { 23.3676 -+ if (convert) 23.3677 -+ { 23.3678 -+ if (wc == L'\b') 23.3679 -+ { 23.3680 -+ if (column > 0) 23.3681 -+ --column; 23.3682 -+ } 23.3683 -+ else 23.3684 -+ { 23.3685 -+ int width; /* The width of WC. */ 23.3686 -+ 23.3687 -+ width = wcwidth (wc); 23.3688 -+ column += (width > 0) ? width : 0; 23.3689 -+ if (convert_entire_line == 0) 23.3690 -+ convert = 0; 23.3691 -+ } 23.3692 -+ } 23.3693 -+ 23.3694 -+ if (wc == L'\n') 23.3695 -+ { 23.3696 -+ tab_index = print_tab_index = 0; 23.3697 -+ column = pending = 0; 23.3698 -+ convert = 1; 23.3699 -+ } 23.3700 -+ fwrite (bufpos, sizeof(char), mblength, stdout); 23.3701 -+ } 23.3702 -+ } 23.3703 -+ prev_tab = wc == L'\t'; 23.3704 -+ buflen -= mblength; 23.3705 -+ bufpos += mblength; 23.3706 -+ } 23.3707 -+} 23.3708 -+#endif 23.3709 -+ 23.3710 -+ 23.3711 - void 23.3712 - usage (int status) 23.3713 - { 23.3714 -@@ -523,7 +744,12 @@ main (int argc, char **argv) 23.3715 - 23.3716 - file_list = (optind < argc ? &argv[optind] : stdin_argv); 23.3717 - 23.3718 -- unexpand (); 23.3719 -+#if HAVE_MBRTOWC 23.3720 -+ if (MB_CUR_MAX > 1) 23.3721 -+ unexpand_multibyte (); 23.3722 -+ else 23.3723 -+#endif 23.3724 -+ unexpand (); 23.3725 - 23.3726 - if (have_read_stdin && fclose (stdin) != 0) 23.3727 - error (EXIT_FAILURE, errno, "-"); 23.3728 -diff -Naurp coreutils-8.25-orig/src/uniq.c coreutils-8.25/src/uniq.c 23.3729 ---- coreutils-8.25-orig/src/uniq.c 2016-01-13 05:08:59.000000000 -0600 23.3730 -+++ coreutils-8.25/src/uniq.c 2016-02-08 19:07:10.312944654 -0600 23.3731 -@@ -21,6 +21,17 @@ 23.3732 - #include <getopt.h> 23.3733 - #include <sys/types.h> 23.3734 - 23.3735 -+/* Get mbstate_t, mbrtowc(). */ 23.3736 -+#if HAVE_WCHAR_H 23.3737 -+# include <wchar.h> 23.3738 -+#endif 23.3739 -+ 23.3740 -+/* Get isw* functions. */ 23.3741 -+#if HAVE_WCTYPE_H 23.3742 -+# include <wctype.h> 23.3743 -+#endif 23.3744 -+#include <assert.h> 23.3745 -+ 23.3746 - #include "system.h" 23.3747 - #include "argmatch.h" 23.3748 - #include "linebuffer.h" 23.3749 -@@ -33,6 +44,18 @@ 23.3750 - #include "xstrtol.h" 23.3751 - #include "memcasecmp.h" 23.3752 - #include "quote.h" 23.3753 -+#include "xmemcoll.h" 23.3754 -+ 23.3755 -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 23.3756 -+ installation; work around this configuration error. */ 23.3757 -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 23.3758 -+# define MB_LEN_MAX 16 23.3759 -+#endif 23.3760 -+ 23.3761 -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 23.3762 -+#if HAVE_MBRTOWC && defined mbstate_t 23.3763 -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 23.3764 -+#endif 23.3765 - 23.3766 - /* The official name of this program (e.g., no 'g' prefix). */ 23.3767 - #define PROGRAM_NAME "uniq" 23.3768 -@@ -143,6 +166,10 @@ enum 23.3769 - GROUP_OPTION = CHAR_MAX + 1 23.3770 - }; 23.3771 - 23.3772 -+/* Function pointers. */ 23.3773 -+static char * 23.3774 -+(*find_field) (struct linebuffer *line); 23.3775 -+ 23.3776 - static struct option const longopts[] = 23.3777 - { 23.3778 - {"count", no_argument, NULL, 'c'}, 23.3779 -@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *m 23.3780 - return a pointer to the beginning of the line's field to be compared. */ 23.3781 - 23.3782 - static char * _GL_ATTRIBUTE_PURE 23.3783 --find_field (struct linebuffer const *line) 23.3784 -+find_field_uni (struct linebuffer *line) 23.3785 - { 23.3786 - size_t count; 23.3787 - char const *lp = line->buffer; 23.3788 -@@ -272,6 +299,83 @@ find_field (struct linebuffer const *lin 23.3789 - return line->buffer + i; 23.3790 - } 23.3791 - 23.3792 -+#if HAVE_MBRTOWC 23.3793 -+ 23.3794 -+# define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL) \ 23.3795 -+ do \ 23.3796 -+ { \ 23.3797 -+ mbstate_t state_bak; \ 23.3798 -+ \ 23.3799 -+ CONVFAIL = 0; \ 23.3800 -+ state_bak = *STATEP; \ 23.3801 -+ \ 23.3802 -+ MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP); \ 23.3803 -+ \ 23.3804 -+ switch (MBLENGTH) \ 23.3805 -+ { \ 23.3806 -+ case (size_t)-2: \ 23.3807 -+ case (size_t)-1: \ 23.3808 -+ *STATEP = state_bak; \ 23.3809 -+ CONVFAIL++; \ 23.3810 -+ /* Fall through */ \ 23.3811 -+ case 0: \ 23.3812 -+ MBLENGTH = 1; \ 23.3813 -+ } \ 23.3814 -+ } \ 23.3815 -+ while (0) 23.3816 -+ 23.3817 -+static char * 23.3818 -+find_field_multi (struct linebuffer *line) 23.3819 -+{ 23.3820 -+ size_t count; 23.3821 -+ char *lp = line->buffer; 23.3822 -+ size_t size = line->length - 1; 23.3823 -+ size_t pos; 23.3824 -+ size_t mblength; 23.3825 -+ wchar_t wc; 23.3826 -+ mbstate_t *statep; 23.3827 -+ int convfail = 0; 23.3828 -+ 23.3829 -+ pos = 0; 23.3830 -+ statep = &(line->state); 23.3831 -+ 23.3832 -+ /* skip fields. */ 23.3833 -+ for (count = 0; count < skip_fields && pos < size; count++) 23.3834 -+ { 23.3835 -+ while (pos < size) 23.3836 -+ { 23.3837 -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 23.3838 -+ 23.3839 -+ if (convfail || !(iswblank (wc) || wc == '\n')) 23.3840 -+ { 23.3841 -+ pos += mblength; 23.3842 -+ break; 23.3843 -+ } 23.3844 -+ pos += mblength; 23.3845 -+ } 23.3846 -+ 23.3847 -+ while (pos < size) 23.3848 -+ { 23.3849 -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 23.3850 -+ 23.3851 -+ if (!convfail && (iswblank (wc) || wc == '\n')) 23.3852 -+ break; 23.3853 -+ 23.3854 -+ pos += mblength; 23.3855 -+ } 23.3856 -+ } 23.3857 -+ 23.3858 -+ /* skip fields. */ 23.3859 -+ for (count = 0; count < skip_chars && pos < size; count++) 23.3860 -+ { 23.3861 -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 23.3862 -+ pos += mblength; 23.3863 -+ } 23.3864 -+ 23.3865 -+ return lp + pos; 23.3866 -+} 23.3867 -+#endif 23.3868 -+ 23.3869 - /* Return false if two strings OLD and NEW match, true if not. 23.3870 - OLD and NEW point not to the beginnings of the lines 23.3871 - but rather to the beginnings of the fields to compare. 23.3872 -@@ -280,6 +384,8 @@ find_field (struct linebuffer const *lin 23.3873 - static bool 23.3874 - different (char *old, char *new, size_t oldlen, size_t newlen) 23.3875 - { 23.3876 -+ char *copy_old, *copy_new; 23.3877 -+ 23.3878 - if (check_chars < oldlen) 23.3879 - oldlen = check_chars; 23.3880 - if (check_chars < newlen) 23.3881 -@@ -287,15 +393,104 @@ different (char *old, char *new, size_t 23.3882 - 23.3883 - if (ignore_case) 23.3884 - { 23.3885 -- /* FIXME: This should invoke strcoll somehow. */ 23.3886 -- return oldlen != newlen || memcasecmp (old, new, oldlen); 23.3887 -+ size_t i; 23.3888 -+ 23.3889 -+ copy_old = xmalloc (oldlen + 1); 23.3890 -+ copy_new = xmalloc (oldlen + 1); 23.3891 -+ 23.3892 -+ for (i = 0; i < oldlen; i++) 23.3893 -+ { 23.3894 -+ copy_old[i] = toupper (old[i]); 23.3895 -+ copy_new[i] = toupper (new[i]); 23.3896 -+ } 23.3897 -+ bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen); 23.3898 -+ free (copy_old); 23.3899 -+ free (copy_new); 23.3900 -+ return rc; 23.3901 - } 23.3902 -- else if (hard_LC_COLLATE) 23.3903 -- return xmemcoll (old, oldlen, new, newlen) != 0; 23.3904 - else 23.3905 -- return oldlen != newlen || memcmp (old, new, oldlen); 23.3906 -+ { 23.3907 -+ copy_old = (char *)old; 23.3908 -+ copy_new = (char *)new; 23.3909 -+ } 23.3910 -+ 23.3911 -+ return xmemcoll (copy_old, oldlen, copy_new, newlen); 23.3912 -+ 23.3913 - } 23.3914 - 23.3915 -+#if HAVE_MBRTOWC 23.3916 -+static int 23.3917 -+different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) 23.3918 -+{ 23.3919 -+ size_t i, j, chars; 23.3920 -+ const char *str[2]; 23.3921 -+ char *copy[2]; 23.3922 -+ size_t len[2]; 23.3923 -+ mbstate_t state[2]; 23.3924 -+ size_t mblength; 23.3925 -+ wchar_t wc, uwc; 23.3926 -+ mbstate_t state_bak; 23.3927 -+ 23.3928 -+ str[0] = old; 23.3929 -+ str[1] = new; 23.3930 -+ len[0] = oldlen; 23.3931 -+ len[1] = newlen; 23.3932 -+ state[0] = oldstate; 23.3933 -+ state[1] = newstate; 23.3934 -+ 23.3935 -+ for (i = 0; i < 2; i++) 23.3936 -+ { 23.3937 -+ copy[i] = xmalloc (len[i] + 1); 23.3938 -+ memset (copy[i], '\0', len[i] + 1); 23.3939 -+ 23.3940 -+ for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) 23.3941 -+ { 23.3942 -+ state_bak = state[i]; 23.3943 -+ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); 23.3944 -+ 23.3945 -+ switch (mblength) 23.3946 -+ { 23.3947 -+ case (size_t)-1: 23.3948 -+ case (size_t)-2: 23.3949 -+ state[i] = state_bak; 23.3950 -+ /* Fall through */ 23.3951 -+ case 0: 23.3952 -+ mblength = 1; 23.3953 -+ break; 23.3954 -+ 23.3955 -+ default: 23.3956 -+ if (ignore_case) 23.3957 -+ { 23.3958 -+ uwc = towupper (wc); 23.3959 -+ 23.3960 -+ if (uwc != wc) 23.3961 -+ { 23.3962 -+ mbstate_t state_wc; 23.3963 -+ size_t mblen; 23.3964 -+ 23.3965 -+ memset (&state_wc, '\0', sizeof(mbstate_t)); 23.3966 -+ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); 23.3967 -+ assert (mblen != (size_t)-1); 23.3968 -+ } 23.3969 -+ else 23.3970 -+ memcpy (copy[i] + j, str[i] + j, mblength); 23.3971 -+ } 23.3972 -+ else 23.3973 -+ memcpy (copy[i] + j, str[i] + j, mblength); 23.3974 -+ } 23.3975 -+ j += mblength; 23.3976 -+ } 23.3977 -+ copy[i][j] = '\0'; 23.3978 -+ len[i] = j; 23.3979 -+ } 23.3980 -+ int rc = xmemcoll (copy[0], len[0], copy[1], len[1]); 23.3981 -+ free (copy[0]); 23.3982 -+ free (copy[1]); 23.3983 -+ return rc; 23.3984 -+ 23.3985 -+} 23.3986 -+#endif 23.3987 -+ 23.3988 - /* Output the line in linebuffer LINE to standard output 23.3989 - provided that the switches say it should be output. 23.3990 - MATCH is true if the line matches the previous line. 23.3991 -@@ -359,19 +554,38 @@ check_file (const char *infile, const ch 23.3992 - char *prevfield IF_LINT ( = NULL); 23.3993 - size_t prevlen IF_LINT ( = 0); 23.3994 - bool first_group_printed = false; 23.3995 -+#if HAVE_MBRTOWC 23.3996 -+ mbstate_t prevstate; 23.3997 -+ 23.3998 -+ memset (&prevstate, '\0', sizeof (mbstate_t)); 23.3999 -+#endif 23.4000 - 23.4001 - while (!feof (stdin)) 23.4002 - { 23.4003 - char *thisfield; 23.4004 - size_t thislen; 23.4005 - bool new_group; 23.4006 -+#if HAVE_MBRTOWC 23.4007 -+ mbstate_t thisstate; 23.4008 -+#endif 23.4009 - 23.4010 - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) 23.4011 - break; 23.4012 - 23.4013 - thisfield = find_field (thisline); 23.4014 - thislen = thisline->length - 1 - (thisfield - thisline->buffer); 23.4015 -+#if HAVE_MBRTOWC 23.4016 -+ if (MB_CUR_MAX > 1) 23.4017 -+ { 23.4018 -+ thisstate = thisline->state; 23.4019 - 23.4020 -+ new_group = (prevline->length == 0 23.4021 -+ || different_multi (thisfield, prevfield, 23.4022 -+ thislen, prevlen, 23.4023 -+ thisstate, prevstate)); 23.4024 -+ } 23.4025 -+ else 23.4026 -+#endif 23.4027 - new_group = (prevline->length == 0 23.4028 - || different (thisfield, prevfield, thislen, prevlen)); 23.4029 - 23.4030 -@@ -389,6 +603,10 @@ check_file (const char *infile, const ch 23.4031 - SWAP_LINES (prevline, thisline); 23.4032 - prevfield = thisfield; 23.4033 - prevlen = thislen; 23.4034 -+#if HAVE_MBRTOWC 23.4035 -+ if (MB_CUR_MAX > 1) 23.4036 -+ prevstate = thisstate; 23.4037 -+#endif 23.4038 - first_group_printed = true; 23.4039 - } 23.4040 - } 23.4041 -@@ -401,17 +619,26 @@ check_file (const char *infile, const ch 23.4042 - size_t prevlen; 23.4043 - uintmax_t match_count = 0; 23.4044 - bool first_delimiter = true; 23.4045 -+#if HAVE_MBRTOWC 23.4046 -+ mbstate_t prevstate; 23.4047 -+#endif 23.4048 - 23.4049 - if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) 23.4050 - goto closefiles; 23.4051 - prevfield = find_field (prevline); 23.4052 - prevlen = prevline->length - 1 - (prevfield - prevline->buffer); 23.4053 -+#if HAVE_MBRTOWC 23.4054 -+ prevstate = prevline->state; 23.4055 -+#endif 23.4056 - 23.4057 - while (!feof (stdin)) 23.4058 - { 23.4059 - bool match; 23.4060 - char *thisfield; 23.4061 - size_t thislen; 23.4062 -+#if HAVE_MBRTOWC 23.4063 -+ mbstate_t thisstate = thisline->state; 23.4064 -+#endif 23.4065 - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) 23.4066 - { 23.4067 - if (ferror (stdin)) 23.4068 -@@ -420,6 +647,14 @@ check_file (const char *infile, const ch 23.4069 - } 23.4070 - thisfield = find_field (thisline); 23.4071 - thislen = thisline->length - 1 - (thisfield - thisline->buffer); 23.4072 -+#if HAVE_MBRTOWC 23.4073 -+ if (MB_CUR_MAX > 1) 23.4074 -+ { 23.4075 -+ match = !different_multi (thisfield, prevfield, 23.4076 -+ thislen, prevlen, thisstate, prevstate); 23.4077 -+ } 23.4078 -+ else 23.4079 -+#endif 23.4080 - match = !different (thisfield, prevfield, thislen, prevlen); 23.4081 - match_count += match; 23.4082 - 23.4083 -@@ -452,6 +687,9 @@ check_file (const char *infile, const ch 23.4084 - SWAP_LINES (prevline, thisline); 23.4085 - prevfield = thisfield; 23.4086 - prevlen = thislen; 23.4087 -+#if HAVE_MBRTOWC 23.4088 -+ prevstate = thisstate; 23.4089 -+#endif 23.4090 - if (!match) 23.4091 - match_count = 0; 23.4092 - } 23.4093 -@@ -498,6 +736,19 @@ main (int argc, char **argv) 23.4094 - 23.4095 - atexit (close_stdout); 23.4096 - 23.4097 -+#if HAVE_MBRTOWC 23.4098 -+ if (MB_CUR_MAX > 1) 23.4099 -+ { 23.4100 -+ find_field = find_field_multi; 23.4101 -+ } 23.4102 -+ else 23.4103 -+#endif 23.4104 -+ { 23.4105 -+ find_field = find_field_uni; 23.4106 -+ } 23.4107 -+ 23.4108 -+ 23.4109 -+ 23.4110 - skip_chars = 0; 23.4111 - skip_fields = 0; 23.4112 - check_chars = SIZE_MAX; 23.4113 -diff -Naurp coreutils-8.25-orig/tests/i18n/sort-month.sh coreutils-8.25/tests/i18n/sort-month.sh 23.4114 ---- coreutils-8.25-orig/tests/i18n/sort-month.sh 1969-12-31 18:00:00.000000000 -0600 23.4115 -+++ coreutils-8.25/tests/i18n/sort-month.sh 2016-02-08 19:07:10.312944654 -0600 23.4116 -@@ -0,0 +1,34 @@ 23.4117 -+#!/bin/sh 23.4118 -+# Verify sort -M multi-byte support. 23.4119 -+ 23.4120 -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 23.4121 -+print_ver_ sort 23.4122 -+require_valgrind_ 23.4123 -+ 23.4124 -+# Skip this test if some deallocations are 23.4125 -+# avoided at process end. 23.4126 -+grep '^#define lint 1' $CONFIG_HEADER > /dev/null || 23.4127 -+ skip_ 'Allocation checks only work reliably in "lint" mode' 23.4128 -+ 23.4129 -+export LC_ALL=en_US.UTF-8 23.4130 -+locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 23.4131 -+ || skip_ "No UTF-8 locale available" 23.4132 -+ 23.4133 -+# Note the use of ɑ here which expands to 23.4134 -+# a wider representation upon case conversion 23.4135 -+# which triggered an assertion in sort -M 23.4136 -+cat <<EOF > exp 23.4137 -+. 23.4138 -+ɑ 23.4139 -+EOF 23.4140 -+ 23.4141 -+ 23.4142 -+# check large mem leak with --month-sort 23.4143 -+# https://bugzilla.redhat.com/show_bug.cgi?id=1259942 23.4144 -+valgrind --leak-check=full \ 23.4145 -+ --error-exitcode=1 --errors-for-leak-kinds=definite \ 23.4146 -+ sort -M < exp > out || fail=1 23.4147 -+compare exp out || { fail=1; cat out; } 23.4148 -+ 23.4149 -+ 23.4150 -+Exit $fail 23.4151 -diff -Naurp coreutils-8.25-orig/tests/i18n/sort.sh coreutils-8.25/tests/i18n/sort.sh 23.4152 ---- coreutils-8.25-orig/tests/i18n/sort.sh 1969-12-31 18:00:00.000000000 -0600 23.4153 -+++ coreutils-8.25/tests/i18n/sort.sh 2016-02-08 19:07:10.312944654 -0600 23.4154 -@@ -0,0 +1,29 @@ 23.4155 -+#!/bin/sh 23.4156 -+# Verify sort's multi-byte support. 23.4157 -+ 23.4158 -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 23.4159 -+print_ver_ sort 23.4160 -+ 23.4161 -+export LC_ALL=en_US.UTF-8 23.4162 -+locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 23.4163 -+ || skip_ "No UTF-8 locale available" 23.4164 -+ 23.4165 -+# Enable heap consistency checkng on older systems 23.4166 -+export MALLOC_CHECK_=2 23.4167 -+ 23.4168 -+ 23.4169 -+# check buffer overflow issue due to 23.4170 -+# expanding multi-byte representation due to case conversion 23.4171 -+# https://bugzilla.suse.com/show_bug.cgi?id=928749 23.4172 -+cat <<EOF > exp 23.4173 -+. 23.4174 -+ɑ 23.4175 -+EOF 23.4176 -+cat <<EOF | sort -f > out || fail=1 23.4177 -+. 23.4178 -+ɑ 23.4179 -+EOF 23.4180 -+compare exp out || { fail=1; cat out; } 23.4181 -+ 23.4182 -+ 23.4183 -+Exit $fail 23.4184 -diff -Naurp coreutils-8.25-orig/tests/local.mk coreutils-8.25/tests/local.mk 23.4185 ---- coreutils-8.25-orig/tests/local.mk 2016-01-16 12:18:13.000000000 -0600 23.4186 -+++ coreutils-8.25/tests/local.mk 2016-02-08 19:07:10.313944658 -0600 23.4187 -@@ -344,6 +344,9 @@ all_tests = \ 23.4188 - tests/misc/sort-discrim.sh \ 23.4189 - tests/misc/sort-files0-from.pl \ 23.4190 - tests/misc/sort-float.sh \ 23.4191 -+ tests/misc/sort-mb-tests.sh \ 23.4192 -+ tests/i18n/sort.sh \ 23.4193 -+ tests/i18n/sort-month.sh \ 23.4194 - tests/misc/sort-merge.pl \ 23.4195 - tests/misc/sort-merge-fdlimit.sh \ 23.4196 - tests/misc/sort-month.sh \ 23.4197 -diff -Naurp coreutils-8.25-orig/tests/misc/cut.pl coreutils-8.25/tests/misc/cut.pl 23.4198 ---- coreutils-8.25-orig/tests/misc/cut.pl 2016-01-16 12:18:13.000000000 -0600 23.4199 -+++ coreutils-8.25/tests/misc/cut.pl 2016-02-08 19:07:10.314944661 -0600 23.4200 -@@ -23,9 +23,11 @@ use strict; 23.4201 - # Turn off localization of executable's output. 23.4202 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 23.4203 - 23.4204 --my $mb_locale = $ENV{LOCALE_FR_UTF8}; 23.4205 -+my $mb_locale; 23.4206 -+# uncommented enable multibyte paths 23.4207 -+$mb_locale = $ENV{LOCALE_FR_UTF8}; 23.4208 - ! defined $mb_locale || $mb_locale eq 'none' 23.4209 -- and $mb_locale = 'C'; 23.4210 -+ and $mb_locale = 'C'; 23.4211 - 23.4212 - my $prog = 'cut'; 23.4213 - my $try = "Try '$prog --help' for more information.\n"; 23.4214 -@@ -240,6 +242,7 @@ if ($mb_locale ne 'C') 23.4215 - my @new_t = @$t; 23.4216 - my $test_name = shift @new_t; 23.4217 - 23.4218 -+ next if ($test_name =~ "newline-[12][0-9]"); 23.4219 - push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 23.4220 - } 23.4221 - push @Tests, @new; 23.4222 -diff -Naurp coreutils-8.25-orig/tests/misc/expand.pl coreutils-8.25/tests/misc/expand.pl 23.4223 ---- coreutils-8.25-orig/tests/misc/expand.pl 2016-01-16 12:18:13.000000000 -0600 23.4224 -+++ coreutils-8.25/tests/misc/expand.pl 2016-02-08 19:07:10.314944661 -0600 23.4225 -@@ -23,6 +23,15 @@ use strict; 23.4226 - # Turn off localization of executable's output. 23.4227 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 23.4228 - 23.4229 -+#comment out next line to disable multibyte tests 23.4230 -+my $mb_locale = $ENV{LOCALE_FR_UTF8}; 23.4231 -+! defined $mb_locale || $mb_locale eq 'none' 23.4232 -+ and $mb_locale = 'C'; 23.4233 -+ 23.4234 -+my $prog = 'expand'; 23.4235 -+my $try = "Try \`$prog --help' for more information.\n"; 23.4236 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 23.4237 -+ 23.4238 - my @Tests = 23.4239 - ( 23.4240 - ['t1', '--tabs=3', {IN=>"a\tb"}, {OUT=>"a b"}], 23.4241 -@@ -31,6 +40,37 @@ my @Tests = 23.4242 - ['i2', '--tabs=3 -i', {IN=>" \ta\tb"}, {OUT=>" a\tb"}], 23.4243 - ); 23.4244 - 23.4245 -+if ($mb_locale ne 'C') 23.4246 -+ { 23.4247 -+ # Duplicate each test vector, appending "-mb" to the test name and 23.4248 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 23.4249 -+ # provide coverage for the distro-added multi-byte code paths. 23.4250 -+ my @new; 23.4251 -+ foreach my $t (@Tests) 23.4252 -+ { 23.4253 -+ my @new_t = @$t; 23.4254 -+ my $test_name = shift @new_t; 23.4255 -+ 23.4256 -+ # Depending on whether expand is multi-byte-patched, 23.4257 -+ # it emits different diagnostics: 23.4258 -+ # non-MB: invalid byte or field list 23.4259 -+ # MB: invalid byte, character or field list 23.4260 -+ # Adjust the expected error output accordingly. 23.4261 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 23.4262 -+ (@new_t)) 23.4263 -+ { 23.4264 -+ my $sub = {ERR_SUBST => 's/, character//'}; 23.4265 -+ push @new_t, $sub; 23.4266 -+ push @$t, $sub; 23.4267 -+ } 23.4268 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 23.4269 -+ } 23.4270 -+ push @Tests, @new; 23.4271 -+ } 23.4272 -+ 23.4273 -+ 23.4274 -+@Tests = triple_test \@Tests; 23.4275 -+ 23.4276 - my $save_temps = $ENV{DEBUG}; 23.4277 - my $verbose = $ENV{VERBOSE}; 23.4278 - 23.4279 -diff -Naurp coreutils-8.25-orig/tests/misc/fold.pl coreutils-8.25/tests/misc/fold.pl 23.4280 ---- coreutils-8.25-orig/tests/misc/fold.pl 2016-01-16 12:18:13.000000000 -0600 23.4281 -+++ coreutils-8.25/tests/misc/fold.pl 2016-02-08 19:07:10.314944661 -0600 23.4282 -@@ -20,9 +20,18 @@ use strict; 23.4283 - 23.4284 - (my $program_name = $0) =~ s|.*/||; 23.4285 - 23.4286 -+my $prog = 'fold'; 23.4287 -+my $try = "Try \`$prog --help' for more information.\n"; 23.4288 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 23.4289 -+ 23.4290 - # Turn off localization of executable's output. 23.4291 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 23.4292 - 23.4293 -+# uncommented to enable multibyte paths 23.4294 -+my $mb_locale = $ENV{LOCALE_FR_UTF8}; 23.4295 -+! defined $mb_locale || $mb_locale eq 'none' 23.4296 -+ and $mb_locale = 'C'; 23.4297 -+ 23.4298 - my @Tests = 23.4299 - ( 23.4300 - ['s1', '-w2 -s', {IN=>"a\t"}, {OUT=>"a\n\t"}], 23.4301 -@@ -31,9 +40,48 @@ my @Tests = 23.4302 - ['s4', '-w4 -s', {IN=>"abc ef\n"}, {OUT=>"abc \nef\n"}], 23.4303 - ); 23.4304 - 23.4305 -+# Add _POSIX2_VERSION=199209 to the environment of each test 23.4306 -+# that uses an old-style option like +1. 23.4307 -+if ($mb_locale ne 'C') 23.4308 -+ { 23.4309 -+ # Duplicate each test vector, appending "-mb" to the test name and 23.4310 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 23.4311 -+ # provide coverage for the distro-added multi-byte code paths. 23.4312 -+ my @new; 23.4313 -+ foreach my $t (@Tests) 23.4314 -+ { 23.4315 -+ my @new_t = @$t; 23.4316 -+ my $test_name = shift @new_t; 23.4317 -+ 23.4318 -+ # Depending on whether fold is multi-byte-patched, 23.4319 -+ # it emits different diagnostics: 23.4320 -+ # non-MB: invalid byte or field list 23.4321 -+ # MB: invalid byte, character or field list 23.4322 -+ # Adjust the expected error output accordingly. 23.4323 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 23.4324 -+ (@new_t)) 23.4325 -+ { 23.4326 -+ my $sub = {ERR_SUBST => 's/, character//'}; 23.4327 -+ push @new_t, $sub; 23.4328 -+ push @$t, $sub; 23.4329 -+ } 23.4330 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 23.4331 -+ } 23.4332 -+ push @Tests, @new; 23.4333 -+ } 23.4334 -+ 23.4335 -+@Tests = triple_test \@Tests; 23.4336 -+ 23.4337 -+# Remember that triple_test creates from each test with exactly one "IN" 23.4338 -+# file two more tests (.p and .r suffix on name) corresponding to reading 23.4339 -+# input from a file and from a pipe. The pipe-reading test would fail 23.4340 -+# due to a race condition about 1 in 20 times. 23.4341 -+# Remove the IN_PIPE version of the "output-is-input" test above. 23.4342 -+# The others aren't susceptible because they have three inputs each. 23.4343 -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 23.4344 -+ 23.4345 - my $save_temps = $ENV{DEBUG}; 23.4346 - my $verbose = $ENV{VERBOSE}; 23.4347 - 23.4348 --my $prog = 'fold'; 23.4349 - my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); 23.4350 - exit $fail; 23.4351 -diff -Naurp coreutils-8.25-orig/tests/misc/join.pl coreutils-8.25/tests/misc/join.pl 23.4352 ---- coreutils-8.25-orig/tests/misc/join.pl 2016-01-16 12:18:13.000000000 -0600 23.4353 -+++ coreutils-8.25/tests/misc/join.pl 2016-02-08 19:07:10.315944664 -0600 23.4354 -@@ -25,6 +25,15 @@ my $limits = getlimits (); 23.4355 - 23.4356 - my $prog = 'join'; 23.4357 - 23.4358 -+my $try = "Try \`$prog --help' for more information.\n"; 23.4359 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 23.4360 -+ 23.4361 -+my $mb_locale; 23.4362 -+#Comment out next line to disable multibyte tests 23.4363 -+$mb_locale = $ENV{LOCALE_FR_UTF8}; 23.4364 -+! defined $mb_locale || $mb_locale eq 'none' 23.4365 -+ and $mb_locale = 'C'; 23.4366 -+ 23.4367 - my $delim = chr 0247; 23.4368 - sub t_subst ($) 23.4369 - { 23.4370 -@@ -329,8 +338,49 @@ foreach my $t (@tv) 23.4371 - push @Tests, $new_ent; 23.4372 - } 23.4373 - 23.4374 -+# Add _POSIX2_VERSION=199209 to the environment of each test 23.4375 -+# that uses an old-style option like +1. 23.4376 -+if ($mb_locale ne 'C') 23.4377 -+ { 23.4378 -+ # Duplicate each test vector, appending "-mb" to the test name and 23.4379 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 23.4380 -+ # provide coverage for the distro-added multi-byte code paths. 23.4381 -+ my @new; 23.4382 -+ foreach my $t (@Tests) 23.4383 -+ { 23.4384 -+ my @new_t = @$t; 23.4385 -+ my $test_name = shift @new_t; 23.4386 -+ 23.4387 -+ # Depending on whether join is multi-byte-patched, 23.4388 -+ # it emits different diagnostics: 23.4389 -+ # non-MB: invalid byte or field list 23.4390 -+ # MB: invalid byte, character or field list 23.4391 -+ # Adjust the expected error output accordingly. 23.4392 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 23.4393 -+ (@new_t)) 23.4394 -+ { 23.4395 -+ my $sub = {ERR_SUBST => 's/, character//'}; 23.4396 -+ push @new_t, $sub; 23.4397 -+ push @$t, $sub; 23.4398 -+ } 23.4399 -+ #Adjust the output some error messages including test_name for mb 23.4400 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR}} 23.4401 -+ (@new_t)) 23.4402 -+ { 23.4403 -+ my $sub2 = {ERR_SUBST => "s/$test_name-mb/$test_name/"}; 23.4404 -+ push @new_t, $sub2; 23.4405 -+ push @$t, $sub2; 23.4406 -+ } 23.4407 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 23.4408 -+ } 23.4409 -+ push @Tests, @new; 23.4410 -+ } 23.4411 -+ 23.4412 - @Tests = triple_test \@Tests; 23.4413 - 23.4414 -+#skip invalid-j-mb test, it is failing because of the format 23.4415 -+@Tests = grep {$_->[0] ne 'invalid-j-mb'} @Tests; 23.4416 -+ 23.4417 - my $save_temps = $ENV{DEBUG}; 23.4418 - my $verbose = $ENV{VERBOSE}; 23.4419 - 23.4420 -diff -Naurp coreutils-8.25-orig/tests/misc/sort-mb-tests.sh coreutils-8.25/tests/misc/sort-mb-tests.sh 23.4421 ---- coreutils-8.25-orig/tests/misc/sort-mb-tests.sh 1969-12-31 18:00:00.000000000 -0600 23.4422 -+++ coreutils-8.25/tests/misc/sort-mb-tests.sh 2016-02-08 19:07:10.315944664 -0600 23.4423 -@@ -0,0 +1,45 @@ 23.4424 -+#!/bin/sh 23.4425 -+# Verify sort's multi-byte support. 23.4426 -+ 23.4427 -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 23.4428 -+print_ver_ sort 23.4429 -+ 23.4430 -+export LC_ALL=en_US.UTF-8 23.4431 -+locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 23.4432 -+ || skip_ "No UTF-8 locale available" 23.4433 -+ 23.4434 -+ 23.4435 -+cat <<EOF > exp 23.4436 -+Banana@5 23.4437 -+Apple@10 23.4438 -+Citrus@20 23.4439 -+Cherry@30 23.4440 -+EOF 23.4441 -+ 23.4442 -+cat <<EOF | sort -t @ -k2 -n > out || fail=1 23.4443 -+Apple@10 23.4444 -+Banana@5 23.4445 -+Citrus@20 23.4446 -+Cherry@30 23.4447 -+EOF 23.4448 -+ 23.4449 -+compare exp out || { fail=1; cat out; } 23.4450 -+ 23.4451 -+ 23.4452 -+cat <<EOF > exp 23.4453 -+Citrus@AA20@@5 23.4454 -+Cherry@AA30@@10 23.4455 -+Apple@AA10@@20 23.4456 -+Banana@AA5@@30 23.4457 -+EOF 23.4458 -+ 23.4459 -+cat <<EOF | sort -t @ -k4 -n > out || fail=1 23.4460 -+Apple@AA10@@20 23.4461 -+Banana@AA5@@30 23.4462 -+Citrus@AA20@@5 23.4463 -+Cherry@AA30@@10 23.4464 -+EOF 23.4465 -+ 23.4466 -+compare exp out || { fail=1; cat out; } 23.4467 -+ 23.4468 -+Exit $fail 23.4469 -diff -Naurp coreutils-8.25-orig/tests/misc/sort-merge.pl coreutils-8.25/tests/misc/sort-merge.pl 23.4470 ---- coreutils-8.25-orig/tests/misc/sort-merge.pl 2016-01-16 12:18:14.000000000 -0600 23.4471 -+++ coreutils-8.25/tests/misc/sort-merge.pl 2016-02-08 19:07:10.316944667 -0600 23.4472 -@@ -26,6 +26,15 @@ my $prog = 'sort'; 23.4473 - # Turn off localization of executable's output. 23.4474 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 23.4475 - 23.4476 -+my $mb_locale; 23.4477 -+# uncommented according to upstream commit enabling multibyte paths 23.4478 -+$mb_locale = $ENV{LOCALE_FR_UTF8}; 23.4479 -+! defined $mb_locale || $mb_locale eq 'none' 23.4480 -+ and $mb_locale = 'C'; 23.4481 -+ 23.4482 -+my $try = "Try \`$prog --help' for more information.\n"; 23.4483 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 23.4484 -+ 23.4485 - # three empty files and one that says 'foo' 23.4486 - my @inputs = (+(map{{IN=> {"empty$_"=> ''}}}1..3), {IN=> {foo=> "foo\n"}}); 23.4487 - 23.4488 -@@ -77,6 +86,39 @@ my @Tests = 23.4489 - {OUT=>$big_input}], 23.4490 - ); 23.4491 - 23.4492 -+# Add _POSIX2_VERSION=199209 to the environment of each test 23.4493 -+# that uses an old-style option like +1. 23.4494 -+if ($mb_locale ne 'C') 23.4495 -+ { 23.4496 -+ # Duplicate each test vector, appending "-mb" to the test name and 23.4497 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 23.4498 -+ # provide coverage for the distro-added multi-byte code paths. 23.4499 -+ my @new; 23.4500 -+ foreach my $t (@Tests) 23.4501 -+ { 23.4502 -+ my @new_t = @$t; 23.4503 -+ my $test_name = shift @new_t; 23.4504 -+ 23.4505 -+ # Depending on whether sort is multi-byte-patched, 23.4506 -+ # it emits different diagnostics: 23.4507 -+ # non-MB: invalid byte or field list 23.4508 -+ # MB: invalid byte, character or field list 23.4509 -+ # Adjust the expected error output accordingly. 23.4510 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 23.4511 -+ (@new_t)) 23.4512 -+ { 23.4513 -+ my $sub = {ERR_SUBST => 's/, character//'}; 23.4514 -+ push @new_t, $sub; 23.4515 -+ push @$t, $sub; 23.4516 -+ } 23.4517 -+ next if ($test_name =~ "nmerge-."); 23.4518 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 23.4519 -+ } 23.4520 -+ push @Tests, @new; 23.4521 -+ } 23.4522 -+ 23.4523 -+@Tests = triple_test \@Tests; 23.4524 -+ 23.4525 - my $save_temps = $ENV{DEBUG}; 23.4526 - my $verbose = $ENV{VERBOSE}; 23.4527 - 23.4528 -diff -Naurp coreutils-8.25-orig/tests/misc/sort.pl coreutils-8.25/tests/misc/sort.pl 23.4529 ---- coreutils-8.25-orig/tests/misc/sort.pl 2016-01-16 12:18:14.000000000 -0600 23.4530 -+++ coreutils-8.25/tests/misc/sort.pl 2016-02-08 19:07:10.316944667 -0600 23.4531 -@@ -24,10 +24,15 @@ my $prog = 'sort'; 23.4532 - # Turn off localization of executable's output. 23.4533 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 23.4534 - 23.4535 --my $mb_locale = $ENV{LOCALE_FR_UTF8}; 23.4536 -+my $mb_locale; 23.4537 -+#Comment out next line to disable multibyte tests 23.4538 -+$mb_locale = $ENV{LOCALE_FR_UTF8}; 23.4539 - ! defined $mb_locale || $mb_locale eq 'none' 23.4540 - and $mb_locale = 'C'; 23.4541 - 23.4542 -+my $try = "Try \`$prog --help' for more information.\n"; 23.4543 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 23.4544 -+ 23.4545 - # Since each test is run with a file name and with redirected stdin, 23.4546 - # the name in the diagnostic is either the file name or "-". 23.4547 - # Normalize each diagnostic to use '-'. 23.4548 -@@ -424,6 +429,38 @@ foreach my $t (@Tests) 23.4549 - } 23.4550 - } 23.4551 - 23.4552 -+if ($mb_locale ne 'C') 23.4553 -+ { 23.4554 -+ # Duplicate each test vector, appending "-mb" to the test name and 23.4555 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 23.4556 -+ # provide coverage for the distro-added multi-byte code paths. 23.4557 -+ my @new; 23.4558 -+ foreach my $t (@Tests) 23.4559 -+ { 23.4560 -+ my @new_t = @$t; 23.4561 -+ my $test_name = shift @new_t; 23.4562 -+ 23.4563 -+ # Depending on whether sort is multi-byte-patched, 23.4564 -+ # it emits different diagnostics: 23.4565 -+ # non-MB: invalid byte or field list 23.4566 -+ # MB: invalid byte, character or field list 23.4567 -+ # Adjust the expected error output accordingly. 23.4568 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 23.4569 -+ (@new_t)) 23.4570 -+ { 23.4571 -+ my $sub = {ERR_SUBST => 's/, character//'}; 23.4572 -+ push @new_t, $sub; 23.4573 -+ push @$t, $sub; 23.4574 -+ } 23.4575 -+ #disable several failing tests until investigation, disable all tests with envvars set 23.4576 -+ next if (grep {ref $_ eq 'HASH' && exists $_->{ENV}} (@new_t)); 23.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"); 23.4578 -+ next if ($test_name =~ "11[ab]"); # avoid FP: expected result differs to MB result due to collation rules. 23.4579 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 23.4580 -+ } 23.4581 -+ push @Tests, @new; 23.4582 -+ } 23.4583 -+ 23.4584 - @Tests = triple_test \@Tests; 23.4585 - 23.4586 - # Remember that triple_test creates from each test with exactly one "IN" 23.4587 -@@ -433,6 +470,7 @@ foreach my $t (@Tests) 23.4588 - # Remove the IN_PIPE version of the "output-is-input" test above. 23.4589 - # The others aren't susceptible because they have three inputs each. 23.4590 - @Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 23.4591 -+@Tests = grep {$_->[0] ne 'output-is-input-mb.p'} @Tests; 23.4592 - 23.4593 - my $save_temps = $ENV{DEBUG}; 23.4594 - my $verbose = $ENV{VERBOSE}; 23.4595 -diff -Naurp coreutils-8.25-orig/tests/misc/unexpand.pl coreutils-8.25/tests/misc/unexpand.pl 23.4596 ---- coreutils-8.25-orig/tests/misc/unexpand.pl 2016-01-16 12:18:14.000000000 -0600 23.4597 -+++ coreutils-8.25/tests/misc/unexpand.pl 2016-02-08 19:07:10.317944671 -0600 23.4598 -@@ -27,6 +27,14 @@ my $limits = getlimits (); 23.4599 - 23.4600 - my $prog = 'unexpand'; 23.4601 - 23.4602 -+# comment out next line to disable multibyte tests 23.4603 -+my $mb_locale = $ENV{LOCALE_FR_UTF8}; 23.4604 -+! defined $mb_locale || $mb_locale eq 'none' 23.4605 -+ and $mb_locale = 'C'; 23.4606 -+ 23.4607 -+my $try = "Try \`$prog --help' for more information.\n"; 23.4608 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 23.4609 -+ 23.4610 - my @Tests = 23.4611 - ( 23.4612 - ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], 23.4613 -@@ -92,6 +100,37 @@ my @Tests = 23.4614 - {EXIT => 1}, {ERR => "$prog: tab stop value is too large\n"}], 23.4615 - ); 23.4616 - 23.4617 -+if ($mb_locale ne 'C') 23.4618 -+ { 23.4619 -+ # Duplicate each test vector, appending "-mb" to the test name and 23.4620 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 23.4621 -+ # provide coverage for the distro-added multi-byte code paths. 23.4622 -+ my @new; 23.4623 -+ foreach my $t (@Tests) 23.4624 -+ { 23.4625 -+ my @new_t = @$t; 23.4626 -+ my $test_name = shift @new_t; 23.4627 -+ 23.4628 -+ # Depending on whether unexpand is multi-byte-patched, 23.4629 -+ # it emits different diagnostics: 23.4630 -+ # non-MB: invalid byte or field list 23.4631 -+ # MB: invalid byte, character or field list 23.4632 -+ # Adjust the expected error output accordingly. 23.4633 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 23.4634 -+ (@new_t)) 23.4635 -+ { 23.4636 -+ my $sub = {ERR_SUBST => 's/, character//'}; 23.4637 -+ push @new_t, $sub; 23.4638 -+ push @$t, $sub; 23.4639 -+ } 23.4640 -+ next if ($test_name =~ 'b-1'); 23.4641 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 23.4642 -+ } 23.4643 -+ push @Tests, @new; 23.4644 -+ } 23.4645 -+ 23.4646 -+@Tests = triple_test \@Tests; 23.4647 -+ 23.4648 - my $save_temps = $ENV{DEBUG}; 23.4649 - my $verbose = $ENV{VERBOSE}; 23.4650 - 23.4651 -diff -Naurp coreutils-8.25-orig/tests/misc/uniq.pl coreutils-8.25/tests/misc/uniq.pl 23.4652 ---- coreutils-8.25-orig/tests/misc/uniq.pl 2016-01-16 12:18:14.000000000 -0600 23.4653 -+++ coreutils-8.25/tests/misc/uniq.pl 2016-02-08 19:07:10.317944671 -0600 23.4654 -@@ -23,9 +23,17 @@ my $limits = getlimits (); 23.4655 - my $prog = 'uniq'; 23.4656 - my $try = "Try '$prog --help' for more information.\n"; 23.4657 - 23.4658 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 23.4659 -+ 23.4660 - # Turn off localization of executable's output. 23.4661 - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 23.4662 - 23.4663 -+my $mb_locale; 23.4664 -+#Comment out next line to disable multibyte tests 23.4665 -+$mb_locale = $ENV{LOCALE_FR_UTF8}; 23.4666 -+! defined $mb_locale || $mb_locale eq 'none' 23.4667 -+ and $mb_locale = 'C'; 23.4668 -+ 23.4669 - # When possible, create a "-z"-testing variant of each test. 23.4670 - sub add_z_variants($) 23.4671 - { 23.4672 -@@ -262,6 +270,53 @@ foreach my $t (@Tests) 23.4673 - and push @$t, {ENV=>'_POSIX2_VERSION=199209'}; 23.4674 - } 23.4675 - 23.4676 -+if ($mb_locale ne 'C') 23.4677 -+ { 23.4678 -+ # Duplicate each test vector, appending "-mb" to the test name and 23.4679 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 23.4680 -+ # provide coverage for the distro-added multi-byte code paths. 23.4681 -+ my @new; 23.4682 -+ foreach my $t (@Tests) 23.4683 -+ { 23.4684 -+ my @new_t = @$t; 23.4685 -+ my $test_name = shift @new_t; 23.4686 -+ 23.4687 -+ # Depending on whether uniq is multi-byte-patched, 23.4688 -+ # it emits different diagnostics: 23.4689 -+ # non-MB: invalid byte or field list 23.4690 -+ # MB: invalid byte, character or field list 23.4691 -+ # Adjust the expected error output accordingly. 23.4692 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 23.4693 -+ (@new_t)) 23.4694 -+ { 23.4695 -+ my $sub = {ERR_SUBST => 's/, character//'}; 23.4696 -+ push @new_t, $sub; 23.4697 -+ push @$t, $sub; 23.4698 -+ } 23.4699 -+ # In test #145, replace the each ‘...’ by '...'. 23.4700 -+ if ($test_name =~ "145") 23.4701 -+ { 23.4702 -+ my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"}; 23.4703 -+ push @new_t, $sub; 23.4704 -+ push @$t, $sub; 23.4705 -+ } 23.4706 -+ next if ( $test_name =~ "schar" 23.4707 -+ or $test_name =~ "^obs-plus" 23.4708 -+ or $test_name =~ "119"); 23.4709 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 23.4710 -+ } 23.4711 -+ push @Tests, @new; 23.4712 -+ } 23.4713 -+ 23.4714 -+# Remember that triple_test creates from each test with exactly one "IN" 23.4715 -+# file two more tests (.p and .r suffix on name) corresponding to reading 23.4716 -+# input from a file and from a pipe. The pipe-reading test would fail 23.4717 -+# due to a race condition about 1 in 20 times. 23.4718 -+# Remove the IN_PIPE version of the "output-is-input" test above. 23.4719 -+# The others aren't susceptible because they have three inputs each. 23.4720 -+ 23.4721 -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 23.4722 -+ 23.4723 - @Tests = add_z_variants \@Tests; 23.4724 - @Tests = triple_test \@Tests; 23.4725 - 23.4726 -diff -Naurp coreutils-8.25-orig/tests/pr/pr-tests.pl coreutils-8.25/tests/pr/pr-tests.pl 23.4727 ---- coreutils-8.25-orig/tests/pr/pr-tests.pl 2016-01-16 12:18:14.000000000 -0600 23.4728 -+++ coreutils-8.25/tests/pr/pr-tests.pl 2016-02-08 19:07:10.318944674 -0600 23.4729 -@@ -24,6 +24,15 @@ use strict; 23.4730 - my $prog = 'pr'; 23.4731 - my $normalize_strerror = "s/': .*/'/"; 23.4732 - 23.4733 -+my $mb_locale; 23.4734 -+#Uncomment the following line to enable multibyte tests 23.4735 -+$mb_locale = $ENV{LOCALE_FR_UTF8}; 23.4736 -+! defined $mb_locale || $mb_locale eq 'none' 23.4737 -+ and $mb_locale = 'C'; 23.4738 -+ 23.4739 -+my $try = "Try \`$prog --help' for more information.\n"; 23.4740 -+my $inval = "$prog: invalid byte, character or field list\n$try"; 23.4741 -+ 23.4742 - my @tv = ( 23.4743 - 23.4744 - # -b option is no longer an official option. But it's still working to 23.4745 -@@ -467,8 +476,48 @@ push @Tests, 23.4746 - {IN=>{3=>"x\ty\tz\n"}}, 23.4747 - {OUT=>join("\t", qw(a b c m n o x y z)) . "\n"} ]; 23.4748 - 23.4749 -+# Add _POSIX2_VERSION=199209 to the environment of each test 23.4750 -+# that uses an old-style option like +1. 23.4751 -+if ($mb_locale ne 'C') 23.4752 -+ { 23.4753 -+ # Duplicate each test vector, appending "-mb" to the test name and 23.4754 -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 23.4755 -+ # provide coverage for the distro-added multi-byte code paths. 23.4756 -+ my @new; 23.4757 -+ foreach my $t (@Tests) 23.4758 -+ { 23.4759 -+ my @new_t = @$t; 23.4760 -+ my $test_name = shift @new_t; 23.4761 -+ 23.4762 -+ # Depending on whether pr is multi-byte-patched, 23.4763 -+ # it emits different diagnostics: 23.4764 -+ # non-MB: invalid byte or field list 23.4765 -+ # MB: invalid byte, character or field list 23.4766 -+ # Adjust the expected error output accordingly. 23.4767 -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 23.4768 -+ (@new_t)) 23.4769 -+ { 23.4770 -+ my $sub = {ERR_SUBST => 's/, character//'}; 23.4771 -+ push @new_t, $sub; 23.4772 -+ push @$t, $sub; 23.4773 -+ } 23.4774 -+ #temporarily skip some failing tests 23.4775 -+ next if ($test_name =~ "col-0" or $test_name =~ "col-inval"); 23.4776 -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 23.4777 -+ } 23.4778 -+ push @Tests, @new; 23.4779 -+ } 23.4780 -+ 23.4781 - @Tests = triple_test \@Tests; 23.4782 - 23.4783 -+# Remember that triple_test creates from each test with exactly one "IN" 23.4784 -+# file two more tests (.p and .r suffix on name) corresponding to reading 23.4785 -+# input from a file and from a pipe. The pipe-reading test would fail 23.4786 -+# due to a race condition about 1 in 20 times. 23.4787 -+# Remove the IN_PIPE version of the "output-is-input" test above. 23.4788 -+# The others aren't susceptible because they have three inputs each. 23.4789 -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 23.4790 -+ 23.4791 - my $save_temps = $ENV{DEBUG}; 23.4792 - my $verbose = $ENV{VERBOSE}; 23.4793 -
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/coreutils/stuff/patches/coreutils-8.27-i18n-1.patch Wed Feb 21 19:48:17 2018 +0200 24.3 @@ -0,0 +1,5521 @@ 24.4 +Submitted by: DJ Lucas (dj_AT_linuxfromscratch_DOT_org) 24.5 +Date: 2017-03-12 24.6 +Initial Package Version: 8.27 24.7 +Upstream Status: Rejected 24.8 +Origin: Based on Fedora's i18n patches at 24.9 + http://pkgs.fedoraproject.org/cgit/rpms/coreutils.git/tree/ 24.10 +Description: Fixes i18n issues with various Coreutils programs 24.11 + 24.12 +diff -Naurp coreutils-8.27-orig/bootstrap.conf coreutils-8.27/bootstrap.conf 24.13 +--- coreutils-8.27-orig/bootstrap.conf 2017-03-07 23:34:06.000000000 -0600 24.14 ++++ coreutils-8.27/bootstrap.conf 2017-03-11 23:47:38.068058445 -0600 24.15 +@@ -152,6 +152,7 @@ gnulib_modules=" 24.16 + maintainer-makefile 24.17 + malloc-gnu 24.18 + manywarnings 24.19 ++ mbfile 24.20 + mbrlen 24.21 + mbrtowc 24.22 + mbsalign 24.23 +diff -Naurp coreutils-8.27-orig/configure.ac coreutils-8.27/configure.ac 24.24 +--- coreutils-8.27-orig/configure.ac 2017-02-26 08:52:29.000000000 -0600 24.25 ++++ coreutils-8.27/configure.ac 2017-03-11 23:47:38.068058445 -0600 24.26 +@@ -429,6 +429,8 @@ fi 24.27 + # I'm leaving it here for now. This whole thing needs to be modernized... 24.28 + gl_WINSIZE_IN_PTEM 24.29 + 24.30 ++gl_MBFILE 24.31 ++ 24.32 + gl_HEADER_TIOCGWINSZ_IN_TERMIOS_H 24.33 + 24.34 + if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ 24.35 +diff -Naurp coreutils-8.27-orig/lib/linebuffer.h coreutils-8.27/lib/linebuffer.h 24.36 +--- coreutils-8.27-orig/lib/linebuffer.h 2017-01-01 16:35:38.000000000 -0600 24.37 ++++ coreutils-8.27/lib/linebuffer.h 2017-03-11 23:47:13.089286391 -0600 24.38 +@@ -21,6 +21,11 @@ 24.39 + 24.40 + # include <stdio.h> 24.41 + 24.42 ++/* Get mbstate_t. */ 24.43 ++# if HAVE_WCHAR_H 24.44 ++# include <wchar.h> 24.45 ++# endif 24.46 ++ 24.47 + /* A 'struct linebuffer' holds a line of text. */ 24.48 + 24.49 + struct linebuffer 24.50 +@@ -28,6 +33,9 @@ struct linebuffer 24.51 + size_t size; /* Allocated. */ 24.52 + size_t length; /* Used. */ 24.53 + char *buffer; 24.54 ++# if HAVE_WCHAR_H 24.55 ++ mbstate_t state; 24.56 ++# endif 24.57 + }; 24.58 + 24.59 + /* Initialize linebuffer LINEBUFFER for use. */ 24.60 +diff -Naurp coreutils-8.27-orig/lib/mbfile.c coreutils-8.27/lib/mbfile.c 24.61 +--- coreutils-8.27-orig/lib/mbfile.c 1969-12-31 18:00:00.000000000 -0600 24.62 ++++ coreutils-8.27/lib/mbfile.c 2017-03-11 23:47:38.069058397 -0600 24.63 +@@ -0,0 +1,3 @@ 24.64 ++#include <config.h> 24.65 ++#define MBFILE_INLINE _GL_EXTERN_INLINE 24.66 ++#include "mbfile.h" 24.67 +diff -Naurp coreutils-8.27-orig/lib/mbfile.h coreutils-8.27/lib/mbfile.h 24.68 +--- coreutils-8.27-orig/lib/mbfile.h 1969-12-31 18:00:00.000000000 -0600 24.69 ++++ coreutils-8.27/lib/mbfile.h 2017-03-11 23:47:38.069058397 -0600 24.70 +@@ -0,0 +1,255 @@ 24.71 ++/* Multibyte character I/O: macros for multi-byte encodings. 24.72 ++ Copyright (C) 2001, 2005, 2009-2017 Free Software Foundation, Inc. 24.73 ++ 24.74 ++ This program is free software: you can redistribute it and/or modify 24.75 ++ it under the terms of the GNU General Public License as published by 24.76 ++ the Free Software Foundation; either version 3 of the License, or 24.77 ++ (at your option) any later version. 24.78 ++ 24.79 ++ This program is distributed in the hope that it will be useful, 24.80 ++ but WITHOUT ANY WARRANTY; without even the implied warranty of 24.81 ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24.82 ++ GNU General Public License for more details. 24.83 ++ 24.84 ++ You should have received a copy of the GNU General Public License 24.85 ++ along with this program. If not, see <http://www.gnu.org/licenses/>. */ 24.86 ++ 24.87 ++/* Written by Mitsuru Chinen <mchinen@yamato.ibm.com> 24.88 ++ and Bruno Haible <bruno@clisp.org>. */ 24.89 ++ 24.90 ++/* The macros in this file implement multi-byte character input from a 24.91 ++ stream. 24.92 ++ 24.93 ++ mb_file_t 24.94 ++ is the type for multibyte character input stream, usable for variable 24.95 ++ declarations. 24.96 ++ 24.97 ++ mbf_char_t 24.98 ++ is the type for multibyte character or EOF, usable for variable 24.99 ++ declarations. 24.100 ++ 24.101 ++ mbf_init (mbf, stream) 24.102 ++ initializes the MB_FILE for reading from stream. 24.103 ++ 24.104 ++ mbf_getc (mbc, mbf) 24.105 ++ reads the next multibyte character from mbf and stores it in mbc. 24.106 ++ 24.107 ++ mb_iseof (mbc) 24.108 ++ returns true if mbc represents the EOF value. 24.109 ++ 24.110 ++ Here are the function prototypes of the macros. 24.111 ++ 24.112 ++ extern void mbf_init (mb_file_t mbf, FILE *stream); 24.113 ++ extern void mbf_getc (mbf_char_t mbc, mb_file_t mbf); 24.114 ++ extern bool mb_iseof (const mbf_char_t mbc); 24.115 ++ */ 24.116 ++ 24.117 ++#ifndef _MBFILE_H 24.118 ++#define _MBFILE_H 1 24.119 ++ 24.120 ++#include <assert.h> 24.121 ++#include <stdbool.h> 24.122 ++#include <stdio.h> 24.123 ++#include <string.h> 24.124 ++ 24.125 ++/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before 24.126 ++ <wchar.h>. 24.127 ++ BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before 24.128 ++ <wchar.h>. */ 24.129 ++#include <stdio.h> 24.130 ++#include <time.h> 24.131 ++#include <wchar.h> 24.132 ++ 24.133 ++#include "mbchar.h" 24.134 ++ 24.135 ++#ifndef _GL_INLINE_HEADER_BEGIN 24.136 ++ #error "Please include config.h first." 24.137 ++#endif 24.138 ++_GL_INLINE_HEADER_BEGIN 24.139 ++#ifndef MBFILE_INLINE 24.140 ++# define MBFILE_INLINE _GL_INLINE 24.141 ++#endif 24.142 ++ 24.143 ++struct mbfile_multi { 24.144 ++ FILE *fp; 24.145 ++ bool eof_seen; 24.146 ++ bool have_pushback; 24.147 ++ mbstate_t state; 24.148 ++ unsigned int bufcount; 24.149 ++ char buf[MBCHAR_BUF_SIZE]; 24.150 ++ struct mbchar pushback; 24.151 ++}; 24.152 ++ 24.153 ++MBFILE_INLINE void 24.154 ++mbfile_multi_getc (struct mbchar *mbc, struct mbfile_multi *mbf) 24.155 ++{ 24.156 ++ size_t bytes; 24.157 ++ 24.158 ++ /* If EOF has already been seen, don't use getc. This matters if 24.159 ++ mbf->fp is connected to an interactive tty. */ 24.160 ++ if (mbf->eof_seen) 24.161 ++ goto eof; 24.162 ++ 24.163 ++ /* Return character pushed back, if there is one. */ 24.164 ++ if (mbf->have_pushback) 24.165 ++ { 24.166 ++ mb_copy (mbc, &mbf->pushback); 24.167 ++ mbf->have_pushback = false; 24.168 ++ return; 24.169 ++ } 24.170 ++ 24.171 ++ /* Before using mbrtowc, we need at least one byte. */ 24.172 ++ if (mbf->bufcount == 0) 24.173 ++ { 24.174 ++ int c = getc (mbf->fp); 24.175 ++ if (c == EOF) 24.176 ++ { 24.177 ++ mbf->eof_seen = true; 24.178 ++ goto eof; 24.179 ++ } 24.180 ++ mbf->buf[0] = (unsigned char) c; 24.181 ++ mbf->bufcount++; 24.182 ++ } 24.183 ++ 24.184 ++ /* Handle most ASCII characters quickly, without calling mbrtowc(). */ 24.185 ++ if (mbf->bufcount == 1 && mbsinit (&mbf->state) && is_basic (mbf->buf[0])) 24.186 ++ { 24.187 ++ /* These characters are part of the basic character set. ISO C 99 24.188 ++ guarantees that their wide character code is identical to their 24.189 ++ char code. */ 24.190 ++ mbc->wc = mbc->buf[0] = mbf->buf[0]; 24.191 ++ mbc->wc_valid = true; 24.192 ++ mbc->ptr = &mbc->buf[0]; 24.193 ++ mbc->bytes = 1; 24.194 ++ mbf->bufcount = 0; 24.195 ++ return; 24.196 ++ } 24.197 ++ 24.198 ++ /* Use mbrtowc on an increasing number of bytes. Read only as many bytes 24.199 ++ from mbf->fp as needed. This is needed to give reasonable interactive 24.200 ++ behaviour when mbf->fp is connected to an interactive tty. */ 24.201 ++ for (;;) 24.202 ++ { 24.203 ++ /* We don't know whether the 'mbrtowc' function updates the state when 24.204 ++ it returns -2, - this is the ISO C 99 and glibc-2.2 behaviour - or 24.205 ++ not - amended ANSI C, glibc-2.1 and Solaris 2.7 behaviour. We 24.206 ++ don't have an autoconf test for this, yet. 24.207 ++ The new behaviour would allow us to feed the bytes one by one into 24.208 ++ mbrtowc. But the old behaviour forces us to feed all bytes since 24.209 ++ the end of the last character into mbrtowc. Since we want to retry 24.210 ++ with more bytes when mbrtowc returns -2, we must backup the state 24.211 ++ before calling mbrtowc, because implementations with the new 24.212 ++ behaviour will clobber it. */ 24.213 ++ mbstate_t backup_state = mbf->state; 24.214 ++ 24.215 ++ bytes = mbrtowc (&mbc->wc, &mbf->buf[0], mbf->bufcount, &mbf->state); 24.216 ++ 24.217 ++ if (bytes == (size_t) -1) 24.218 ++ { 24.219 ++ /* An invalid multibyte sequence was encountered. */ 24.220 ++ /* Return a single byte. */ 24.221 ++ bytes = 1; 24.222 ++ mbc->wc_valid = false; 24.223 ++ break; 24.224 ++ } 24.225 ++ else if (bytes == (size_t) -2) 24.226 ++ { 24.227 ++ /* An incomplete multibyte character. */ 24.228 ++ mbf->state = backup_state; 24.229 ++ if (mbf->bufcount == MBCHAR_BUF_SIZE) 24.230 ++ { 24.231 ++ /* An overlong incomplete multibyte sequence was encountered. */ 24.232 ++ /* Return a single byte. */ 24.233 ++ bytes = 1; 24.234 ++ mbc->wc_valid = false; 24.235 ++ break; 24.236 ++ } 24.237 ++ else 24.238 ++ { 24.239 ++ /* Read one more byte and retry mbrtowc. */ 24.240 ++ int c = getc (mbf->fp); 24.241 ++ if (c == EOF) 24.242 ++ { 24.243 ++ /* An incomplete multibyte character at the end. */ 24.244 ++ mbf->eof_seen = true; 24.245 ++ bytes = mbf->bufcount; 24.246 ++ mbc->wc_valid = false; 24.247 ++ break; 24.248 ++ } 24.249 ++ mbf->buf[mbf->bufcount] = (unsigned char) c; 24.250 ++ mbf->bufcount++; 24.251 ++ } 24.252 ++ } 24.253 ++ else 24.254 ++ { 24.255 ++ if (bytes == 0) 24.256 ++ { 24.257 ++ /* A null wide character was encountered. */ 24.258 ++ bytes = 1; 24.259 ++ assert (mbf->buf[0] == '\0'); 24.260 ++ assert (mbc->wc == 0); 24.261 ++ } 24.262 ++ mbc->wc_valid = true; 24.263 ++ break; 24.264 ++ } 24.265 ++ } 24.266 ++ 24.267 ++ /* Return the multibyte sequence mbf->buf[0..bytes-1]. */ 24.268 ++ mbc->ptr = &mbc->buf[0]; 24.269 ++ memcpy (&mbc->buf[0], &mbf->buf[0], bytes); 24.270 ++ mbc->bytes = bytes; 24.271 ++ 24.272 ++ mbf->bufcount -= bytes; 24.273 ++ if (mbf->bufcount > 0) 24.274 ++ { 24.275 ++ /* It's not worth calling memmove() for so few bytes. */ 24.276 ++ unsigned int count = mbf->bufcount; 24.277 ++ char *p = &mbf->buf[0]; 24.278 ++ 24.279 ++ do 24.280 ++ { 24.281 ++ *p = *(p + bytes); 24.282 ++ p++; 24.283 ++ } 24.284 ++ while (--count > 0); 24.285 ++ } 24.286 ++ return; 24.287 ++ 24.288 ++eof: 24.289 ++ /* An mbchar_t with bytes == 0 is used to indicate EOF. */ 24.290 ++ mbc->ptr = NULL; 24.291 ++ mbc->bytes = 0; 24.292 ++ mbc->wc_valid = false; 24.293 ++ return; 24.294 ++} 24.295 ++ 24.296 ++MBFILE_INLINE void 24.297 ++mbfile_multi_ungetc (const struct mbchar *mbc, struct mbfile_multi *mbf) 24.298 ++{ 24.299 ++ mb_copy (&mbf->pushback, mbc); 24.300 ++ mbf->have_pushback = true; 24.301 ++} 24.302 ++ 24.303 ++typedef struct mbfile_multi mb_file_t; 24.304 ++ 24.305 ++typedef mbchar_t mbf_char_t; 24.306 ++ 24.307 ++#define mbf_init(mbf, stream) \ 24.308 ++ ((mbf).fp = (stream), \ 24.309 ++ (mbf).eof_seen = false, \ 24.310 ++ (mbf).have_pushback = false, \ 24.311 ++ memset (&(mbf).state, '\0', sizeof (mbstate_t)), \ 24.312 ++ (mbf).bufcount = 0) 24.313 ++ 24.314 ++#define mbf_getc(mbc, mbf) mbfile_multi_getc (&(mbc), &(mbf)) 24.315 ++ 24.316 ++#define mbf_ungetc(mbc, mbf) mbfile_multi_ungetc (&(mbc), &(mbf)) 24.317 ++ 24.318 ++#define mb_iseof(mbc) ((mbc).bytes == 0) 24.319 ++ 24.320 ++#ifndef _GL_INLINE_HEADER_BEGIN 24.321 ++ #error "Please include config.h first." 24.322 ++#endif 24.323 ++_GL_INLINE_HEADER_BEGIN 24.324 ++ 24.325 ++#endif /* _MBFILE_H */ 24.326 +diff -Naurp coreutils-8.27-orig/m4/mbfile.m4 coreutils-8.27/m4/mbfile.m4 24.327 +--- coreutils-8.27-orig/m4/mbfile.m4 1969-12-31 18:00:00.000000000 -0600 24.328 ++++ coreutils-8.27/m4/mbfile.m4 2017-03-11 23:47:38.070058349 -0600 24.329 +@@ -0,0 +1,14 @@ 24.330 ++# mbfile.m4 serial 7 24.331 ++dnl Copyright (C) 2005, 2008-2017 Free Software Foundation, Inc. 24.332 ++dnl This file is free software; the Free Software Foundation 24.333 ++dnl gives unlimited permission to copy and/or distribute it, 24.334 ++dnl with or without modifications, as long as this notice is preserved. 24.335 ++ 24.336 ++dnl autoconf tests required for use of mbfile.h 24.337 ++dnl From Bruno Haible. 24.338 ++ 24.339 ++AC_DEFUN([gl_MBFILE], 24.340 ++[ 24.341 ++ AC_REQUIRE([AC_TYPE_MBSTATE_T]) 24.342 ++ : 24.343 ++]) 24.344 +diff -Naurp coreutils-8.27-orig/src/cut.c coreutils-8.27/src/cut.c 24.345 +--- coreutils-8.27-orig/src/cut.c 2017-01-01 16:34:24.000000000 -0600 24.346 ++++ coreutils-8.27/src/cut.c 2017-03-11 23:47:59.526048471 -0600 24.347 +@@ -28,6 +28,11 @@ 24.348 + #include <assert.h> 24.349 + #include <getopt.h> 24.350 + #include <sys/types.h> 24.351 ++ 24.352 ++/* Get mbstate_t, mbrtowc(). */ 24.353 ++#if HAVE_WCHAR_H 24.354 ++# include <wchar.h> 24.355 ++#endif 24.356 + #include "system.h" 24.357 + 24.358 + #include "error.h" 24.359 +@@ -38,6 +43,18 @@ 24.360 + 24.361 + #include "set-fields.h" 24.362 + 24.363 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 24.364 ++ installation; work around this configuration error. */ 24.365 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 24.366 ++# undef MB_LEN_MAX 24.367 ++# define MB_LEN_MAX 16 24.368 ++#endif 24.369 ++ 24.370 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 24.371 ++#if HAVE_MBRTOWC && defined mbstate_t 24.372 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 24.373 ++#endif 24.374 ++ 24.375 + /* The official name of this program (e.g., no 'g' prefix). */ 24.376 + #define PROGRAM_NAME "cut" 24.377 + 24.378 +@@ -54,6 +71,52 @@ 24.379 + } \ 24.380 + while (0) 24.381 + 24.382 ++/* Refill the buffer BUF to get a multibyte character. */ 24.383 ++#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM) \ 24.384 ++ do \ 24.385 ++ { \ 24.386 ++ if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM)) \ 24.387 ++ { \ 24.388 ++ memmove (BUF, BUFPOS, BUFLEN); \ 24.389 ++ BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \ 24.390 ++ BUFPOS = BUF; \ 24.391 ++ } \ 24.392 ++ } \ 24.393 ++ while (0) 24.394 ++ 24.395 ++/* Get wide character on BUFPOS. BUFPOS is not included after that. 24.396 ++ If byte sequence is not valid as a character, CONVFAIL is true. Otherwise false. */ 24.397 ++#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ 24.398 ++ do \ 24.399 ++ { \ 24.400 ++ mbstate_t state_bak; \ 24.401 ++ \ 24.402 ++ if (BUFLEN < 1) \ 24.403 ++ { \ 24.404 ++ WC = WEOF; \ 24.405 ++ break; \ 24.406 ++ } \ 24.407 ++ \ 24.408 ++ /* Get a wide character. */ \ 24.409 ++ CONVFAIL = false; \ 24.410 ++ state_bak = STATE; \ 24.411 ++ MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \ 24.412 ++ \ 24.413 ++ switch (MBLENGTH) \ 24.414 ++ { \ 24.415 ++ case (size_t)-1: \ 24.416 ++ case (size_t)-2: \ 24.417 ++ CONVFAIL = true; \ 24.418 ++ STATE = state_bak; \ 24.419 ++ /* Fall througn. */ \ 24.420 ++ \ 24.421 ++ case 0: \ 24.422 ++ MBLENGTH = 1; \ 24.423 ++ break; \ 24.424 ++ } \ 24.425 ++ } \ 24.426 ++ while (0) 24.427 ++ 24.428 + 24.429 + /* Pointer inside RP. When checking if a byte or field is selected 24.430 + by a finite range, we check if it is between CURRENT_RP.LO 24.431 +@@ -61,6 +124,9 @@ 24.432 + CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ 24.433 + static struct field_range_pair *current_rp; 24.434 + 24.435 ++/* Length of the delimiter given as argument to -d. */ 24.436 ++size_t delimlen; 24.437 ++ 24.438 + /* This buffer is used to support the semantics of the -s option 24.439 + (or lack of same) when the specified field list includes (does 24.440 + not include) the first field. In both of those cases, the entire 24.441 +@@ -77,15 +143,25 @@ enum operating_mode 24.442 + { 24.443 + undefined_mode, 24.444 + 24.445 +- /* Output characters that are in the given bytes. */ 24.446 ++ /* Output bytes that are at the given positions. */ 24.447 + byte_mode, 24.448 + 24.449 ++ /* Output characters that are at the given positions. */ 24.450 ++ character_mode, 24.451 ++ 24.452 + /* Output the given delimiter-separated fields. */ 24.453 + field_mode 24.454 + }; 24.455 + 24.456 + static enum operating_mode operating_mode; 24.457 + 24.458 ++/* If nonzero, when in byte mode, don't split multibyte characters. */ 24.459 ++static int byte_mode_character_aware; 24.460 ++ 24.461 ++/* If nonzero, the function for single byte locale is work 24.462 ++ if this program runs on multibyte locale. */ 24.463 ++static int force_singlebyte_mode; 24.464 ++ 24.465 + /* If true do not output lines containing no delimiter characters. 24.466 + Otherwise, all such lines are printed. This option is valid only 24.467 + with field mode. */ 24.468 +@@ -97,6 +173,9 @@ static bool complement; 24.469 + 24.470 + /* The delimiter character for field mode. */ 24.471 + static unsigned char delim; 24.472 ++#if HAVE_WCHAR_H 24.473 ++static wchar_t wcdelim; 24.474 ++#endif 24.475 + 24.476 + /* The delimiter for each line/record. */ 24.477 + static unsigned char line_delim = '\n'; 24.478 +@@ -164,7 +243,7 @@ Print selected parts of lines from each 24.479 + -f, --fields=LIST select only these fields; also print any line\n\ 24.480 + that contains no delimiter character, unless\n\ 24.481 + the -s option is specified\n\ 24.482 +- -n (ignored)\n\ 24.483 ++ -n with -b: don't split multibyte characters\n\ 24.484 + "), stdout); 24.485 + fputs (_("\ 24.486 + --complement complement the set of selected bytes, characters\n\ 24.487 +@@ -280,6 +359,82 @@ cut_bytes (FILE *stream) 24.488 + } 24.489 + } 24.490 + 24.491 ++#if HAVE_MBRTOWC 24.492 ++/* This function is in use for the following case. 24.493 ++ 24.494 ++ 1. Read from the stream STREAM, printing to standard output any selected 24.495 ++ characters. 24.496 ++ 24.497 ++ 2. Read from stream STREAM, printing to standard output any selected bytes, 24.498 ++ without splitting multibyte characters. */ 24.499 ++ 24.500 ++static void 24.501 ++cut_characters_or_cut_bytes_no_split (FILE *stream) 24.502 ++{ 24.503 ++ size_t idx; /* number of bytes or characters in the line so far. */ 24.504 ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 24.505 ++ char *bufpos; /* Next read position of BUF. */ 24.506 ++ size_t buflen; /* The length of the byte sequence in buf. */ 24.507 ++ wint_t wc; /* A gotten wide character. */ 24.508 ++ size_t mblength; /* The byte size of a multibyte character which shows 24.509 ++ as same character as WC. */ 24.510 ++ mbstate_t state; /* State of the stream. */ 24.511 ++ bool convfail = false; /* true, when conversion failed. Otherwise false. */ 24.512 ++ /* Whether to begin printing delimiters between ranges for the current line. 24.513 ++ Set after we've begun printing data corresponding to the first range. */ 24.514 ++ bool print_delimiter = false; 24.515 ++ 24.516 ++ idx = 0; 24.517 ++ buflen = 0; 24.518 ++ bufpos = buf; 24.519 ++ memset (&state, '\0', sizeof(mbstate_t)); 24.520 ++ 24.521 ++ current_rp = frp; 24.522 ++ 24.523 ++ while (1) 24.524 ++ { 24.525 ++ REFILL_BUFFER (buf, bufpos, buflen, stream); 24.526 ++ 24.527 ++ GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); 24.528 ++ (void) convfail; /* ignore unused */ 24.529 ++ 24.530 ++ if (wc == WEOF) 24.531 ++ { 24.532 ++ if (idx > 0) 24.533 ++ putchar (line_delim); 24.534 ++ break; 24.535 ++ } 24.536 ++ else if (wc == line_delim) 24.537 ++ { 24.538 ++ putchar (line_delim); 24.539 ++ idx = 0; 24.540 ++ print_delimiter = false; 24.541 ++ current_rp = frp; 24.542 ++ } 24.543 ++ else 24.544 ++ { 24.545 ++ next_item (&idx); 24.546 ++ if (print_kth (idx)) 24.547 ++ { 24.548 ++ if (output_delimiter_specified) 24.549 ++ { 24.550 ++ if (print_delimiter && is_range_start_index (idx)) 24.551 ++ { 24.552 ++ fwrite (output_delimiter_string, sizeof (char), 24.553 ++ output_delimiter_length, stdout); 24.554 ++ } 24.555 ++ print_delimiter = true; 24.556 ++ } 24.557 ++ fwrite (bufpos, mblength, sizeof(char), stdout); 24.558 ++ } 24.559 ++ } 24.560 ++ 24.561 ++ buflen -= mblength; 24.562 ++ bufpos += mblength; 24.563 ++ } 24.564 ++} 24.565 ++#endif 24.566 ++ 24.567 + /* Read from stream STREAM, printing to standard output any selected fields. */ 24.568 + 24.569 + static void 24.570 +@@ -425,13 +580,211 @@ cut_fields (FILE *stream) 24.571 + } 24.572 + } 24.573 + 24.574 ++#if HAVE_MBRTOWC 24.575 ++static void 24.576 ++cut_fields_mb (FILE *stream) 24.577 ++{ 24.578 ++ int c; 24.579 ++ size_t field_idx; 24.580 ++ int found_any_selected_field; 24.581 ++ int buffer_first_field; 24.582 ++ int empty_input; 24.583 ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 24.584 ++ char *bufpos; /* Next read position of BUF. */ 24.585 ++ size_t buflen; /* The length of the byte sequence in buf. */ 24.586 ++ wint_t wc = 0; /* A gotten wide character. */ 24.587 ++ size_t mblength; /* The byte size of a multibyte character which shows 24.588 ++ as same character as WC. */ 24.589 ++ mbstate_t state; /* State of the stream. */ 24.590 ++ bool convfail = false; /* true, when conversion failed. Otherwise false. */ 24.591 ++ 24.592 ++ current_rp = frp; 24.593 ++ 24.594 ++ found_any_selected_field = 0; 24.595 ++ field_idx = 1; 24.596 ++ bufpos = buf; 24.597 ++ buflen = 0; 24.598 ++ memset (&state, '\0', sizeof(mbstate_t)); 24.599 ++ 24.600 ++ c = getc (stream); 24.601 ++ empty_input = (c == EOF); 24.602 ++ if (c != EOF) 24.603 ++ { 24.604 ++ ungetc (c, stream); 24.605 ++ wc = 0; 24.606 ++ } 24.607 ++ else 24.608 ++ wc = WEOF; 24.609 ++ 24.610 ++ /* To support the semantics of the -s flag, we may have to buffer 24.611 ++ all of the first field to determine whether it is `delimited.' 24.612 ++ But that is unnecessary if all non-delimited lines must be printed 24.613 ++ and the first field has been selected, or if non-delimited lines 24.614 ++ must be suppressed and the first field has *not* been selected. 24.615 ++ That is because a non-delimited line has exactly one field. */ 24.616 ++ buffer_first_field = (suppress_non_delimited ^ !print_kth (1)); 24.617 ++ 24.618 ++ while (1) 24.619 ++ { 24.620 ++ if (field_idx == 1 && buffer_first_field) 24.621 ++ { 24.622 ++ int len = 0; 24.623 ++ 24.624 ++ while (1) 24.625 ++ { 24.626 ++ REFILL_BUFFER (buf, bufpos, buflen, stream); 24.627 ++ 24.628 ++ GET_NEXT_WC_FROM_BUFFER 24.629 ++ (wc, bufpos, buflen, mblength, state, convfail); 24.630 ++ 24.631 ++ if (wc == WEOF) 24.632 ++ break; 24.633 ++ 24.634 ++ field_1_buffer = xrealloc (field_1_buffer, len + mblength); 24.635 ++ memcpy (field_1_buffer + len, bufpos, mblength); 24.636 ++ len += mblength; 24.637 ++ buflen -= mblength; 24.638 ++ bufpos += mblength; 24.639 ++ 24.640 ++ if (!convfail && (wc == line_delim || wc == wcdelim)) 24.641 ++ break; 24.642 ++ } 24.643 ++ 24.644 ++ if (len <= 0 && wc == WEOF) 24.645 ++ break; 24.646 ++ 24.647 ++ /* If the first field extends to the end of line (it is not 24.648 ++ delimited) and we are printing all non-delimited lines, 24.649 ++ print this one. */ 24.650 ++ if (convfail || (!convfail && wc != wcdelim)) 24.651 ++ { 24.652 ++ if (suppress_non_delimited) 24.653 ++ { 24.654 ++ /* Empty. */ 24.655 ++ } 24.656 ++ else 24.657 ++ { 24.658 ++ fwrite (field_1_buffer, sizeof (char), len, stdout); 24.659 ++ /* Make sure the output line is newline terminated. */ 24.660 ++ if (convfail || (!convfail && wc != line_delim)) 24.661 ++ putchar (line_delim); 24.662 ++ } 24.663 ++ continue; 24.664 ++ } 24.665 ++ 24.666 ++ if (print_kth (1)) 24.667 ++ { 24.668 ++ /* Print the field, but not the trailing delimiter. */ 24.669 ++ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); 24.670 ++ found_any_selected_field = 1; 24.671 ++ } 24.672 ++ next_item (&field_idx); 24.673 ++ } 24.674 ++ 24.675 ++ if (wc != WEOF) 24.676 ++ { 24.677 ++ if (print_kth (field_idx)) 24.678 ++ { 24.679 ++ if (found_any_selected_field) 24.680 ++ { 24.681 ++ fwrite (output_delimiter_string, sizeof (char), 24.682 ++ output_delimiter_length, stdout); 24.683 ++ } 24.684 ++ found_any_selected_field = 1; 24.685 ++ } 24.686 ++ 24.687 ++ while (1) 24.688 ++ { 24.689 ++ REFILL_BUFFER (buf, bufpos, buflen, stream); 24.690 ++ 24.691 ++ GET_NEXT_WC_FROM_BUFFER 24.692 ++ (wc, bufpos, buflen, mblength, state, convfail); 24.693 ++ 24.694 ++ if (wc == WEOF) 24.695 ++ break; 24.696 ++ else if (!convfail && (wc == wcdelim || wc == line_delim)) 24.697 ++ { 24.698 ++ buflen -= mblength; 24.699 ++ bufpos += mblength; 24.700 ++ break; 24.701 ++ } 24.702 ++ 24.703 ++ if (print_kth (field_idx)) 24.704 ++ fwrite (bufpos, mblength, sizeof(char), stdout); 24.705 ++ 24.706 ++ buflen -= mblength; 24.707 ++ bufpos += mblength; 24.708 ++ } 24.709 ++ } 24.710 ++ 24.711 ++ if ((!convfail || wc == line_delim) && buflen < 1) 24.712 ++ wc = WEOF; 24.713 ++ 24.714 ++ if (!convfail && wc == wcdelim) 24.715 ++ next_item (&field_idx); 24.716 ++ else if (wc == WEOF || (!convfail && wc == line_delim)) 24.717 ++ { 24.718 ++ if (found_any_selected_field 24.719 ++ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) 24.720 ++ putchar (line_delim); 24.721 ++ if (wc == WEOF) 24.722 ++ break; 24.723 ++ field_idx = 1; 24.724 ++ current_rp = frp; 24.725 ++ found_any_selected_field = 0; 24.726 ++ } 24.727 ++ } 24.728 ++} 24.729 ++#endif 24.730 ++ 24.731 + static void 24.732 + cut_stream (FILE *stream) 24.733 + { 24.734 +- if (operating_mode == byte_mode) 24.735 +- cut_bytes (stream); 24.736 ++#if HAVE_MBRTOWC 24.737 ++ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) 24.738 ++ { 24.739 ++ switch (operating_mode) 24.740 ++ { 24.741 ++ case byte_mode: 24.742 ++ if (byte_mode_character_aware) 24.743 ++ cut_characters_or_cut_bytes_no_split (stream); 24.744 ++ else 24.745 ++ cut_bytes (stream); 24.746 ++ break; 24.747 ++ 24.748 ++ case character_mode: 24.749 ++ cut_characters_or_cut_bytes_no_split (stream); 24.750 ++ break; 24.751 ++ 24.752 ++ case field_mode: 24.753 ++ if (delimlen == 1) 24.754 ++ { 24.755 ++ /* Check if we have utf8 multibyte locale, so we can use this 24.756 ++ optimization because of uniqueness of characters, which is 24.757 ++ not true for e.g. SJIS */ 24.758 ++ char * loc = setlocale(LC_CTYPE, NULL); 24.759 ++ if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") || 24.760 ++ strstr (loc, "UTF8") || strstr (loc, "utf8"))) 24.761 ++ { 24.762 ++ cut_fields (stream); 24.763 ++ break; 24.764 ++ } 24.765 ++ } 24.766 ++ cut_fields_mb (stream); 24.767 ++ break; 24.768 ++ 24.769 ++ default: 24.770 ++ abort (); 24.771 ++ } 24.772 ++ } 24.773 + else 24.774 +- cut_fields (stream); 24.775 ++#endif 24.776 ++ { 24.777 ++ if (operating_mode == field_mode) 24.778 ++ cut_fields (stream); 24.779 ++ else 24.780 ++ cut_bytes (stream); 24.781 ++ } 24.782 + } 24.783 + 24.784 + /* Process file FILE to standard output. 24.785 +@@ -483,6 +836,7 @@ main (int argc, char **argv) 24.786 + bool ok; 24.787 + bool delim_specified = false; 24.788 + char *spec_list_string IF_LINT ( = NULL); 24.789 ++ char mbdelim[MB_LEN_MAX + 1]; 24.790 + 24.791 + initialize_main (&argc, &argv); 24.792 + set_program_name (argv[0]); 24.793 +@@ -505,7 +859,6 @@ main (int argc, char **argv) 24.794 + switch (optc) 24.795 + { 24.796 + case 'b': 24.797 +- case 'c': 24.798 + /* Build the byte list. */ 24.799 + if (operating_mode != undefined_mode) 24.800 + FATAL_ERROR (_("only one type of list may be specified")); 24.801 +@@ -513,6 +866,14 @@ main (int argc, char **argv) 24.802 + spec_list_string = optarg; 24.803 + break; 24.804 + 24.805 ++ case 'c': 24.806 ++ /* Build the character list. */ 24.807 ++ if (operating_mode != undefined_mode) 24.808 ++ FATAL_ERROR (_("only one type of list may be specified")); 24.809 ++ operating_mode = character_mode; 24.810 ++ spec_list_string = optarg; 24.811 ++ break; 24.812 ++ 24.813 + case 'f': 24.814 + /* Build the field list. */ 24.815 + if (operating_mode != undefined_mode) 24.816 +@@ -524,10 +885,38 @@ main (int argc, char **argv) 24.817 + case 'd': 24.818 + /* New delimiter. */ 24.819 + /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ 24.820 +- if (optarg[0] != '\0' && optarg[1] != '\0') 24.821 +- FATAL_ERROR (_("the delimiter must be a single character")); 24.822 +- delim = optarg[0]; 24.823 +- delim_specified = true; 24.824 ++ { 24.825 ++#if HAVE_MBRTOWC 24.826 ++ if(MB_CUR_MAX > 1) 24.827 ++ { 24.828 ++ mbstate_t state; 24.829 ++ 24.830 ++ memset (&state, '\0', sizeof(mbstate_t)); 24.831 ++ delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state); 24.832 ++ 24.833 ++ if (delimlen == (size_t)-1 || delimlen == (size_t)-2) 24.834 ++ ++force_singlebyte_mode; 24.835 ++ else 24.836 ++ { 24.837 ++ delimlen = (delimlen < 1) ? 1 : delimlen; 24.838 ++ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') 24.839 ++ FATAL_ERROR (_("the delimiter must be a single character")); 24.840 ++ memcpy (mbdelim, optarg, delimlen); 24.841 ++ mbdelim[delimlen] = '\0'; 24.842 ++ if (delimlen == 1) 24.843 ++ delim = *optarg; 24.844 ++ } 24.845 ++ } 24.846 ++ 24.847 ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) 24.848 ++#endif 24.849 ++ { 24.850 ++ if (optarg[0] != '\0' && optarg[1] != '\0') 24.851 ++ FATAL_ERROR (_("the delimiter must be a single character")); 24.852 ++ delim = (unsigned char) optarg[0]; 24.853 ++ } 24.854 ++ delim_specified = true; 24.855 ++ } 24.856 + break; 24.857 + 24.858 + case OUTPUT_DELIMITER_OPTION: 24.859 +@@ -540,6 +929,7 @@ main (int argc, char **argv) 24.860 + break; 24.861 + 24.862 + case 'n': 24.863 ++ byte_mode_character_aware = 1; 24.864 + break; 24.865 + 24.866 + case 's': 24.867 +@@ -579,15 +969,34 @@ main (int argc, char **argv) 24.868 + | (complement ? SETFLD_COMPLEMENT : 0) ); 24.869 + 24.870 + if (!delim_specified) 24.871 +- delim = '\t'; 24.872 ++ { 24.873 ++ delim = '\t'; 24.874 ++#ifdef HAVE_MBRTOWC 24.875 ++ wcdelim = L'\t'; 24.876 ++ mbdelim[0] = '\t'; 24.877 ++ mbdelim[1] = '\0'; 24.878 ++ delimlen = 1; 24.879 ++#endif 24.880 ++ } 24.881 + 24.882 + if (output_delimiter_string == NULL) 24.883 + { 24.884 +- static char dummy[2]; 24.885 +- dummy[0] = delim; 24.886 +- dummy[1] = '\0'; 24.887 +- output_delimiter_string = dummy; 24.888 +- output_delimiter_length = 1; 24.889 ++#ifdef HAVE_MBRTOWC 24.890 ++ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) 24.891 ++ { 24.892 ++ output_delimiter_string = xstrdup(mbdelim); 24.893 ++ output_delimiter_length = delimlen; 24.894 ++ } 24.895 ++ 24.896 ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) 24.897 ++#endif 24.898 ++ { 24.899 ++ static char dummy[2]; 24.900 ++ dummy[0] = delim; 24.901 ++ dummy[1] = '\0'; 24.902 ++ output_delimiter_string = dummy; 24.903 ++ output_delimiter_length = 1; 24.904 ++ } 24.905 + } 24.906 + 24.907 + if (optind == argc) 24.908 +diff -Naurp coreutils-8.27-orig/src/expand.c coreutils-8.27/src/expand.c 24.909 +--- coreutils-8.27-orig/src/expand.c 2017-02-26 15:42:25.000000000 -0600 24.910 ++++ coreutils-8.27/src/expand.c 2017-03-11 23:49:06.758133530 -0600 24.911 +@@ -37,6 +37,9 @@ 24.912 + #include <stdio.h> 24.913 + #include <getopt.h> 24.914 + #include <sys/types.h> 24.915 ++ 24.916 ++#include <mbfile.h> 24.917 ++ 24.918 + #include "system.h" 24.919 + #include "die.h" 24.920 + #include "xstrndup.h" 24.921 +@@ -100,19 +103,41 @@ expand (void) 24.922 + { 24.923 + /* Input stream. */ 24.924 + FILE *fp = next_file (NULL); 24.925 ++ mb_file_t mbf; 24.926 ++ mbf_char_t c; 24.927 ++ /* True if the starting locale is utf8. */ 24.928 ++ bool using_utf_locale; 24.929 ++ 24.930 ++ /* True if the first file contains BOM header. */ 24.931 ++ bool found_bom; 24.932 ++ using_utf_locale=check_utf_locale(); 24.933 + 24.934 + if (!fp) 24.935 + return; 24.936 ++ mbf_init (mbf, fp); 24.937 ++ found_bom=check_bom(fp,&mbf); 24.938 + 24.939 +- while (true) 24.940 ++ if (using_utf_locale == false && found_bom == true) 24.941 ++ { 24.942 ++ /*try using some predefined locale */ 24.943 ++ 24.944 ++ if (set_utf_locale () != 0) 24.945 + { 24.946 +- /* Input character, or EOF. */ 24.947 +- int c; 24.948 ++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); 24.949 ++ } 24.950 ++ } 24.951 ++ 24.952 + 24.953 ++ if (found_bom == true) 24.954 ++ { 24.955 ++ print_bom(); 24.956 ++ } 24.957 ++ 24.958 ++ while (true) 24.959 ++ { 24.960 + /* If true, perform translations. */ 24.961 + bool convert = true; 24.962 + 24.963 +- 24.964 + /* The following variables have valid values only when CONVERT 24.965 + is true: */ 24.966 + 24.967 +@@ -122,17 +147,48 @@ expand (void) 24.968 + /* Index in TAB_LIST of next tab stop to examine. */ 24.969 + size_t tab_index = 0; 24.970 + 24.971 +- 24.972 + /* Convert a line of text. */ 24.973 + 24.974 + do 24.975 + { 24.976 +- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) 24.977 +- continue; 24.978 ++ while (true) { 24.979 ++ mbf_getc (c, mbf); 24.980 ++ if ((mb_iseof (c)) && (fp = next_file (fp))) 24.981 ++ { 24.982 ++ mbf_init (mbf, fp); 24.983 ++ if (fp!=NULL) 24.984 ++ { 24.985 ++ if (check_bom(fp,&mbf)==true) 24.986 ++ { 24.987 ++ /*Not the first file - check BOM header*/ 24.988 ++ if (using_utf_locale==false && found_bom==false) 24.989 ++ { 24.990 ++ /*BOM header in subsequent file but not in the first one. */ 24.991 ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); 24.992 ++ } 24.993 ++ } 24.994 ++ else 24.995 ++ { 24.996 ++ if(using_utf_locale==false && found_bom==true) 24.997 ++ { 24.998 ++ /*First file conatined BOM header - locale was switched to UTF 24.999 ++ /*all subsequent files should contain BOM. */ 24.1000 ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); 24.1001 ++ } 24.1002 ++ } 24.1003 ++ } 24.1004 ++ continue; 24.1005 ++ } 24.1006 ++ else 24.1007 ++ { 24.1008 ++ break; 24.1009 ++ } 24.1010 ++ } 24.1011 ++ 24.1012 + 24.1013 + if (convert) 24.1014 + { 24.1015 +- if (c == '\t') 24.1016 ++ if (mb_iseq (c, '\t')) 24.1017 + { 24.1018 + /* Column the next input tab stop is on. */ 24.1019 + uintmax_t next_tab_column; 24.1020 +@@ -151,32 +207,34 @@ expand (void) 24.1021 + if (putchar (' ') < 0) 24.1022 + die (EXIT_FAILURE, errno, _("write error")); 24.1023 + 24.1024 +- c = ' '; 24.1025 ++ mb_setascii (&c, ' '); 24.1026 + } 24.1027 +- else if (c == '\b') 24.1028 ++ else if (mb_iseq (c, '\b')) 24.1029 + { 24.1030 + /* Go back one column, and force recalculation of the 24.1031 + next tab stop. */ 24.1032 + column -= !!column; 24.1033 + tab_index -= !!tab_index; 24.1034 + } 24.1035 +- else 24.1036 ++ /* A leading control character could make us trip over. */ 24.1037 ++ else if (!mb_iscntrl (c)) 24.1038 + { 24.1039 +- column++; 24.1040 ++ column += mb_width (c); 24.1041 + if (!column) 24.1042 + die (EXIT_FAILURE, 0, _("input line is too long")); 24.1043 + } 24.1044 + 24.1045 +- convert &= convert_entire_line || !! isblank (c); 24.1046 ++ convert &= convert_entire_line || mb_isblank (c); 24.1047 + } 24.1048 + 24.1049 +- if (c < 0) 24.1050 ++ if (mb_iseof (c)) 24.1051 + return; 24.1052 + 24.1053 +- if (putchar (c) < 0) 24.1054 ++ mb_putc (c, stdout); 24.1055 ++ if (ferror (stdout)) 24.1056 + die (EXIT_FAILURE, errno, _("write error")); 24.1057 + } 24.1058 +- while (c != '\n'); 24.1059 ++ while (!mb_iseq (c, '\n')); 24.1060 + } 24.1061 + } 24.1062 + 24.1063 +diff -Naurp coreutils-8.27-orig/src/expand-common.c coreutils-8.27/src/expand-common.c 24.1064 +--- coreutils-8.27-orig/src/expand-common.c 2017-03-01 11:22:55.000000000 -0600 24.1065 ++++ coreutils-8.27/src/expand-common.c 2017-03-11 23:49:06.757133570 -0600 24.1066 +@@ -18,6 +18,7 @@ 24.1067 + 24.1068 + #include <stdio.h> 24.1069 + #include <sys/types.h> 24.1070 ++#include <mbfile.h> 24.1071 + #include "system.h" 24.1072 + #include "die.h" 24.1073 + #include "error.h" 24.1074 +@@ -105,6 +106,119 @@ set_extend_size (uintmax_t tabval) 24.1075 + return ok; 24.1076 + } 24.1077 + 24.1078 ++extern int 24.1079 ++set_utf_locale (void) 24.1080 ++{ 24.1081 ++ /*try using some predefined locale */ 24.1082 ++ const char* predef_locales[] = {"C.UTF8","en_US.UTF8","en_GB.UTF8"}; 24.1083 ++ 24.1084 ++ const int predef_locales_count=3; 24.1085 ++ for (int i=0;i<predef_locales_count;i++) 24.1086 ++ { 24.1087 ++ if (setlocale(LC_ALL,predef_locales[i])!=NULL) 24.1088 ++ { 24.1089 ++ break; 24.1090 ++ } 24.1091 ++ else if (i==predef_locales_count-1) 24.1092 ++ { 24.1093 ++ return 1; 24.1094 ++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); 24.1095 ++ } 24.1096 ++ } 24.1097 ++ return 0; 24.1098 ++} 24.1099 ++ 24.1100 ++extern bool 24.1101 ++check_utf_locale(void) 24.1102 ++{ 24.1103 ++ char* locale = setlocale (LC_CTYPE , NULL); 24.1104 ++ if (locale == NULL) 24.1105 ++ { 24.1106 ++ return false; 24.1107 ++ } 24.1108 ++ else if (strcasestr(locale, "utf8") == NULL && strcasestr(locale, "utf-8") == NULL) 24.1109 ++ { 24.1110 ++ return false; 24.1111 ++ } 24.1112 ++ return true; 24.1113 ++} 24.1114 ++ 24.1115 ++extern bool 24.1116 ++check_bom(FILE* fp, mb_file_t *mbf) 24.1117 ++{ 24.1118 ++ int c; 24.1119 ++ 24.1120 ++ 24.1121 ++ c=fgetc(fp); 24.1122 ++ 24.1123 ++ /*test BOM header of the first file */ 24.1124 ++ mbf->bufcount=0; 24.1125 ++ if (c == 0xEF) 24.1126 ++ { 24.1127 ++ c=fgetc(fp); 24.1128 ++ } 24.1129 ++ else 24.1130 ++ { 24.1131 ++ if (c != EOF) 24.1132 ++ { 24.1133 ++ ungetc(c,fp); 24.1134 ++ } 24.1135 ++ return false; 24.1136 ++ } 24.1137 ++ 24.1138 ++ if (c == 0xBB) 24.1139 ++ { 24.1140 ++ c=fgetc(fp); 24.1141 ++ } 24.1142 ++ else 24.1143 ++ { 24.1144 ++ if ( c!= EOF ) 24.1145 ++ { 24.1146 ++ mbf->buf[0]=(unsigned char) 0xEF; 24.1147 ++ mbf->bufcount=1; 24.1148 ++ ungetc(c,fp); 24.1149 ++ return false; 24.1150 ++ } 24.1151 ++ else 24.1152 ++ { 24.1153 ++ ungetc(0xEF,fp); 24.1154 ++ return false; 24.1155 ++ } 24.1156 ++ } 24.1157 ++ if (c == 0xBF) 24.1158 ++ { 24.1159 ++ mbf->bufcount=0; 24.1160 ++ return true; 24.1161 ++ } 24.1162 ++ else 24.1163 ++ { 24.1164 ++ if (c != EOF) 24.1165 ++ { 24.1166 ++ mbf->buf[0]=(unsigned char) 0xEF; 24.1167 ++ mbf->buf[1]=(unsigned char) 0xBB; 24.1168 ++ mbf->bufcount=2; 24.1169 ++ ungetc(c,fp); 24.1170 ++ return false; 24.1171 ++ } 24.1172 ++ else 24.1173 ++ { 24.1174 ++ mbf->buf[0]=(unsigned char) 0xEF; 24.1175 ++ mbf->bufcount=1; 24.1176 ++ ungetc(0xBB,fp); 24.1177 ++ return false; 24.1178 ++ } 24.1179 ++ } 24.1180 ++ return false; 24.1181 ++} 24.1182 ++ 24.1183 ++extern void 24.1184 ++print_bom(void) 24.1185 ++{ 24.1186 ++ putc (0xEF, stdout); 24.1187 ++ putc (0xBB, stdout); 24.1188 ++ putc (0xBF, stdout); 24.1189 ++} 24.1190 ++ 24.1191 + /* Add the comma or blank separated list of tab stops STOPS 24.1192 + to the list of tab stops. */ 24.1193 + extern void 24.1194 +diff -Naurp coreutils-8.27-orig/src/expand-common.h coreutils-8.27/src/expand-common.h 24.1195 +--- coreutils-8.27-orig/src/expand-common.h 2017-01-01 16:34:24.000000000 -0600 24.1196 ++++ coreutils-8.27/src/expand-common.h 2017-03-11 23:49:06.758133530 -0600 24.1197 +@@ -34,6 +34,18 @@ extern size_t max_column_width; 24.1198 + /* The desired exit status. */ 24.1199 + extern int exit_status; 24.1200 + 24.1201 ++extern int 24.1202 ++set_utf_locale (void); 24.1203 ++ 24.1204 ++extern bool 24.1205 ++check_utf_locale(void); 24.1206 ++ 24.1207 ++extern bool 24.1208 ++check_bom(FILE* fp, mb_file_t *mbf); 24.1209 ++ 24.1210 ++extern void 24.1211 ++print_bom(void); 24.1212 ++ 24.1213 + /* Add tab stop TABVAL to the end of 'tab_list'. */ 24.1214 + extern void 24.1215 + add_tab_stop (uintmax_t tabval); 24.1216 +diff -Naurp coreutils-8.27-orig/src/fold.c coreutils-8.27/src/fold.c 24.1217 +--- coreutils-8.27-orig/src/fold.c 2017-01-01 16:34:24.000000000 -0600 24.1218 ++++ coreutils-8.27/src/fold.c 2017-03-11 23:49:30.982169404 -0600 24.1219 +@@ -22,12 +22,34 @@ 24.1220 + #include <getopt.h> 24.1221 + #include <sys/types.h> 24.1222 + 24.1223 ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ 24.1224 ++#if HAVE_WCHAR_H 24.1225 ++# include <wchar.h> 24.1226 ++#endif 24.1227 ++ 24.1228 ++/* Get iswprint(), iswblank(), wcwidth(). */ 24.1229 ++#if HAVE_WCTYPE_H 24.1230 ++# include <wctype.h> 24.1231 ++#endif 24.1232 ++ 24.1233 + #include "system.h" 24.1234 + #include "die.h" 24.1235 + #include "error.h" 24.1236 + #include "fadvise.h" 24.1237 + #include "xdectoint.h" 24.1238 + 24.1239 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 24.1240 ++ installation; work around this configuration error. */ 24.1241 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 24.1242 ++# undef MB_LEN_MAX 24.1243 ++# define MB_LEN_MAX 16 24.1244 ++#endif 24.1245 ++ 24.1246 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 24.1247 ++#if HAVE_MBRTOWC && defined mbstate_t 24.1248 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 24.1249 ++#endif 24.1250 ++ 24.1251 + #define TAB_WIDTH 8 24.1252 + 24.1253 + /* The official name of this program (e.g., no 'g' prefix). */ 24.1254 +@@ -35,20 +57,41 @@ 24.1255 + 24.1256 + #define AUTHORS proper_name ("David MacKenzie") 24.1257 + 24.1258 ++#define FATAL_ERROR(Message) \ 24.1259 ++ do \ 24.1260 ++ { \ 24.1261 ++ error (0, 0, (Message)); \ 24.1262 ++ usage (2); \ 24.1263 ++ } \ 24.1264 ++ while (0) 24.1265 ++ 24.1266 ++enum operating_mode 24.1267 ++{ 24.1268 ++ /* Fold texts by columns that are at the given positions. */ 24.1269 ++ column_mode, 24.1270 ++ 24.1271 ++ /* Fold texts by bytes that are at the given positions. */ 24.1272 ++ byte_mode, 24.1273 ++ 24.1274 ++ /* Fold texts by characters that are at the given positions. */ 24.1275 ++ character_mode, 24.1276 ++}; 24.1277 ++ 24.1278 ++/* The argument shows current mode. (Default: column_mode) */ 24.1279 ++static enum operating_mode operating_mode; 24.1280 ++ 24.1281 + /* If nonzero, try to break on whitespace. */ 24.1282 + static bool break_spaces; 24.1283 + 24.1284 +-/* If nonzero, count bytes, not column positions. */ 24.1285 +-static bool count_bytes; 24.1286 +- 24.1287 + /* If nonzero, at least one of the files we read was standard input. */ 24.1288 + static bool have_read_stdin; 24.1289 + 24.1290 +-static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::"; 24.1291 ++static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::"; 24.1292 + 24.1293 + static struct option const longopts[] = 24.1294 + { 24.1295 + {"bytes", no_argument, NULL, 'b'}, 24.1296 ++ {"characters", no_argument, NULL, 'c'}, 24.1297 + {"spaces", no_argument, NULL, 's'}, 24.1298 + {"width", required_argument, NULL, 'w'}, 24.1299 + {GETOPT_HELP_OPTION_DECL}, 24.1300 +@@ -76,6 +119,7 @@ Wrap input lines in each FILE, writing t 24.1301 + 24.1302 + fputs (_("\ 24.1303 + -b, --bytes count bytes rather than columns\n\ 24.1304 ++ -c, --characters count characters rather than columns\n\ 24.1305 + -s, --spaces break at spaces\n\ 24.1306 + -w, --width=WIDTH use WIDTH columns instead of 80\n\ 24.1307 + "), stdout); 24.1308 +@@ -93,7 +137,7 @@ Wrap input lines in each FILE, writing t 24.1309 + static size_t 24.1310 + adjust_column (size_t column, char c) 24.1311 + { 24.1312 +- if (!count_bytes) 24.1313 ++ if (operating_mode != byte_mode) 24.1314 + { 24.1315 + if (c == '\b') 24.1316 + { 24.1317 +@@ -116,30 +160,14 @@ adjust_column (size_t column, char c) 24.1318 + to stdout, with maximum line length WIDTH. 24.1319 + Return true if successful. */ 24.1320 + 24.1321 +-static bool 24.1322 +-fold_file (char const *filename, size_t width) 24.1323 ++static void 24.1324 ++fold_text (FILE *istream, size_t width, int *saved_errno) 24.1325 + { 24.1326 +- FILE *istream; 24.1327 + int c; 24.1328 + size_t column = 0; /* Screen column where next char will go. */ 24.1329 + size_t offset_out = 0; /* Index in 'line_out' for next char. */ 24.1330 + static char *line_out = NULL; 24.1331 + static size_t allocated_out = 0; 24.1332 +- int saved_errno; 24.1333 +- 24.1334 +- if (STREQ (filename, "-")) 24.1335 +- { 24.1336 +- istream = stdin; 24.1337 +- have_read_stdin = true; 24.1338 +- } 24.1339 +- else 24.1340 +- istream = fopen (filename, "r"); 24.1341 +- 24.1342 +- if (istream == NULL) 24.1343 +- { 24.1344 +- error (0, errno, "%s", quotef (filename)); 24.1345 +- return false; 24.1346 +- } 24.1347 + 24.1348 + fadvise (istream, FADVISE_SEQUENTIAL); 24.1349 + 24.1350 +@@ -169,6 +197,15 @@ fold_file (char const *filename, size_t 24.1351 + bool found_blank = false; 24.1352 + size_t logical_end = offset_out; 24.1353 + 24.1354 ++ /* If LINE_OUT has no wide character, 24.1355 ++ put a new wide character in LINE_OUT 24.1356 ++ if column is bigger than width. */ 24.1357 ++ if (offset_out == 0) 24.1358 ++ { 24.1359 ++ line_out[offset_out++] = c; 24.1360 ++ continue; 24.1361 ++ } 24.1362 ++ 24.1363 + /* Look for the last blank. */ 24.1364 + while (logical_end) 24.1365 + { 24.1366 +@@ -215,11 +252,220 @@ fold_file (char const *filename, size_t 24.1367 + line_out[offset_out++] = c; 24.1368 + } 24.1369 + 24.1370 +- saved_errno = errno; 24.1371 ++ *saved_errno = errno; 24.1372 ++ 24.1373 ++ if (offset_out) 24.1374 ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); 24.1375 ++ 24.1376 ++} 24.1377 ++ 24.1378 ++#if HAVE_MBRTOWC 24.1379 ++static void 24.1380 ++fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) 24.1381 ++{ 24.1382 ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 24.1383 ++ size_t buflen = 0; /* The length of the byte sequence in buf. */ 24.1384 ++ char *bufpos = buf; /* Next read position of BUF. */ 24.1385 ++ wint_t wc; /* A gotten wide character. */ 24.1386 ++ size_t mblength; /* The byte size of a multibyte character which shows 24.1387 ++ as same character as WC. */ 24.1388 ++ mbstate_t state, state_bak; /* State of the stream. */ 24.1389 ++ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ 24.1390 ++ 24.1391 ++ static char *line_out = NULL; 24.1392 ++ size_t offset_out = 0; /* Index in `line_out' for next char. */ 24.1393 ++ static size_t allocated_out = 0; 24.1394 ++ 24.1395 ++ int increment; 24.1396 ++ size_t column = 0; 24.1397 ++ 24.1398 ++ size_t last_blank_pos; 24.1399 ++ size_t last_blank_column; 24.1400 ++ int is_blank_seen; 24.1401 ++ int last_blank_increment = 0; 24.1402 ++ int is_bs_following_last_blank; 24.1403 ++ size_t bs_following_last_blank_num; 24.1404 ++ int is_cr_after_last_blank; 24.1405 ++ 24.1406 ++#define CLEAR_FLAGS \ 24.1407 ++ do \ 24.1408 ++ { \ 24.1409 ++ last_blank_pos = 0; \ 24.1410 ++ last_blank_column = 0; \ 24.1411 ++ is_blank_seen = 0; \ 24.1412 ++ is_bs_following_last_blank = 0; \ 24.1413 ++ bs_following_last_blank_num = 0; \ 24.1414 ++ is_cr_after_last_blank = 0; \ 24.1415 ++ } \ 24.1416 ++ while (0) 24.1417 ++ 24.1418 ++#define START_NEW_LINE \ 24.1419 ++ do \ 24.1420 ++ { \ 24.1421 ++ putchar ('\n'); \ 24.1422 ++ column = 0; \ 24.1423 ++ offset_out = 0; \ 24.1424 ++ CLEAR_FLAGS; \ 24.1425 ++ } \ 24.1426 ++ while (0) 24.1427 ++ 24.1428 ++ CLEAR_FLAGS; 24.1429 ++ memset (&state, '\0', sizeof(mbstate_t)); 24.1430 ++ 24.1431 ++ for (;; bufpos += mblength, buflen -= mblength) 24.1432 ++ { 24.1433 ++ if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream)) 24.1434 ++ { 24.1435 ++ memmove (buf, bufpos, buflen); 24.1436 ++ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream); 24.1437 ++ bufpos = buf; 24.1438 ++ } 24.1439 ++ 24.1440 ++ if (buflen < 1) 24.1441 ++ break; 24.1442 ++ 24.1443 ++ /* Get a wide character. */ 24.1444 ++ state_bak = state; 24.1445 ++ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state); 24.1446 ++ 24.1447 ++ switch (mblength) 24.1448 ++ { 24.1449 ++ case (size_t)-1: 24.1450 ++ case (size_t)-2: 24.1451 ++ convfail++; 24.1452 ++ state = state_bak; 24.1453 ++ /* Fall through. */ 24.1454 ++ 24.1455 ++ case 0: 24.1456 ++ mblength = 1; 24.1457 ++ break; 24.1458 ++ } 24.1459 ++ 24.1460 ++rescan: 24.1461 ++ if (convfail) 24.1462 ++ increment = 1; 24.1463 ++ else if (wc == L'\n') 24.1464 ++ { 24.1465 ++ /* preserve newline */ 24.1466 ++ fwrite (line_out, sizeof(char), offset_out, stdout); 24.1467 ++ START_NEW_LINE; 24.1468 ++ continue; 24.1469 ++ } 24.1470 ++ else if (operating_mode == byte_mode) /* byte mode */ 24.1471 ++ increment = mblength; 24.1472 ++ else if (operating_mode == character_mode) /* character mode */ 24.1473 ++ increment = 1; 24.1474 ++ else /* column mode */ 24.1475 ++ { 24.1476 ++ switch (wc) 24.1477 ++ { 24.1478 ++ case L'\b': 24.1479 ++ increment = (column > 0) ? -1 : 0; 24.1480 ++ break; 24.1481 ++ 24.1482 ++ case L'\r': 24.1483 ++ increment = -1 * column; 24.1484 ++ break; 24.1485 ++ 24.1486 ++ case L'\t': 24.1487 ++ increment = 8 - column % 8; 24.1488 ++ break; 24.1489 ++ 24.1490 ++ default: 24.1491 ++ increment = wcwidth (wc); 24.1492 ++ increment = (increment < 0) ? 0 : increment; 24.1493 ++ } 24.1494 ++ } 24.1495 ++ 24.1496 ++ if (column + increment > width && break_spaces && last_blank_pos) 24.1497 ++ { 24.1498 ++ fwrite (line_out, sizeof(char), last_blank_pos, stdout); 24.1499 ++ putchar ('\n'); 24.1500 ++ 24.1501 ++ offset_out = offset_out - last_blank_pos; 24.1502 ++ column = column - last_blank_column + ((is_cr_after_last_blank) 24.1503 ++ ? last_blank_increment : bs_following_last_blank_num); 24.1504 ++ memmove (line_out, line_out + last_blank_pos, offset_out); 24.1505 ++ CLEAR_FLAGS; 24.1506 ++ goto rescan; 24.1507 ++ } 24.1508 ++ 24.1509 ++ if (column + increment > width && column != 0) 24.1510 ++ { 24.1511 ++ fwrite (line_out, sizeof(char), offset_out, stdout); 24.1512 ++ START_NEW_LINE; 24.1513 ++ goto rescan; 24.1514 ++ } 24.1515 ++ 24.1516 ++ if (allocated_out < offset_out + mblength) 24.1517 ++ { 24.1518 ++ line_out = X2REALLOC (line_out, &allocated_out); 24.1519 ++ } 24.1520 ++ 24.1521 ++ memcpy (line_out + offset_out, bufpos, mblength); 24.1522 ++ offset_out += mblength; 24.1523 ++ column += increment; 24.1524 ++ 24.1525 ++ if (is_blank_seen && !convfail && wc == L'\r') 24.1526 ++ is_cr_after_last_blank = 1; 24.1527 ++ 24.1528 ++ if (is_bs_following_last_blank && !convfail && wc == L'\b') 24.1529 ++ ++bs_following_last_blank_num; 24.1530 ++ else 24.1531 ++ is_bs_following_last_blank = 0; 24.1532 ++ 24.1533 ++ if (break_spaces && !convfail && iswblank (wc)) 24.1534 ++ { 24.1535 ++ last_blank_pos = offset_out; 24.1536 ++ last_blank_column = column; 24.1537 ++ is_blank_seen = 1; 24.1538 ++ last_blank_increment = increment; 24.1539 ++ is_bs_following_last_blank = 1; 24.1540 ++ bs_following_last_blank_num = 0; 24.1541 ++ is_cr_after_last_blank = 0; 24.1542 ++ } 24.1543 ++ } 24.1544 ++ 24.1545 ++ *saved_errno = errno; 24.1546 + 24.1547 + if (offset_out) 24.1548 + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); 24.1549 + 24.1550 ++} 24.1551 ++#endif 24.1552 ++ 24.1553 ++/* Fold file FILENAME, or standard input if FILENAME is "-", 24.1554 ++ to stdout, with maximum line length WIDTH. 24.1555 ++ Return 0 if successful, 1 if an error occurs. */ 24.1556 ++ 24.1557 ++static bool 24.1558 ++fold_file (char const *filename, size_t width) 24.1559 ++{ 24.1560 ++ FILE *istream; 24.1561 ++ int saved_errno; 24.1562 ++ 24.1563 ++ if (STREQ (filename, "-")) 24.1564 ++ { 24.1565 ++ istream = stdin; 24.1566 ++ have_read_stdin = 1; 24.1567 ++ } 24.1568 ++ else 24.1569 ++ istream = fopen (filename, "r"); 24.1570 ++ 24.1571 ++ if (istream == NULL) 24.1572 ++ { 24.1573 ++ error (0, errno, "%s", filename); 24.1574 ++ return 1; 24.1575 ++ } 24.1576 ++ 24.1577 ++ /* Define how ISTREAM is being folded. */ 24.1578 ++#if HAVE_MBRTOWC 24.1579 ++ if (MB_CUR_MAX > 1) 24.1580 ++ fold_multibyte_text (istream, width, &saved_errno); 24.1581 ++ else 24.1582 ++#endif 24.1583 ++ fold_text (istream, width, &saved_errno); 24.1584 ++ 24.1585 + if (ferror (istream)) 24.1586 + { 24.1587 + error (0, saved_errno, "%s", quotef (filename)); 24.1588 +@@ -252,7 +498,8 @@ main (int argc, char **argv) 24.1589 + 24.1590 + atexit (close_stdout); 24.1591 + 24.1592 +- break_spaces = count_bytes = have_read_stdin = false; 24.1593 ++ operating_mode = column_mode; 24.1594 ++ break_spaces = have_read_stdin = false; 24.1595 + 24.1596 + while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) 24.1597 + { 24.1598 +@@ -261,7 +508,15 @@ main (int argc, char **argv) 24.1599 + switch (optc) 24.1600 + { 24.1601 + case 'b': /* Count bytes rather than columns. */ 24.1602 +- count_bytes = true; 24.1603 ++ if (operating_mode != column_mode) 24.1604 ++ FATAL_ERROR (_("only one way of folding may be specified")); 24.1605 ++ operating_mode = byte_mode; 24.1606 ++ break; 24.1607 ++ 24.1608 ++ case 'c': 24.1609 ++ if (operating_mode != column_mode) 24.1610 ++ FATAL_ERROR (_("only one way of folding may be specified")); 24.1611 ++ operating_mode = character_mode; 24.1612 + break; 24.1613 + 24.1614 + case 's': /* Break at word boundaries. */ 24.1615 +diff -Naurp coreutils-8.27-orig/src/join.c coreutils-8.27/src/join.c 24.1616 +--- coreutils-8.27-orig/src/join.c 2017-01-01 16:34:24.000000000 -0600 24.1617 ++++ coreutils-8.27/src/join.c 2017-03-11 23:47:13.091286290 -0600 24.1618 +@@ -22,19 +22,33 @@ 24.1619 + #include <sys/types.h> 24.1620 + #include <getopt.h> 24.1621 + 24.1622 ++/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth(). */ 24.1623 ++#if HAVE_WCHAR_H 24.1624 ++# include <wchar.h> 24.1625 ++#endif 24.1626 ++ 24.1627 ++/* Get iswblank(), towupper. */ 24.1628 ++#if HAVE_WCTYPE_H 24.1629 ++# include <wctype.h> 24.1630 ++#endif 24.1631 ++ 24.1632 + #include "system.h" 24.1633 + #include "die.h" 24.1634 + #include "error.h" 24.1635 + #include "fadvise.h" 24.1636 + #include "hard-locale.h" 24.1637 + #include "linebuffer.h" 24.1638 +-#include "memcasecmp.h" 24.1639 + #include "quote.h" 24.1640 + #include "stdio--.h" 24.1641 + #include "xmemcoll.h" 24.1642 + #include "xstrtol.h" 24.1643 + #include "argmatch.h" 24.1644 + 24.1645 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 24.1646 ++#if HAVE_MBRTOWC && defined mbstate_t 24.1647 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 24.1648 ++#endif 24.1649 ++ 24.1650 + /* The official name of this program (e.g., no 'g' prefix). */ 24.1651 + #define PROGRAM_NAME "join" 24.1652 + 24.1653 +@@ -136,10 +150,12 @@ static struct outlist outlist_head; 24.1654 + /* Last element in 'outlist', where a new element can be added. */ 24.1655 + static struct outlist *outlist_end = &outlist_head; 24.1656 + 24.1657 +-/* Tab character separating fields. If negative, fields are separated 24.1658 +- by any nonempty string of blanks, otherwise by exactly one 24.1659 +- tab character whose value (when cast to unsigned char) equals TAB. */ 24.1660 +-static int tab = -1; 24.1661 ++/* Tab character separating fields. If NULL, fields are separated 24.1662 ++ by any nonempty string of blanks. */ 24.1663 ++static char *tab = NULL; 24.1664 ++ 24.1665 ++/* The number of bytes used for tab. */ 24.1666 ++static size_t tablen = 0; 24.1667 + 24.1668 + /* If nonzero, check that the input is correctly ordered. */ 24.1669 + static enum 24.1670 +@@ -276,13 +292,14 @@ xfields (struct line *line) 24.1671 + if (ptr == lim) 24.1672 + return; 24.1673 + 24.1674 +- if (0 <= tab && tab != '\n') 24.1675 ++ if (tab != NULL) 24.1676 + { 24.1677 ++ unsigned char t = tab[0]; 24.1678 + char *sep; 24.1679 +- for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1) 24.1680 ++ for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1) 24.1681 + extract_field (line, ptr, sep - ptr); 24.1682 + } 24.1683 +- else if (tab < 0) 24.1684 ++ else 24.1685 + { 24.1686 + /* Skip leading blanks before the first field. */ 24.1687 + while (field_sep (*ptr)) 24.1688 +@@ -306,6 +323,147 @@ xfields (struct line *line) 24.1689 + extract_field (line, ptr, lim - ptr); 24.1690 + } 24.1691 + 24.1692 ++#if HAVE_MBRTOWC 24.1693 ++static void 24.1694 ++xfields_multibyte (struct line *line) 24.1695 ++{ 24.1696 ++ char *ptr = line->buf.buffer; 24.1697 ++ char const *lim = ptr + line->buf.length - 1; 24.1698 ++ wchar_t wc = 0; 24.1699 ++ size_t mblength = 1; 24.1700 ++ mbstate_t state, state_bak; 24.1701 ++ 24.1702 ++ memset (&state, 0, sizeof (mbstate_t)); 24.1703 ++ 24.1704 ++ if (ptr >= lim) 24.1705 ++ return; 24.1706 ++ 24.1707 ++ if (tab != NULL) 24.1708 ++ { 24.1709 ++ char *sep = ptr; 24.1710 ++ for (; ptr < lim; ptr = sep + mblength) 24.1711 ++ { 24.1712 ++ sep = ptr; 24.1713 ++ while (sep < lim) 24.1714 ++ { 24.1715 ++ state_bak = state; 24.1716 ++ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 24.1717 ++ 24.1718 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 24.1719 ++ { 24.1720 ++ mblength = 1; 24.1721 ++ state = state_bak; 24.1722 ++ } 24.1723 ++ mblength = (mblength < 1) ? 1 : mblength; 24.1724 ++ 24.1725 ++ if (mblength == tablen && !memcmp (sep, tab, mblength)) 24.1726 ++ break; 24.1727 ++ else 24.1728 ++ { 24.1729 ++ sep += mblength; 24.1730 ++ continue; 24.1731 ++ } 24.1732 ++ } 24.1733 ++ 24.1734 ++ if (sep >= lim) 24.1735 ++ break; 24.1736 ++ 24.1737 ++ extract_field (line, ptr, sep - ptr); 24.1738 ++ } 24.1739 ++ } 24.1740 ++ else 24.1741 ++ { 24.1742 ++ /* Skip leading blanks before the first field. */ 24.1743 ++ while(ptr < lim) 24.1744 ++ { 24.1745 ++ state_bak = state; 24.1746 ++ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 24.1747 ++ 24.1748 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 24.1749 ++ { 24.1750 ++ mblength = 1; 24.1751 ++ state = state_bak; 24.1752 ++ break; 24.1753 ++ } 24.1754 ++ mblength = (mblength < 1) ? 1 : mblength; 24.1755 ++ 24.1756 ++ if (!iswblank(wc) && wc != '\n') 24.1757 ++ break; 24.1758 ++ ptr += mblength; 24.1759 ++ } 24.1760 ++ 24.1761 ++ do 24.1762 ++ { 24.1763 ++ char *sep; 24.1764 ++ state_bak = state; 24.1765 ++ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 24.1766 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 24.1767 ++ { 24.1768 ++ mblength = 1; 24.1769 ++ state = state_bak; 24.1770 ++ break; 24.1771 ++ } 24.1772 ++ mblength = (mblength < 1) ? 1 : mblength; 24.1773 ++ 24.1774 ++ sep = ptr + mblength; 24.1775 ++ while (sep < lim) 24.1776 ++ { 24.1777 ++ state_bak = state; 24.1778 ++ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 24.1779 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 24.1780 ++ { 24.1781 ++ mblength = 1; 24.1782 ++ state = state_bak; 24.1783 ++ break; 24.1784 ++ } 24.1785 ++ mblength = (mblength < 1) ? 1 : mblength; 24.1786 ++ 24.1787 ++ if (iswblank (wc) || wc == '\n') 24.1788 ++ break; 24.1789 ++ 24.1790 ++ sep += mblength; 24.1791 ++ } 24.1792 ++ 24.1793 ++ extract_field (line, ptr, sep - ptr); 24.1794 ++ if (sep >= lim) 24.1795 ++ return; 24.1796 ++ 24.1797 ++ state_bak = state; 24.1798 ++ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 24.1799 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 24.1800 ++ { 24.1801 ++ mblength = 1; 24.1802 ++ state = state_bak; 24.1803 ++ break; 24.1804 ++ } 24.1805 ++ mblength = (mblength < 1) ? 1 : mblength; 24.1806 ++ 24.1807 ++ ptr = sep + mblength; 24.1808 ++ while (ptr < lim) 24.1809 ++ { 24.1810 ++ state_bak = state; 24.1811 ++ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 24.1812 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 24.1813 ++ { 24.1814 ++ mblength = 1; 24.1815 ++ state = state_bak; 24.1816 ++ break; 24.1817 ++ } 24.1818 ++ mblength = (mblength < 1) ? 1 : mblength; 24.1819 ++ 24.1820 ++ if (!iswblank (wc) && wc != '\n') 24.1821 ++ break; 24.1822 ++ 24.1823 ++ ptr += mblength; 24.1824 ++ } 24.1825 ++ } 24.1826 ++ while (ptr < lim); 24.1827 ++ } 24.1828 ++ 24.1829 ++ extract_field (line, ptr, lim - ptr); 24.1830 ++} 24.1831 ++#endif 24.1832 ++ 24.1833 + static void 24.1834 + freeline (struct line *line) 24.1835 + { 24.1836 +@@ -327,56 +485,133 @@ keycmp (struct line const *line1, struct 24.1837 + size_t jf_1, size_t jf_2) 24.1838 + { 24.1839 + /* Start of field to compare in each file. */ 24.1840 +- char *beg1; 24.1841 +- char *beg2; 24.1842 +- 24.1843 +- size_t len1; 24.1844 +- size_t len2; /* Length of fields to compare. */ 24.1845 ++ char *beg[2]; 24.1846 ++ char *copy[2]; 24.1847 ++ size_t len[2]; /* Length of fields to compare. */ 24.1848 + int diff; 24.1849 ++ int i, j; 24.1850 ++ int mallocd = 0; 24.1851 + 24.1852 + if (jf_1 < line1->nfields) 24.1853 + { 24.1854 +- beg1 = line1->fields[jf_1].beg; 24.1855 +- len1 = line1->fields[jf_1].len; 24.1856 ++ beg[0] = line1->fields[jf_1].beg; 24.1857 ++ len[0] = line1->fields[jf_1].len; 24.1858 + } 24.1859 + else 24.1860 + { 24.1861 +- beg1 = NULL; 24.1862 +- len1 = 0; 24.1863 ++ beg[0] = NULL; 24.1864 ++ len[0] = 0; 24.1865 + } 24.1866 + 24.1867 + if (jf_2 < line2->nfields) 24.1868 + { 24.1869 +- beg2 = line2->fields[jf_2].beg; 24.1870 +- len2 = line2->fields[jf_2].len; 24.1871 ++ beg[1] = line2->fields[jf_2].beg; 24.1872 ++ len[1] = line2->fields[jf_2].len; 24.1873 + } 24.1874 + else 24.1875 + { 24.1876 +- beg2 = NULL; 24.1877 +- len2 = 0; 24.1878 ++ beg[1] = NULL; 24.1879 ++ len[1] = 0; 24.1880 + } 24.1881 + 24.1882 +- if (len1 == 0) 24.1883 +- return len2 == 0 ? 0 : -1; 24.1884 +- if (len2 == 0) 24.1885 ++ if (len[0] == 0) 24.1886 ++ return len[1] == 0 ? 0 : -1; 24.1887 ++ if (len[1] == 0) 24.1888 + return 1; 24.1889 + 24.1890 + if (ignore_case) 24.1891 + { 24.1892 +- /* FIXME: ignore_case does not work with NLS (in particular, 24.1893 +- with multibyte chars). */ 24.1894 +- diff = memcasecmp (beg1, beg2, MIN (len1, len2)); 24.1895 ++#ifdef HAVE_MBRTOWC 24.1896 ++ if (MB_CUR_MAX > 1) 24.1897 ++ { 24.1898 ++ size_t mblength; 24.1899 ++ wchar_t wc, uwc; 24.1900 ++ mbstate_t state, state_bak; 24.1901 ++ 24.1902 ++ memset (&state, '\0', sizeof (mbstate_t)); 24.1903 ++ 24.1904 ++ for (i = 0; i < 2; i++) 24.1905 ++ { 24.1906 ++ mallocd = 1; 24.1907 ++ copy[i] = xmalloc (len[i] + 1); 24.1908 ++ memset (copy[i], '\0',len[i] + 1); 24.1909 ++ 24.1910 ++ for (j = 0; j < MIN (len[0], len[1]);) 24.1911 ++ { 24.1912 ++ state_bak = state; 24.1913 ++ mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state); 24.1914 ++ 24.1915 ++ switch (mblength) 24.1916 ++ { 24.1917 ++ case (size_t) -1: 24.1918 ++ case (size_t) -2: 24.1919 ++ state = state_bak; 24.1920 ++ /* Fall through */ 24.1921 ++ case 0: 24.1922 ++ mblength = 1; 24.1923 ++ break; 24.1924 ++ 24.1925 ++ default: 24.1926 ++ uwc = towupper (wc); 24.1927 ++ 24.1928 ++ if (uwc != wc) 24.1929 ++ { 24.1930 ++ mbstate_t state_wc; 24.1931 ++ size_t mblen; 24.1932 ++ 24.1933 ++ memset (&state_wc, '\0', sizeof (mbstate_t)); 24.1934 ++ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); 24.1935 ++ assert (mblen != (size_t)-1); 24.1936 ++ } 24.1937 ++ else 24.1938 ++ memcpy (copy[i] + j, beg[i] + j, mblength); 24.1939 ++ } 24.1940 ++ j += mblength; 24.1941 ++ } 24.1942 ++ copy[i][j] = '\0'; 24.1943 ++ } 24.1944 ++ } 24.1945 ++ else 24.1946 ++#endif 24.1947 ++ { 24.1948 ++ for (i = 0; i < 2; i++) 24.1949 ++ { 24.1950 ++ mallocd = 1; 24.1951 ++ copy[i] = xmalloc (len[i] + 1); 24.1952 ++ 24.1953 ++ for (j = 0; j < MIN (len[0], len[1]); j++) 24.1954 ++ copy[i][j] = toupper (beg[i][j]); 24.1955 ++ 24.1956 ++ copy[i][j] = '\0'; 24.1957 ++ } 24.1958 ++ } 24.1959 + } 24.1960 + else 24.1961 + { 24.1962 +- if (hard_LC_COLLATE) 24.1963 +- return xmemcoll (beg1, len1, beg2, len2); 24.1964 +- diff = memcmp (beg1, beg2, MIN (len1, len2)); 24.1965 ++ copy[0] = beg[0]; 24.1966 ++ copy[1] = beg[1]; 24.1967 + } 24.1968 + 24.1969 ++ if (hard_LC_COLLATE) 24.1970 ++ { 24.1971 ++ diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); 24.1972 ++ 24.1973 ++ if (mallocd) 24.1974 ++ for (i = 0; i < 2; i++) 24.1975 ++ free (copy[i]); 24.1976 ++ 24.1977 ++ return diff; 24.1978 ++ } 24.1979 ++ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); 24.1980 ++ 24.1981 ++ if (mallocd) 24.1982 ++ for (i = 0; i < 2; i++) 24.1983 ++ free (copy[i]); 24.1984 ++ 24.1985 ++ 24.1986 + if (diff) 24.1987 + return diff; 24.1988 +- return len1 < len2 ? -1 : len1 != len2; 24.1989 ++ return len[0] - len[1]; 24.1990 + } 24.1991 + 24.1992 + /* Check that successive input lines PREV and CURRENT from input file 24.1993 +@@ -468,6 +703,11 @@ get_line (FILE *fp, struct line **linep, 24.1994 + } 24.1995 + ++line_no[which - 1]; 24.1996 + 24.1997 ++#if HAVE_MBRTOWC 24.1998 ++ if (MB_CUR_MAX > 1) 24.1999 ++ xfields_multibyte (line); 24.2000 ++ else 24.2001 ++#endif 24.2002 + xfields (line); 24.2003 + 24.2004 + if (prevline[which - 1]) 24.2005 +@@ -567,21 +807,28 @@ prfield (size_t n, struct line const *li 24.2006 + 24.2007 + /* Output all the fields in line, other than the join field. */ 24.2008 + 24.2009 ++#define PUT_TAB_CHAR \ 24.2010 ++ do \ 24.2011 ++ { \ 24.2012 ++ (tab != NULL) ? \ 24.2013 ++ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ 24.2014 ++ } \ 24.2015 ++ while (0) 24.2016 ++ 24.2017 + static void 24.2018 + prfields (struct line const *line, size_t join_field, size_t autocount) 24.2019 + { 24.2020 + size_t i; 24.2021 + size_t nfields = autoformat ? autocount : line->nfields; 24.2022 +- char output_separator = tab < 0 ? ' ' : tab; 24.2023 + 24.2024 + for (i = 0; i < join_field && i < nfields; ++i) 24.2025 + { 24.2026 +- putchar (output_separator); 24.2027 ++ PUT_TAB_CHAR; 24.2028 + prfield (i, line); 24.2029 + } 24.2030 + for (i = join_field + 1; i < nfields; ++i) 24.2031 + { 24.2032 +- putchar (output_separator); 24.2033 ++ PUT_TAB_CHAR; 24.2034 + prfield (i, line); 24.2035 + } 24.2036 + } 24.2037 +@@ -592,7 +839,6 @@ static void 24.2038 + prjoin (struct line const *line1, struct line const *line2) 24.2039 + { 24.2040 + const struct outlist *outlist; 24.2041 +- char output_separator = tab < 0 ? ' ' : tab; 24.2042 + size_t field; 24.2043 + struct line const *line; 24.2044 + 24.2045 +@@ -626,7 +872,7 @@ prjoin (struct line const *line1, struct 24.2046 + o = o->next; 24.2047 + if (o == NULL) 24.2048 + break; 24.2049 +- putchar (output_separator); 24.2050 ++ PUT_TAB_CHAR; 24.2051 + } 24.2052 + putchar (eolchar); 24.2053 + } 24.2054 +@@ -1104,20 +1350,43 @@ main (int argc, char **argv) 24.2055 + 24.2056 + case 't': 24.2057 + { 24.2058 +- unsigned char newtab = optarg[0]; 24.2059 ++ char *newtab = NULL; 24.2060 ++ size_t newtablen; 24.2061 ++ newtab = xstrdup (optarg); 24.2062 ++#if HAVE_MBRTOWC 24.2063 ++ if (MB_CUR_MAX > 1) 24.2064 ++ { 24.2065 ++ mbstate_t state; 24.2066 ++ 24.2067 ++ memset (&state, 0, sizeof (mbstate_t)); 24.2068 ++ newtablen = mbrtowc (NULL, newtab, 24.2069 ++ strnlen (newtab, MB_LEN_MAX), 24.2070 ++ &state); 24.2071 ++ if (newtablen == (size_t) 0 24.2072 ++ || newtablen == (size_t) -1 24.2073 ++ || newtablen == (size_t) -2) 24.2074 ++ newtablen = 1; 24.2075 ++ } 24.2076 ++ else 24.2077 ++#endif 24.2078 ++ newtablen = 1; 24.2079 + if (! newtab) 24.2080 +- newtab = '\n'; /* '' => process the whole line. */ 24.2081 ++ newtab = (char*)"\n"; /* '' => process the whole line. */ 24.2082 + else if (optarg[1]) 24.2083 + { 24.2084 +- if (STREQ (optarg, "\\0")) 24.2085 +- newtab = '\0'; 24.2086 +- else 24.2087 +- die (EXIT_FAILURE, 0, _("multi-character tab %s"), 24.2088 +- quote (optarg)); 24.2089 ++ if (newtablen == 1 && newtab[1]) 24.2090 ++ { 24.2091 ++ if (STREQ (newtab, "\\0")) 24.2092 ++ newtab[0] = '\0'; 24.2093 ++ } 24.2094 ++ } 24.2095 ++ if (tab != NULL && strcmp (tab, newtab)) 24.2096 ++ { 24.2097 ++ free (newtab); 24.2098 ++ die (EXIT_FAILURE, 0, _("incompatible tabs")); 24.2099 + } 24.2100 +- if (0 <= tab && tab != newtab) 24.2101 +- die (EXIT_FAILURE, 0, _("incompatible tabs")); 24.2102 + tab = newtab; 24.2103 ++ tablen = newtablen; 24.2104 + } 24.2105 + break; 24.2106 + 24.2107 +diff -Naurp coreutils-8.27-orig/src/pr.c coreutils-8.27/src/pr.c 24.2108 +--- coreutils-8.27-orig/src/pr.c 2017-01-01 16:34:24.000000000 -0600 24.2109 ++++ coreutils-8.27/src/pr.c 2017-03-11 23:47:13.094286139 -0600 24.2110 +@@ -311,6 +311,24 @@ 24.2111 + 24.2112 + #include <getopt.h> 24.2113 + #include <sys/types.h> 24.2114 ++ 24.2115 ++/* Get MB_LEN_MAX. */ 24.2116 ++#include <limits.h> 24.2117 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 24.2118 ++ installation; work around this configuration error. */ 24.2119 ++#if !defined MB_LEN_MAX || MB_LEN_MAX == 1 24.2120 ++# define MB_LEN_MAX 16 24.2121 ++#endif 24.2122 ++ 24.2123 ++/* Get MB_CUR_MAX. */ 24.2124 ++#include <stdlib.h> 24.2125 ++ 24.2126 ++/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */ 24.2127 ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ 24.2128 ++#if HAVE_WCHAR_H 24.2129 ++# include <wchar.h> 24.2130 ++#endif 24.2131 ++ 24.2132 + #include "system.h" 24.2133 + #include "die.h" 24.2134 + #include "error.h" 24.2135 +@@ -324,6 +342,18 @@ 24.2136 + #include "xstrtol.h" 24.2137 + #include "xdectoint.h" 24.2138 + 24.2139 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 24.2140 ++#if HAVE_MBRTOWC && defined mbstate_t 24.2141 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 24.2142 ++#endif 24.2143 ++ 24.2144 ++#ifndef HAVE_DECL_WCWIDTH 24.2145 ++"this configure-time declaration test was not run" 24.2146 ++#endif 24.2147 ++#if !HAVE_DECL_WCWIDTH 24.2148 ++extern int wcwidth (); 24.2149 ++#endif 24.2150 ++ 24.2151 + /* The official name of this program (e.g., no 'g' prefix). */ 24.2152 + #define PROGRAM_NAME "pr" 24.2153 + 24.2154 +@@ -416,7 +446,20 @@ struct COLUMN 24.2155 + 24.2156 + typedef struct COLUMN COLUMN; 24.2157 + 24.2158 +-static int char_to_clump (char c); 24.2159 ++/* Funtion pointers to switch functions for single byte locale or for 24.2160 ++ multibyte locale. If multibyte functions do not exist in your sysytem, 24.2161 ++ these pointers always point the function for single byte locale. */ 24.2162 ++static void (*print_char) (char c); 24.2163 ++static int (*char_to_clump) (char c); 24.2164 ++ 24.2165 ++/* Functions for single byte locale. */ 24.2166 ++static void print_char_single (char c); 24.2167 ++static int char_to_clump_single (char c); 24.2168 ++ 24.2169 ++/* Functions for multibyte locale. */ 24.2170 ++static void print_char_multi (char c); 24.2171 ++static int char_to_clump_multi (char c); 24.2172 ++ 24.2173 + static bool read_line (COLUMN *p); 24.2174 + static bool print_page (void); 24.2175 + static bool print_stored (COLUMN *p); 24.2176 +@@ -428,6 +471,7 @@ static void add_line_number (COLUMN *p); 24.2177 + static void getoptnum (const char *n_str, int min, int *num, 24.2178 + const char *errfmt); 24.2179 + static void getoptarg (char *arg, char switch_char, char *character, 24.2180 ++ int *character_length, int *character_width, 24.2181 + int *number); 24.2182 + static void print_files (int number_of_files, char **av); 24.2183 + static void init_parameters (int number_of_files); 24.2184 +@@ -441,7 +485,6 @@ static void store_char (char c); 24.2185 + static void pad_down (unsigned int lines); 24.2186 + static void read_rest_of_line (COLUMN *p); 24.2187 + static void skip_read (COLUMN *p, int column_number); 24.2188 +-static void print_char (char c); 24.2189 + static void cleanup (void); 24.2190 + static void print_sep_string (void); 24.2191 + static void separator_string (const char *optarg_S); 24.2192 +@@ -453,7 +496,7 @@ static COLUMN *column_vector; 24.2193 + we store the leftmost columns contiguously in buff. 24.2194 + To print a line from buff, get the index of the first character 24.2195 + from line_vector[i], and print up to line_vector[i + 1]. */ 24.2196 +-static char *buff; 24.2197 ++static unsigned char *buff; 24.2198 + 24.2199 + /* Index of the position in buff where the next character 24.2200 + will be stored. */ 24.2201 +@@ -557,7 +600,7 @@ static int chars_per_column; 24.2202 + static bool untabify_input = false; 24.2203 + 24.2204 + /* (-e) The input tab character. */ 24.2205 +-static char input_tab_char = '\t'; 24.2206 ++static char input_tab_char[MB_LEN_MAX] = "\t"; 24.2207 + 24.2208 + /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... 24.2209 + where the leftmost column is 1. */ 24.2210 +@@ -567,7 +610,10 @@ static int chars_per_input_tab = 8; 24.2211 + static bool tabify_output = false; 24.2212 + 24.2213 + /* (-i) The output tab character. */ 24.2214 +-static char output_tab_char = '\t'; 24.2215 ++static char output_tab_char[MB_LEN_MAX] = "\t"; 24.2216 ++ 24.2217 ++/* (-i) The byte length of output tab character. */ 24.2218 ++static int output_tab_char_length = 1; 24.2219 + 24.2220 + /* (-i) The width of the output tab. */ 24.2221 + static int chars_per_output_tab = 8; 24.2222 +@@ -637,7 +683,13 @@ static int line_number; 24.2223 + static bool numbered_lines = false; 24.2224 + 24.2225 + /* (-n) Character which follows each line number. */ 24.2226 +-static char number_separator = '\t'; 24.2227 ++static char number_separator[MB_LEN_MAX] = "\t"; 24.2228 ++ 24.2229 ++/* (-n) The byte length of the character which follows each line number. */ 24.2230 ++static int number_separator_length = 1; 24.2231 ++ 24.2232 ++/* (-n) The character width of the character which follows each line number. */ 24.2233 ++static int number_separator_width = 0; 24.2234 + 24.2235 + /* (-n) line counting starts with 1st line of input file (not with 1st 24.2236 + line of 1st page printed). */ 24.2237 +@@ -690,6 +742,7 @@ static bool use_col_separator = false; 24.2238 + -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ 24.2239 + static char const *col_sep_string = ""; 24.2240 + static int col_sep_length = 0; 24.2241 ++static int col_sep_width = 0; 24.2242 + static char *column_separator = (char *) " "; 24.2243 + static char *line_separator = (char *) "\t"; 24.2244 + 24.2245 +@@ -851,6 +904,13 @@ separator_string (const char *optarg_S) 24.2246 + integer_overflow (); 24.2247 + col_sep_length = len; 24.2248 + col_sep_string = optarg_S; 24.2249 ++ 24.2250 ++#if HAVE_MBRTOWC 24.2251 ++ if (MB_CUR_MAX > 1) 24.2252 ++ col_sep_width = mbswidth (col_sep_string, 0); 24.2253 ++ else 24.2254 ++#endif 24.2255 ++ col_sep_width = col_sep_length; 24.2256 + } 24.2257 + 24.2258 + int 24.2259 +@@ -875,6 +935,21 @@ main (int argc, char **argv) 24.2260 + 24.2261 + atexit (close_stdout); 24.2262 + 24.2263 ++/* Define which functions are used, the ones for single byte locale or the ones 24.2264 ++ for multibyte locale. */ 24.2265 ++#if HAVE_MBRTOWC 24.2266 ++ if (MB_CUR_MAX > 1) 24.2267 ++ { 24.2268 ++ print_char = print_char_multi; 24.2269 ++ char_to_clump = char_to_clump_multi; 24.2270 ++ } 24.2271 ++ else 24.2272 ++#endif 24.2273 ++ { 24.2274 ++ print_char = print_char_single; 24.2275 ++ char_to_clump = char_to_clump_single; 24.2276 ++ } 24.2277 ++ 24.2278 + n_files = 0; 24.2279 + file_names = (argc > 1 24.2280 + ? xnmalloc (argc - 1, sizeof (char *)) 24.2281 +@@ -951,8 +1026,12 @@ main (int argc, char **argv) 24.2282 + break; 24.2283 + case 'e': 24.2284 + if (optarg) 24.2285 +- getoptarg (optarg, 'e', &input_tab_char, 24.2286 +- &chars_per_input_tab); 24.2287 ++ { 24.2288 ++ int dummy_length, dummy_width; 24.2289 ++ 24.2290 ++ getoptarg (optarg, 'e', input_tab_char, &dummy_length, 24.2291 ++ &dummy_width, &chars_per_input_tab); 24.2292 ++ } 24.2293 + /* Could check tab width > 0. */ 24.2294 + untabify_input = true; 24.2295 + break; 24.2296 +@@ -965,8 +1044,12 @@ main (int argc, char **argv) 24.2297 + break; 24.2298 + case 'i': 24.2299 + if (optarg) 24.2300 +- getoptarg (optarg, 'i', &output_tab_char, 24.2301 +- &chars_per_output_tab); 24.2302 ++ { 24.2303 ++ int dummy_width; 24.2304 ++ 24.2305 ++ getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length, 24.2306 ++ &dummy_width, &chars_per_output_tab); 24.2307 ++ } 24.2308 + /* Could check tab width > 0. */ 24.2309 + tabify_output = true; 24.2310 + break; 24.2311 +@@ -984,8 +1067,8 @@ main (int argc, char **argv) 24.2312 + case 'n': 24.2313 + numbered_lines = true; 24.2314 + if (optarg) 24.2315 +- getoptarg (optarg, 'n', &number_separator, 24.2316 +- &chars_per_number); 24.2317 ++ getoptarg (optarg, 'n', number_separator, &number_separator_length, 24.2318 ++ &number_separator_width, &chars_per_number); 24.2319 + break; 24.2320 + case 'N': 24.2321 + skip_count = false; 24.2322 +@@ -1010,6 +1093,7 @@ main (int argc, char **argv) 24.2323 + /* Reset an additional input of -s, -S dominates -s */ 24.2324 + col_sep_string = ""; 24.2325 + col_sep_length = 0; 24.2326 ++ col_sep_width = 0; 24.2327 + use_col_separator = true; 24.2328 + if (optarg) 24.2329 + separator_string (optarg); 24.2330 +@@ -1166,10 +1250,45 @@ getoptnum (const char *n_str, int min, i 24.2331 + a number. */ 24.2332 + 24.2333 + static void 24.2334 +-getoptarg (char *arg, char switch_char, char *character, int *number) 24.2335 ++getoptarg (char *arg, char switch_char, char *character, int *character_length, 24.2336 ++ int *character_width, int *number) 24.2337 + { 24.2338 + if (!ISDIGIT (*arg)) 24.2339 +- *character = *arg++; 24.2340 ++ { 24.2341 ++#ifdef HAVE_MBRTOWC 24.2342 ++ if (MB_CUR_MAX > 1) /* for multibyte locale. */ 24.2343 ++ { 24.2344 ++ wchar_t wc; 24.2345 ++ size_t mblength; 24.2346 ++ int width; 24.2347 ++ mbstate_t state = {'\0'}; 24.2348 ++ 24.2349 ++ mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state); 24.2350 ++ 24.2351 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 24.2352 ++ { 24.2353 ++ *character_length = 1; 24.2354 ++ *character_width = 1; 24.2355 ++ } 24.2356 ++ else 24.2357 ++ { 24.2358 ++ *character_length = (mblength < 1) ? 1 : mblength; 24.2359 ++ width = wcwidth (wc); 24.2360 ++ *character_width = (width < 0) ? 0 : width; 24.2361 ++ } 24.2362 ++ 24.2363 ++ strncpy (character, arg, *character_length); 24.2364 ++ arg += *character_length; 24.2365 ++ } 24.2366 ++ else /* for single byte locale. */ 24.2367 ++#endif 24.2368 ++ { 24.2369 ++ *character = *arg++; 24.2370 ++ *character_length = 1; 24.2371 ++ *character_width = 1; 24.2372 ++ } 24.2373 ++ } 24.2374 ++ 24.2375 + if (*arg) 24.2376 + { 24.2377 + long int tmp_long; 24.2378 +@@ -1191,6 +1310,11 @@ static void 24.2379 + init_parameters (int number_of_files) 24.2380 + { 24.2381 + int chars_used_by_number = 0; 24.2382 ++ int mb_len = 1; 24.2383 ++#if HAVE_MBRTOWC 24.2384 ++ if (MB_CUR_MAX > 1) 24.2385 ++ mb_len = MB_LEN_MAX; 24.2386 ++#endif 24.2387 + 24.2388 + lines_per_body = lines_per_page - lines_per_header - lines_per_footer; 24.2389 + if (lines_per_body <= 0) 24.2390 +@@ -1228,7 +1352,7 @@ init_parameters (int number_of_files) 24.2391 + else 24.2392 + col_sep_string = column_separator; 24.2393 + 24.2394 +- col_sep_length = 1; 24.2395 ++ col_sep_length = col_sep_width = 1; 24.2396 + use_col_separator = true; 24.2397 + } 24.2398 + /* It's rather pointless to define a TAB separator with column 24.2399 +@@ -1258,11 +1382,11 @@ init_parameters (int number_of_files) 24.2400 + + TAB_WIDTH (chars_per_input_tab, chars_per_number); */ 24.2401 + 24.2402 + /* Estimate chars_per_text without any margin and keep it constant. */ 24.2403 +- if (number_separator == '\t') 24.2404 ++ if (number_separator[0] == '\t') 24.2405 + number_width = (chars_per_number 24.2406 + + TAB_WIDTH (chars_per_default_tab, chars_per_number)); 24.2407 + else 24.2408 +- number_width = chars_per_number + 1; 24.2409 ++ number_width = chars_per_number + number_separator_width; 24.2410 + 24.2411 + /* The number is part of the column width unless we are 24.2412 + printing files in parallel. */ 24.2413 +@@ -1271,7 +1395,7 @@ init_parameters (int number_of_files) 24.2414 + } 24.2415 + 24.2416 + int sep_chars, useful_chars; 24.2417 +- if (INT_MULTIPLY_WRAPV (columns - 1, col_sep_length, &sep_chars)) 24.2418 ++ if (INT_MULTIPLY_WRAPV (columns - 1, col_sep_width, &sep_chars)) 24.2419 + sep_chars = INT_MAX; 24.2420 + if (INT_SUBTRACT_WRAPV (chars_per_line - chars_used_by_number, sep_chars, 24.2421 + &useful_chars)) 24.2422 +@@ -1294,7 +1418,7 @@ init_parameters (int number_of_files) 24.2423 + We've to use 8 as the lower limit, if we use chars_per_default_tab = 8 24.2424 + to expand a tab which is not an input_tab-char. */ 24.2425 + free (clump_buff); 24.2426 +- clump_buff = xmalloc (MAX (8, chars_per_input_tab)); 24.2427 ++ clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab)); 24.2428 + } 24.2429 + 24.2430 + /* Open the necessary files, 24.2431 +@@ -1402,7 +1526,7 @@ init_funcs (void) 24.2432 + 24.2433 + /* Enlarge p->start_position of first column to use the same form of 24.2434 + padding_not_printed with all columns. */ 24.2435 +- h = h + col_sep_length; 24.2436 ++ h = h + col_sep_width; 24.2437 + 24.2438 + /* This loop takes care of all but the rightmost column. */ 24.2439 + 24.2440 +@@ -1436,7 +1560,7 @@ init_funcs (void) 24.2441 + } 24.2442 + else 24.2443 + { 24.2444 +- h = h_next + col_sep_length; 24.2445 ++ h = h_next + col_sep_width; 24.2446 + h_next = h + chars_per_column; 24.2447 + } 24.2448 + } 24.2449 +@@ -1727,9 +1851,9 @@ static void 24.2450 + align_column (COLUMN *p) 24.2451 + { 24.2452 + padding_not_printed = p->start_position; 24.2453 +- if (col_sep_length < padding_not_printed) 24.2454 ++ if (col_sep_width < padding_not_printed) 24.2455 + { 24.2456 +- pad_across_to (padding_not_printed - col_sep_length); 24.2457 ++ pad_across_to (padding_not_printed - col_sep_width); 24.2458 + padding_not_printed = ANYWHERE; 24.2459 + } 24.2460 + 24.2461 +@@ -2004,13 +2128,13 @@ store_char (char c) 24.2462 + /* May be too generous. */ 24.2463 + buff = X2REALLOC (buff, &buff_allocated); 24.2464 + } 24.2465 +- buff[buff_current++] = c; 24.2466 ++ buff[buff_current++] = (unsigned char) c; 24.2467 + } 24.2468 + 24.2469 + static void 24.2470 + add_line_number (COLUMN *p) 24.2471 + { 24.2472 +- int i; 24.2473 ++ int i, j; 24.2474 + char *s; 24.2475 + int num_width; 24.2476 + 24.2477 +@@ -2027,22 +2151,24 @@ add_line_number (COLUMN *p) 24.2478 + /* Tabification is assumed for multiple columns, also for n-separators, 24.2479 + but 'default n-separator = TAB' hasn't been given priority over 24.2480 + equal column_width also specified by POSIX. */ 24.2481 +- if (number_separator == '\t') 24.2482 ++ if (number_separator[0] == '\t') 24.2483 + { 24.2484 + i = number_width - chars_per_number; 24.2485 + while (i-- > 0) 24.2486 + (p->char_func) (' '); 24.2487 + } 24.2488 + else 24.2489 +- (p->char_func) (number_separator); 24.2490 ++ for (j = 0; j < number_separator_length; j++) 24.2491 ++ (p->char_func) (number_separator[j]); 24.2492 + } 24.2493 + else 24.2494 + /* To comply with POSIX, we avoid any expansion of default TAB 24.2495 + separator with a single column output. No column_width requirement 24.2496 + has to be considered. */ 24.2497 + { 24.2498 +- (p->char_func) (number_separator); 24.2499 +- if (number_separator == '\t') 24.2500 ++ for (j = 0; j < number_separator_length; j++) 24.2501 ++ (p->char_func) (number_separator[j]); 24.2502 ++ if (number_separator[0] == '\t') 24.2503 + output_position = POS_AFTER_TAB (chars_per_output_tab, 24.2504 + output_position); 24.2505 + } 24.2506 +@@ -2203,7 +2329,7 @@ print_white_space (void) 24.2507 + while (goal - h_old > 1 24.2508 + && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) 24.2509 + { 24.2510 +- putchar (output_tab_char); 24.2511 ++ fwrite (output_tab_char, sizeof(char), output_tab_char_length, stdout); 24.2512 + h_old = h_new; 24.2513 + } 24.2514 + while (++h_old <= goal) 24.2515 +@@ -2223,6 +2349,7 @@ print_sep_string (void) 24.2516 + { 24.2517 + char const *s = col_sep_string; 24.2518 + int l = col_sep_length; 24.2519 ++ int not_space_flag; 24.2520 + 24.2521 + if (separators_not_printed <= 0) 24.2522 + { 24.2523 +@@ -2234,6 +2361,7 @@ print_sep_string (void) 24.2524 + { 24.2525 + for (; separators_not_printed > 0; --separators_not_printed) 24.2526 + { 24.2527 ++ not_space_flag = 0; 24.2528 + while (l-- > 0) 24.2529 + { 24.2530 + /* 3 types of sep_strings: spaces only, spaces and chars, 24.2531 +@@ -2247,12 +2375,15 @@ print_sep_string (void) 24.2532 + } 24.2533 + else 24.2534 + { 24.2535 ++ not_space_flag = 1; 24.2536 + if (spaces_not_printed > 0) 24.2537 + print_white_space (); 24.2538 + putchar (*s++); 24.2539 +- ++output_position; 24.2540 + } 24.2541 + } 24.2542 ++ if (not_space_flag) 24.2543 ++ output_position += col_sep_width; 24.2544 ++ 24.2545 + /* sep_string ends with some spaces */ 24.2546 + if (spaces_not_printed > 0) 24.2547 + print_white_space (); 24.2548 +@@ -2280,7 +2411,7 @@ print_clump (COLUMN *p, int n, char *clu 24.2549 + required number of tabs and spaces. */ 24.2550 + 24.2551 + static void 24.2552 +-print_char (char c) 24.2553 ++print_char_single (char c) 24.2554 + { 24.2555 + if (tabify_output) 24.2556 + { 24.2557 +@@ -2304,6 +2435,74 @@ print_char (char c) 24.2558 + putchar (c); 24.2559 + } 24.2560 + 24.2561 ++#ifdef HAVE_MBRTOWC 24.2562 ++static void 24.2563 ++print_char_multi (char c) 24.2564 ++{ 24.2565 ++ static size_t mbc_pos = 0; 24.2566 ++ static char mbc[MB_LEN_MAX] = {'\0'}; 24.2567 ++ static mbstate_t state = {'\0'}; 24.2568 ++ mbstate_t state_bak; 24.2569 ++ wchar_t wc; 24.2570 ++ size_t mblength; 24.2571 ++ int width; 24.2572 ++ 24.2573 ++ if (tabify_output) 24.2574 ++ { 24.2575 ++ state_bak = state; 24.2576 ++ mbc[mbc_pos++] = c; 24.2577 ++ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); 24.2578 ++ 24.2579 ++ while (mbc_pos > 0) 24.2580 ++ { 24.2581 ++ switch (mblength) 24.2582 ++ { 24.2583 ++ case (size_t)-2: 24.2584 ++ state = state_bak; 24.2585 ++ return; 24.2586 ++ 24.2587 ++ case (size_t)-1: 24.2588 ++ state = state_bak; 24.2589 ++ ++output_position; 24.2590 ++ putchar (mbc[0]); 24.2591 ++ memmove (mbc, mbc + 1, MB_CUR_MAX - 1); 24.2592 ++ --mbc_pos; 24.2593 ++ break; 24.2594 ++ 24.2595 ++ case 0: 24.2596 ++ mblength = 1; 24.2597 ++ 24.2598 ++ default: 24.2599 ++ if (wc == L' ') 24.2600 ++ { 24.2601 ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 24.2602 ++ --mbc_pos; 24.2603 ++ ++spaces_not_printed; 24.2604 ++ return; 24.2605 ++ } 24.2606 ++ else if (spaces_not_printed > 0) 24.2607 ++ print_white_space (); 24.2608 ++ 24.2609 ++ /* Nonprintables are assumed to have width 0, except L'\b'. */ 24.2610 ++ if ((width = wcwidth (wc)) < 1) 24.2611 ++ { 24.2612 ++ if (wc == L'\b') 24.2613 ++ --output_position; 24.2614 ++ } 24.2615 ++ else 24.2616 ++ output_position += width; 24.2617 ++ 24.2618 ++ fwrite (mbc, sizeof(char), mblength, stdout); 24.2619 ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 24.2620 ++ mbc_pos -= mblength; 24.2621 ++ } 24.2622 ++ } 24.2623 ++ return; 24.2624 ++ } 24.2625 ++ putchar (c); 24.2626 ++} 24.2627 ++#endif 24.2628 ++ 24.2629 + /* Skip to page PAGE before printing. 24.2630 + PAGE may be larger than total number of pages. */ 24.2631 + 24.2632 +@@ -2483,9 +2682,9 @@ read_line (COLUMN *p) 24.2633 + align_empty_cols = false; 24.2634 + } 24.2635 + 24.2636 +- if (col_sep_length < padding_not_printed) 24.2637 ++ if (col_sep_width < padding_not_printed) 24.2638 + { 24.2639 +- pad_across_to (padding_not_printed - col_sep_length); 24.2640 ++ pad_across_to (padding_not_printed - col_sep_width); 24.2641 + padding_not_printed = ANYWHERE; 24.2642 + } 24.2643 + 24.2644 +@@ -2555,7 +2754,7 @@ print_stored (COLUMN *p) 24.2645 + int i; 24.2646 + 24.2647 + int line = p->current_line++; 24.2648 +- char *first = &buff[line_vector[line]]; 24.2649 ++ unsigned char *first = &buff[line_vector[line]]; 24.2650 + /* FIXME 24.2651 + UMR: Uninitialized memory read: 24.2652 + * This is occurring while in: 24.2653 +@@ -2567,7 +2766,7 @@ print_stored (COLUMN *p) 24.2654 + xmalloc [xmalloc.c:94] 24.2655 + init_store_cols [pr.c:1648] 24.2656 + */ 24.2657 +- char *last = &buff[line_vector[line + 1]]; 24.2658 ++ unsigned char *last = &buff[line_vector[line + 1]]; 24.2659 + 24.2660 + pad_vertically = true; 24.2661 + 24.2662 +@@ -2586,9 +2785,9 @@ print_stored (COLUMN *p) 24.2663 + } 24.2664 + } 24.2665 + 24.2666 +- if (col_sep_length < padding_not_printed) 24.2667 ++ if (col_sep_width < padding_not_printed) 24.2668 + { 24.2669 +- pad_across_to (padding_not_printed - col_sep_length); 24.2670 ++ pad_across_to (padding_not_printed - col_sep_width); 24.2671 + padding_not_printed = ANYWHERE; 24.2672 + } 24.2673 + 24.2674 +@@ -2601,8 +2800,8 @@ print_stored (COLUMN *p) 24.2675 + if (spaces_not_printed == 0) 24.2676 + { 24.2677 + output_position = p->start_position + end_vector[line]; 24.2678 +- if (p->start_position - col_sep_length == chars_per_margin) 24.2679 +- output_position -= col_sep_length; 24.2680 ++ if (p->start_position - col_sep_width == chars_per_margin) 24.2681 ++ output_position -= col_sep_width; 24.2682 + } 24.2683 + 24.2684 + return true; 24.2685 +@@ -2621,7 +2820,7 @@ print_stored (COLUMN *p) 24.2686 + number of characters is 1.) */ 24.2687 + 24.2688 + static int 24.2689 +-char_to_clump (char c) 24.2690 ++char_to_clump_single (char c) 24.2691 + { 24.2692 + unsigned char uc = c; 24.2693 + char *s = clump_buff; 24.2694 +@@ -2631,10 +2830,10 @@ char_to_clump (char c) 24.2695 + int chars; 24.2696 + int chars_per_c = 8; 24.2697 + 24.2698 +- if (c == input_tab_char) 24.2699 ++ if (c == input_tab_char[0]) 24.2700 + chars_per_c = chars_per_input_tab; 24.2701 + 24.2702 +- if (c == input_tab_char || c == '\t') 24.2703 ++ if (c == input_tab_char[0] || c == '\t') 24.2704 + { 24.2705 + width = TAB_WIDTH (chars_per_c, input_position); 24.2706 + 24.2707 +@@ -2715,6 +2914,164 @@ char_to_clump (char c) 24.2708 + return chars; 24.2709 + } 24.2710 + 24.2711 ++#ifdef HAVE_MBRTOWC 24.2712 ++static int 24.2713 ++char_to_clump_multi (char c) 24.2714 ++{ 24.2715 ++ static size_t mbc_pos = 0; 24.2716 ++ static char mbc[MB_LEN_MAX] = {'\0'}; 24.2717 ++ static mbstate_t state = {'\0'}; 24.2718 ++ mbstate_t state_bak; 24.2719 ++ wchar_t wc; 24.2720 ++ size_t mblength; 24.2721 ++ int wc_width; 24.2722 ++ register char *s = clump_buff; 24.2723 ++ register int i, j; 24.2724 ++ char esc_buff[4]; 24.2725 ++ int width; 24.2726 ++ int chars; 24.2727 ++ int chars_per_c = 8; 24.2728 ++ 24.2729 ++ state_bak = state; 24.2730 ++ mbc[mbc_pos++] = c; 24.2731 ++ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); 24.2732 ++ 24.2733 ++ width = 0; 24.2734 ++ chars = 0; 24.2735 ++ while (mbc_pos > 0) 24.2736 ++ { 24.2737 ++ switch (mblength) 24.2738 ++ { 24.2739 ++ case (size_t)-2: 24.2740 ++ state = state_bak; 24.2741 ++ return 0; 24.2742 ++ 24.2743 ++ case (size_t)-1: 24.2744 ++ state = state_bak; 24.2745 ++ mblength = 1; 24.2746 ++ 24.2747 ++ if (use_esc_sequence || use_cntrl_prefix) 24.2748 ++ { 24.2749 ++ width = +4; 24.2750 ++ chars = +4; 24.2751 ++ *s++ = '\\'; 24.2752 ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[0]); 24.2753 ++ for (i = 0; i <= 2; ++i) 24.2754 ++ *s++ = (int) esc_buff[i]; 24.2755 ++ } 24.2756 ++ else 24.2757 ++ { 24.2758 ++ width += 1; 24.2759 ++ chars += 1; 24.2760 ++ *s++ = mbc[0]; 24.2761 ++ } 24.2762 ++ break; 24.2763 ++ 24.2764 ++ case 0: 24.2765 ++ mblength = 1; 24.2766 ++ /* Fall through */ 24.2767 ++ 24.2768 ++ default: 24.2769 ++ if (memcmp (mbc, input_tab_char, mblength) == 0) 24.2770 ++ chars_per_c = chars_per_input_tab; 24.2771 ++ 24.2772 ++ if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t') 24.2773 ++ { 24.2774 ++ int width_inc; 24.2775 ++ 24.2776 ++ width_inc = TAB_WIDTH (chars_per_c, input_position); 24.2777 ++ width += width_inc; 24.2778 ++ 24.2779 ++ if (untabify_input) 24.2780 ++ { 24.2781 ++ for (i = width_inc; i; --i) 24.2782 ++ *s++ = ' '; 24.2783 ++ chars += width_inc; 24.2784 ++ } 24.2785 ++ else 24.2786 ++ { 24.2787 ++ for (i = 0; i < mblength; i++) 24.2788 ++ *s++ = mbc[i]; 24.2789 ++ chars += mblength; 24.2790 ++ } 24.2791 ++ } 24.2792 ++ else if ((wc_width = wcwidth (wc)) < 1) 24.2793 ++ { 24.2794 ++ if (use_esc_sequence) 24.2795 ++ { 24.2796 ++ for (i = 0; i < mblength; i++) 24.2797 ++ { 24.2798 ++ width += 4; 24.2799 ++ chars += 4; 24.2800 ++ *s++ = '\\'; 24.2801 ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); 24.2802 ++ for (j = 0; j <= 2; ++j) 24.2803 ++ *s++ = (int) esc_buff[j]; 24.2804 ++ } 24.2805 ++ } 24.2806 ++ else if (use_cntrl_prefix) 24.2807 ++ { 24.2808 ++ if (wc < 0200) 24.2809 ++ { 24.2810 ++ width += 2; 24.2811 ++ chars += 2; 24.2812 ++ *s++ = '^'; 24.2813 ++ *s++ = wc ^ 0100; 24.2814 ++ } 24.2815 ++ else 24.2816 ++ { 24.2817 ++ for (i = 0; i < mblength; i++) 24.2818 ++ { 24.2819 ++ width += 4; 24.2820 ++ chars += 4; 24.2821 ++ *s++ = '\\'; 24.2822 ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); 24.2823 ++ for (j = 0; j <= 2; ++j) 24.2824 ++ *s++ = (int) esc_buff[j]; 24.2825 ++ } 24.2826 ++ } 24.2827 ++ } 24.2828 ++ else if (wc == L'\b') 24.2829 ++ { 24.2830 ++ width += -1; 24.2831 ++ chars += 1; 24.2832 ++ *s++ = c; 24.2833 ++ } 24.2834 ++ else 24.2835 ++ { 24.2836 ++ width += 0; 24.2837 ++ chars += mblength; 24.2838 ++ for (i = 0; i < mblength; i++) 24.2839 ++ *s++ = mbc[i]; 24.2840 ++ } 24.2841 ++ } 24.2842 ++ else 24.2843 ++ { 24.2844 ++ width += wc_width; 24.2845 ++ chars += mblength; 24.2846 ++ for (i = 0; i < mblength; i++) 24.2847 ++ *s++ = mbc[i]; 24.2848 ++ } 24.2849 ++ } 24.2850 ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 24.2851 ++ mbc_pos -= mblength; 24.2852 ++ } 24.2853 ++ 24.2854 ++ /* Too many backspaces must put us in position 0 -- never negative. */ 24.2855 ++ if (width < 0 && input_position == 0) 24.2856 ++ { 24.2857 ++ chars = 0; 24.2858 ++ input_position = 0; 24.2859 ++ } 24.2860 ++ else if (width < 0 && input_position <= -width) 24.2861 ++ input_position = 0; 24.2862 ++ else 24.2863 ++ input_position += width; 24.2864 ++ 24.2865 ++ return chars; 24.2866 ++} 24.2867 ++#endif 24.2868 ++ 24.2869 + /* We've just printed some files and need to clean up things before 24.2870 + looking for more options and printing the next batch of files. 24.2871 + 24.2872 +diff -Naurp coreutils-8.27-orig/src/sort.c coreutils-8.27/src/sort.c 24.2873 +--- coreutils-8.27-orig/src/sort.c 2017-01-01 16:34:24.000000000 -0600 24.2874 ++++ coreutils-8.27/src/sort.c 2017-03-11 23:49:22.416505389 -0600 24.2875 +@@ -29,6 +29,14 @@ 24.2876 + #include <sys/wait.h> 24.2877 + #include <signal.h> 24.2878 + #include <assert.h> 24.2879 ++#if HAVE_WCHAR_H 24.2880 ++# include <wchar.h> 24.2881 ++#endif 24.2882 ++/* Get isw* functions. */ 24.2883 ++#if HAVE_WCTYPE_H 24.2884 ++# include <wctype.h> 24.2885 ++#endif 24.2886 ++ 24.2887 + #include "system.h" 24.2888 + #include "argmatch.h" 24.2889 + #include "die.h" 24.2890 +@@ -165,14 +173,39 @@ static int decimal_point; 24.2891 + /* Thousands separator; if -1, then there isn't one. */ 24.2892 + static int thousands_sep; 24.2893 + 24.2894 ++/* True if -f is specified. */ 24.2895 ++static bool folding; 24.2896 ++ 24.2897 + /* Nonzero if the corresponding locales are hard. */ 24.2898 + static bool hard_LC_COLLATE; 24.2899 +-#if HAVE_NL_LANGINFO 24.2900 ++#if HAVE_LANGINFO_CODESET 24.2901 + static bool hard_LC_TIME; 24.2902 + #endif 24.2903 + 24.2904 + #define NONZERO(x) ((x) != 0) 24.2905 + 24.2906 ++/* get a multibyte character's byte length. */ 24.2907 ++#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE) \ 24.2908 ++ do \ 24.2909 ++ { \ 24.2910 ++ wchar_t wc; \ 24.2911 ++ mbstate_t state_bak; \ 24.2912 ++ \ 24.2913 ++ state_bak = STATE; \ 24.2914 ++ mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE); \ 24.2915 ++ \ 24.2916 ++ switch (MBLENGTH) \ 24.2917 ++ { \ 24.2918 ++ case (size_t)-1: \ 24.2919 ++ case (size_t)-2: \ 24.2920 ++ STATE = state_bak; \ 24.2921 ++ /* Fall through. */ \ 24.2922 ++ case 0: \ 24.2923 ++ MBLENGTH = 1; \ 24.2924 ++ } \ 24.2925 ++ } \ 24.2926 ++ while (0) 24.2927 ++ 24.2928 + /* The kind of blanks for '-b' to skip in various options. */ 24.2929 + enum blanktype { bl_start, bl_end, bl_both }; 24.2930 + 24.2931 +@@ -346,13 +379,11 @@ static bool reverse; 24.2932 + they were read if all keys compare equal. */ 24.2933 + static bool stable; 24.2934 + 24.2935 +-/* If TAB has this value, blanks separate fields. */ 24.2936 +-enum { TAB_DEFAULT = CHAR_MAX + 1 }; 24.2937 +- 24.2938 +-/* Tab character separating fields. If TAB_DEFAULT, then fields are 24.2939 ++/* Tab character separating fields. If tab_length is 0, then fields are 24.2940 + separated by the empty string between a non-blank character and a blank 24.2941 + character. */ 24.2942 +-static int tab = TAB_DEFAULT; 24.2943 ++static char tab[MB_LEN_MAX + 1]; 24.2944 ++static size_t tab_length = 0; 24.2945 + 24.2946 + /* Flag to remove consecutive duplicate lines from the output. 24.2947 + Only the last of a sequence of equal lines will be output. */ 24.2948 +@@ -811,6 +842,46 @@ reap_all (void) 24.2949 + reap (-1); 24.2950 + } 24.2951 + 24.2952 ++/* Function pointers. */ 24.2953 ++static void 24.2954 ++(*inittables) (void); 24.2955 ++static char * 24.2956 ++(*begfield) (const struct line*, const struct keyfield *); 24.2957 ++static char * 24.2958 ++(*limfield) (const struct line*, const struct keyfield *); 24.2959 ++static void 24.2960 ++(*skipblanks) (char **ptr, char *lim); 24.2961 ++static int 24.2962 ++(*getmonth) (char const *, size_t, char **); 24.2963 ++static int 24.2964 ++(*keycompare) (const struct line *, const struct line *); 24.2965 ++static int 24.2966 ++(*numcompare) (const char *, const char *); 24.2967 ++ 24.2968 ++/* Test for white space multibyte character. 24.2969 ++ Set LENGTH the byte length of investigated multibyte character. */ 24.2970 ++#if HAVE_MBRTOWC 24.2971 ++static int 24.2972 ++ismbblank (const char *str, size_t len, size_t *length) 24.2973 ++{ 24.2974 ++ size_t mblength; 24.2975 ++ wchar_t wc; 24.2976 ++ mbstate_t state; 24.2977 ++ 24.2978 ++ memset (&state, '\0', sizeof(mbstate_t)); 24.2979 ++ mblength = mbrtowc (&wc, str, len, &state); 24.2980 ++ 24.2981 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 24.2982 ++ { 24.2983 ++ *length = 1; 24.2984 ++ return 0; 24.2985 ++ } 24.2986 ++ 24.2987 ++ *length = (mblength < 1) ? 1 : mblength; 24.2988 ++ return iswblank (wc) || wc == '\n'; 24.2989 ++} 24.2990 ++#endif 24.2991 ++ 24.2992 + /* Clean up any remaining temporary files. */ 24.2993 + 24.2994 + static void 24.2995 +@@ -1255,7 +1326,7 @@ zaptemp (char const *name) 24.2996 + free (node); 24.2997 + } 24.2998 + 24.2999 +-#if HAVE_NL_LANGINFO 24.3000 ++#if HAVE_LANGINFO_CODESET 24.3001 + 24.3002 + static int 24.3003 + struct_month_cmp (void const *m1, void const *m2) 24.3004 +@@ -1270,7 +1341,7 @@ struct_month_cmp (void const *m1, void c 24.3005 + /* Initialize the character class tables. */ 24.3006 + 24.3007 + static void 24.3008 +-inittables (void) 24.3009 ++inittables_uni (void) 24.3010 + { 24.3011 + size_t i; 24.3012 + 24.3013 +@@ -1282,7 +1353,7 @@ inittables (void) 24.3014 + fold_toupper[i] = toupper (i); 24.3015 + } 24.3016 + 24.3017 +-#if HAVE_NL_LANGINFO 24.3018 ++#if HAVE_LANGINFO_CODESET 24.3019 + /* If we're not in the "C" locale, read different names for months. */ 24.3020 + if (hard_LC_TIME) 24.3021 + { 24.3022 +@@ -1364,6 +1435,84 @@ specify_nmerge (int oi, char c, char con 24.3023 + xstrtol_fatal (e, oi, c, long_options, s); 24.3024 + } 24.3025 + 24.3026 ++#if HAVE_MBRTOWC 24.3027 ++static void 24.3028 ++inittables_mb (void) 24.3029 ++{ 24.3030 ++ int i, j, k, l; 24.3031 ++ char *name, *s, *lc_time, *lc_ctype; 24.3032 ++ size_t s_len, mblength; 24.3033 ++ char mbc[MB_LEN_MAX]; 24.3034 ++ wchar_t wc, pwc; 24.3035 ++ mbstate_t state_mb, state_wc; 24.3036 ++ 24.3037 ++ lc_time = setlocale (LC_TIME, ""); 24.3038 ++ if (lc_time) 24.3039 ++ lc_time = xstrdup (lc_time); 24.3040 ++ 24.3041 ++ lc_ctype = setlocale (LC_CTYPE, ""); 24.3042 ++ if (lc_ctype) 24.3043 ++ lc_ctype = xstrdup (lc_ctype); 24.3044 ++ 24.3045 ++ if (lc_time && lc_ctype) 24.3046 ++ /* temporarily set LC_CTYPE to match LC_TIME, so that we can convert 24.3047 ++ * the names of months to upper case */ 24.3048 ++ setlocale (LC_CTYPE, lc_time); 24.3049 ++ 24.3050 ++ for (i = 0; i < MONTHS_PER_YEAR; i++) 24.3051 ++ { 24.3052 ++ s = (char *) nl_langinfo (ABMON_1 + i); 24.3053 ++ s_len = strlen (s); 24.3054 ++ monthtab[i].name = name = (char *) xmalloc (s_len + 1); 24.3055 ++ monthtab[i].val = i + 1; 24.3056 ++ 24.3057 ++ memset (&state_mb, '\0', sizeof (mbstate_t)); 24.3058 ++ memset (&state_wc, '\0', sizeof (mbstate_t)); 24.3059 ++ 24.3060 ++ for (j = 0; j < s_len;) 24.3061 ++ { 24.3062 ++ if (!ismbblank (s + j, s_len - j, &mblength)) 24.3063 ++ break; 24.3064 ++ j += mblength; 24.3065 ++ } 24.3066 ++ 24.3067 ++ for (k = 0; j < s_len;) 24.3068 ++ { 24.3069 ++ mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb); 24.3070 ++ assert (mblength != (size_t)-1 && mblength != (size_t)-2); 24.3071 ++ if (mblength == 0) 24.3072 ++ break; 24.3073 ++ 24.3074 ++ pwc = towupper (wc); 24.3075 ++ if (pwc == wc) 24.3076 ++ { 24.3077 ++ memcpy (mbc, s + j, mblength); 24.3078 ++ j += mblength; 24.3079 ++ } 24.3080 ++ else 24.3081 ++ { 24.3082 ++ j += mblength; 24.3083 ++ mblength = wcrtomb (mbc, pwc, &state_wc); 24.3084 ++ assert (mblength != (size_t)0 && mblength != (size_t)-1); 24.3085 ++ } 24.3086 ++ 24.3087 ++ for (l = 0; l < mblength; l++) 24.3088 ++ name[k++] = mbc[l]; 24.3089 ++ } 24.3090 ++ name[k] = '\0'; 24.3091 ++ } 24.3092 ++ qsort ((void *) monthtab, MONTHS_PER_YEAR, 24.3093 ++ sizeof (struct month), struct_month_cmp); 24.3094 ++ 24.3095 ++ if (lc_time && lc_ctype) 24.3096 ++ /* restore the original locales */ 24.3097 ++ setlocale (LC_CTYPE, lc_ctype); 24.3098 ++ 24.3099 ++ free (lc_ctype); 24.3100 ++ free (lc_time); 24.3101 ++} 24.3102 ++#endif 24.3103 ++ 24.3104 + /* Specify the amount of main memory to use when sorting. */ 24.3105 + static void 24.3106 + specify_sort_size (int oi, char c, char const *s) 24.3107 +@@ -1597,7 +1746,7 @@ buffer_linelim (struct buffer const *buf 24.3108 + by KEY in LINE. */ 24.3109 + 24.3110 + static char * 24.3111 +-begfield (struct line const *line, struct keyfield const *key) 24.3112 ++begfield_uni (const struct line *line, const struct keyfield *key) 24.3113 + { 24.3114 + char *ptr = line->text, *lim = ptr + line->length - 1; 24.3115 + size_t sword = key->sword; 24.3116 +@@ -1606,10 +1755,10 @@ begfield (struct line const *line, struc 24.3117 + /* The leading field separator itself is included in a field when -t 24.3118 + is absent. */ 24.3119 + 24.3120 +- if (tab != TAB_DEFAULT) 24.3121 ++ if (tab_length) 24.3122 + while (ptr < lim && sword--) 24.3123 + { 24.3124 +- while (ptr < lim && *ptr != tab) 24.3125 ++ while (ptr < lim && *ptr != tab[0]) 24.3126 + ++ptr; 24.3127 + if (ptr < lim) 24.3128 + ++ptr; 24.3129 +@@ -1635,11 +1784,70 @@ begfield (struct line const *line, struc 24.3130 + return ptr; 24.3131 + } 24.3132 + 24.3133 ++#if HAVE_MBRTOWC 24.3134 ++static char * 24.3135 ++begfield_mb (const struct line *line, const struct keyfield *key) 24.3136 ++{ 24.3137 ++ int i; 24.3138 ++ char *ptr = line->text, *lim = ptr + line->length - 1; 24.3139 ++ size_t sword = key->sword; 24.3140 ++ size_t schar = key->schar; 24.3141 ++ size_t mblength; 24.3142 ++ mbstate_t state; 24.3143 ++ 24.3144 ++ memset (&state, '\0', sizeof(mbstate_t)); 24.3145 ++ 24.3146 ++ if (tab_length) 24.3147 ++ while (ptr < lim && sword--) 24.3148 ++ { 24.3149 ++ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) 24.3150 ++ { 24.3151 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 24.3152 ++ ptr += mblength; 24.3153 ++ } 24.3154 ++ if (ptr < lim) 24.3155 ++ { 24.3156 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 24.3157 ++ ptr += mblength; 24.3158 ++ } 24.3159 ++ } 24.3160 ++ else 24.3161 ++ while (ptr < lim && sword--) 24.3162 ++ { 24.3163 ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 24.3164 ++ ptr += mblength; 24.3165 ++ if (ptr < lim) 24.3166 ++ { 24.3167 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 24.3168 ++ ptr += mblength; 24.3169 ++ } 24.3170 ++ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) 24.3171 ++ ptr += mblength; 24.3172 ++ } 24.3173 ++ 24.3174 ++ if (key->skipsblanks) 24.3175 ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 24.3176 ++ ptr += mblength; 24.3177 ++ 24.3178 ++ for (i = 0; i < schar; i++) 24.3179 ++ { 24.3180 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 24.3181 ++ 24.3182 ++ if (ptr + mblength > lim) 24.3183 ++ break; 24.3184 ++ else 24.3185 ++ ptr += mblength; 24.3186 ++ } 24.3187 ++ 24.3188 ++ return ptr; 24.3189 ++} 24.3190 ++#endif 24.3191 ++ 24.3192 + /* Return the limit of (a pointer to the first character after) the field 24.3193 + in LINE specified by KEY. */ 24.3194 + 24.3195 + static char * 24.3196 +-limfield (struct line const *line, struct keyfield const *key) 24.3197 ++limfield_uni (const struct line *line, const struct keyfield *key) 24.3198 + { 24.3199 + char *ptr = line->text, *lim = ptr + line->length - 1; 24.3200 + size_t eword = key->eword, echar = key->echar; 24.3201 +@@ -1654,10 +1862,10 @@ limfield (struct line const *line, struc 24.3202 + 'beginning' is the first character following the delimiting TAB. 24.3203 + Otherwise, leave PTR pointing at the first 'blank' character after 24.3204 + the preceding field. */ 24.3205 +- if (tab != TAB_DEFAULT) 24.3206 ++ if (tab_length) 24.3207 + while (ptr < lim && eword--) 24.3208 + { 24.3209 +- while (ptr < lim && *ptr != tab) 24.3210 ++ while (ptr < lim && *ptr != tab[0]) 24.3211 + ++ptr; 24.3212 + if (ptr < lim && (eword || echar)) 24.3213 + ++ptr; 24.3214 +@@ -1703,10 +1911,10 @@ limfield (struct line const *line, struc 24.3215 + */ 24.3216 + 24.3217 + /* Make LIM point to the end of (one byte past) the current field. */ 24.3218 +- if (tab != TAB_DEFAULT) 24.3219 ++ if (tab_length) 24.3220 + { 24.3221 + char *newlim; 24.3222 +- newlim = memchr (ptr, tab, lim - ptr); 24.3223 ++ newlim = memchr (ptr, tab[0], lim - ptr); 24.3224 + if (newlim) 24.3225 + lim = newlim; 24.3226 + } 24.3227 +@@ -1737,6 +1945,130 @@ limfield (struct line const *line, struc 24.3228 + return ptr; 24.3229 + } 24.3230 + 24.3231 ++#if HAVE_MBRTOWC 24.3232 ++static char * 24.3233 ++limfield_mb (const struct line *line, const struct keyfield *key) 24.3234 ++{ 24.3235 ++ char *ptr = line->text, *lim = ptr + line->length - 1; 24.3236 ++ size_t eword = key->eword, echar = key->echar; 24.3237 ++ int i; 24.3238 ++ size_t mblength; 24.3239 ++ mbstate_t state; 24.3240 ++ 24.3241 ++ if (echar == 0) 24.3242 ++ eword++; /* skip all of end field. */ 24.3243 ++ 24.3244 ++ memset (&state, '\0', sizeof(mbstate_t)); 24.3245 ++ 24.3246 ++ if (tab_length) 24.3247 ++ while (ptr < lim && eword--) 24.3248 ++ { 24.3249 ++ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) 24.3250 ++ { 24.3251 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 24.3252 ++ ptr += mblength; 24.3253 ++ } 24.3254 ++ if (ptr < lim && (eword | echar)) 24.3255 ++ { 24.3256 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 24.3257 ++ ptr += mblength; 24.3258 ++ } 24.3259 ++ } 24.3260 ++ else 24.3261 ++ while (ptr < lim && eword--) 24.3262 ++ { 24.3263 ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 24.3264 ++ ptr += mblength; 24.3265 ++ if (ptr < lim) 24.3266 ++ { 24.3267 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 24.3268 ++ ptr += mblength; 24.3269 ++ } 24.3270 ++ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) 24.3271 ++ ptr += mblength; 24.3272 ++ } 24.3273 ++ 24.3274 ++ 24.3275 ++# ifdef POSIX_UNSPECIFIED 24.3276 ++ /* Make LIM point to the end of (one byte past) the current field. */ 24.3277 ++ if (tab_length) 24.3278 ++ { 24.3279 ++ char *newlim, *p; 24.3280 ++ 24.3281 ++ newlim = NULL; 24.3282 ++ for (p = ptr; p < lim;) 24.3283 ++ { 24.3284 ++ if (memcmp (p, tab, tab_length) == 0) 24.3285 ++ { 24.3286 ++ newlim = p; 24.3287 ++ break; 24.3288 ++ } 24.3289 ++ 24.3290 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 24.3291 ++ p += mblength; 24.3292 ++ } 24.3293 ++ } 24.3294 ++ else 24.3295 ++ { 24.3296 ++ char *newlim; 24.3297 ++ newlim = ptr; 24.3298 ++ 24.3299 ++ while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength)) 24.3300 ++ newlim += mblength; 24.3301 ++ if (ptr < lim) 24.3302 ++ { 24.3303 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 24.3304 ++ ptr += mblength; 24.3305 ++ } 24.3306 ++ while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength)) 24.3307 ++ newlim += mblength; 24.3308 ++ lim = newlim; 24.3309 ++ } 24.3310 ++# endif 24.3311 ++ 24.3312 ++ if (echar != 0) 24.3313 ++ { 24.3314 ++ /* If we're skipping leading blanks, don't start counting characters 24.3315 ++ * until after skipping past any leading blanks. */ 24.3316 ++ if (key->skipeblanks) 24.3317 ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 24.3318 ++ ptr += mblength; 24.3319 ++ 24.3320 ++ memset (&state, '\0', sizeof(mbstate_t)); 24.3321 ++ 24.3322 ++ /* Advance PTR by ECHAR (if possible), but no further than LIM. */ 24.3323 ++ for (i = 0; i < echar; i++) 24.3324 ++ { 24.3325 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 24.3326 ++ 24.3327 ++ if (ptr + mblength > lim) 24.3328 ++ break; 24.3329 ++ else 24.3330 ++ ptr += mblength; 24.3331 ++ } 24.3332 ++ } 24.3333 ++ 24.3334 ++ return ptr; 24.3335 ++} 24.3336 ++#endif 24.3337 ++ 24.3338 ++static void 24.3339 ++skipblanks_uni (char **ptr, char *lim) 24.3340 ++{ 24.3341 ++ while (*ptr < lim && blanks[to_uchar (**ptr)]) 24.3342 ++ ++(*ptr); 24.3343 ++} 24.3344 ++ 24.3345 ++#if HAVE_MBRTOWC 24.3346 ++static void 24.3347 ++skipblanks_mb (char **ptr, char *lim) 24.3348 ++{ 24.3349 ++ size_t mblength; 24.3350 ++ while (*ptr < lim && ismbblank (*ptr, lim - *ptr, &mblength)) 24.3351 ++ (*ptr) += mblength; 24.3352 ++} 24.3353 ++#endif 24.3354 ++ 24.3355 + /* Fill BUF reading from FP, moving buf->left bytes from the end 24.3356 + of buf->buf to the beginning first. If EOF is reached and the 24.3357 + file wasn't terminated by a newline, supply one. Set up BUF's line 24.3358 +@@ -1823,8 +2155,22 @@ fillbuf (struct buffer *buf, FILE *fp, c 24.3359 + else 24.3360 + { 24.3361 + if (key->skipsblanks) 24.3362 +- while (blanks[to_uchar (*line_start)]) 24.3363 +- line_start++; 24.3364 ++ { 24.3365 ++#if HAVE_MBRTOWC 24.3366 ++ if (MB_CUR_MAX > 1) 24.3367 ++ { 24.3368 ++ size_t mblength; 24.3369 ++ while (line_start < line->keylim && 24.3370 ++ ismbblank (line_start, 24.3371 ++ line->keylim - line_start, 24.3372 ++ &mblength)) 24.3373 ++ line_start += mblength; 24.3374 ++ } 24.3375 ++ else 24.3376 ++#endif 24.3377 ++ while (blanks[to_uchar (*line_start)]) 24.3378 ++ line_start++; 24.3379 ++ } 24.3380 + line->keybeg = line_start; 24.3381 + } 24.3382 + } 24.3383 +@@ -1958,12 +2304,10 @@ find_unit_order (char const *number) 24.3384 + <none/unknown> < K/k < M < G < T < P < E < Z < Y */ 24.3385 + 24.3386 + static int 24.3387 +-human_numcompare (char const *a, char const *b) 24.3388 ++human_numcompare (char *a, char *b) 24.3389 + { 24.3390 +- while (blanks[to_uchar (*a)]) 24.3391 +- a++; 24.3392 +- while (blanks[to_uchar (*b)]) 24.3393 +- b++; 24.3394 ++ skipblanks(&a, a + strlen(a)); 24.3395 ++ skipblanks(&b, b + strlen(b)); 24.3396 + 24.3397 + int diff = find_unit_order (a) - find_unit_order (b); 24.3398 + return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); 24.3399 +@@ -1974,7 +2318,7 @@ human_numcompare (char const *a, char co 24.3400 + hideously fast. */ 24.3401 + 24.3402 + static int 24.3403 +-numcompare (char const *a, char const *b) 24.3404 ++numcompare_uni (const char *a, const char *b) 24.3405 + { 24.3406 + while (blanks[to_uchar (*a)]) 24.3407 + a++; 24.3408 +@@ -1984,6 +2328,25 @@ numcompare (char const *a, char const *b 24.3409 + return strnumcmp (a, b, decimal_point, thousands_sep); 24.3410 + } 24.3411 + 24.3412 ++#if HAVE_MBRTOWC 24.3413 ++static int 24.3414 ++numcompare_mb (const char *a, const char *b) 24.3415 ++{ 24.3416 ++ size_t mblength, len; 24.3417 ++ len = strlen (a); /* okay for UTF-8 */ 24.3418 ++ while (*a && ismbblank (a, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) 24.3419 ++ { 24.3420 ++ a += mblength; 24.3421 ++ len -= mblength; 24.3422 ++ } 24.3423 ++ len = strlen (b); /* okay for UTF-8 */ 24.3424 ++ while (*b && ismbblank (b, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) 24.3425 ++ b += mblength; 24.3426 ++ 24.3427 ++ return strnumcmp (a, b, decimal_point, thousands_sep); 24.3428 ++} 24.3429 ++#endif /* HAV_EMBRTOWC */ 24.3430 ++ 24.3431 + /* Work around a problem whereby the long double value returned by glibc's 24.3432 + strtold ("NaN", ...) contains uninitialized bits: clear all bytes of 24.3433 + A and B before calling strtold. FIXME: remove this function once 24.3434 +@@ -2034,7 +2397,7 @@ general_numcompare (char const *sa, char 24.3435 + Return 0 if the name in S is not recognized. */ 24.3436 + 24.3437 + static int 24.3438 +-getmonth (char const *month, char **ea) 24.3439 ++getmonth_uni (char const *month, size_t len, char **ea) 24.3440 + { 24.3441 + size_t lo = 0; 24.3442 + size_t hi = MONTHS_PER_YEAR; 24.3443 +@@ -2310,15 +2673,14 @@ debug_key (struct line const *line, stru 24.3444 + char saved = *lim; 24.3445 + *lim = '\0'; 24.3446 + 24.3447 +- while (blanks[to_uchar (*beg)]) 24.3448 +- beg++; 24.3449 ++ skipblanks (&beg, lim); 24.3450 + 24.3451 + char *tighter_lim = beg; 24.3452 + 24.3453 + if (lim < beg) 24.3454 + tighter_lim = lim; 24.3455 + else if (key->month) 24.3456 +- getmonth (beg, &tighter_lim); 24.3457 ++ getmonth (beg, lim-beg, &tighter_lim); 24.3458 + else if (key->general_numeric) 24.3459 + ignore_value (strtold (beg, &tighter_lim)); 24.3460 + else if (key->numeric || key->human_numeric) 24.3461 +@@ -2452,7 +2814,7 @@ key_warnings (struct keyfield const *gke 24.3462 + /* Warn about significant leading blanks. */ 24.3463 + bool implicit_skip = key_numeric (key) || key->month; 24.3464 + bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ 24.3465 +- if (!zero_width && !gkey_only && tab == TAB_DEFAULT && !line_offset 24.3466 ++ if (!zero_width && !gkey_only && !tab_length && !line_offset 24.3467 + && ((!key->skipsblanks && !implicit_skip) 24.3468 + || (!key->skipsblanks && key->schar) 24.3469 + || (!key->skipeblanks && key->echar))) 24.3470 +@@ -2510,11 +2872,87 @@ key_warnings (struct keyfield const *gke 24.3471 + error (0, 0, _("option '-r' only applies to last-resort comparison")); 24.3472 + } 24.3473 + 24.3474 ++#if HAVE_MBRTOWC 24.3475 ++static int 24.3476 ++getmonth_mb (const char *s, size_t len, char **ea) 24.3477 ++{ 24.3478 ++ char *month; 24.3479 ++ register size_t i; 24.3480 ++ register int lo = 0, hi = MONTHS_PER_YEAR, result; 24.3481 ++ char *tmp; 24.3482 ++ size_t wclength, mblength; 24.3483 ++ const char *pp; 24.3484 ++ const wchar_t *wpp; 24.3485 ++ wchar_t *month_wcs; 24.3486 ++ mbstate_t state; 24.3487 ++ 24.3488 ++ while (len > 0 && ismbblank (s, len, &mblength)) 24.3489 ++ { 24.3490 ++ s += mblength; 24.3491 ++ len -= mblength; 24.3492 ++ } 24.3493 ++ 24.3494 ++ if (len == 0) 24.3495 ++ return 0; 24.3496 ++ 24.3497 ++ if (SIZE_MAX - len < 1) 24.3498 ++ xalloc_die (); 24.3499 ++ 24.3500 ++ month = (char *) xnmalloc (len + 1, MB_CUR_MAX); 24.3501 ++ 24.3502 ++ pp = tmp = (char *) xnmalloc (len + 1, MB_CUR_MAX); 24.3503 ++ memcpy (tmp, s, len); 24.3504 ++ tmp[len] = '\0'; 24.3505 ++ wpp = month_wcs = (wchar_t *) xnmalloc (len + 1, sizeof (wchar_t)); 24.3506 ++ memset (&state, '\0', sizeof (mbstate_t)); 24.3507 ++ 24.3508 ++ wclength = mbsrtowcs (month_wcs, &pp, len + 1, &state); 24.3509 ++ if (wclength == (size_t)-1 || pp != NULL) 24.3510 ++ error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s)); 24.3511 ++ 24.3512 ++ for (i = 0; i < wclength; i++) 24.3513 ++ { 24.3514 ++ month_wcs[i] = towupper(month_wcs[i]); 24.3515 ++ if (iswblank (month_wcs[i])) 24.3516 ++ { 24.3517 ++ month_wcs[i] = L'\0'; 24.3518 ++ break; 24.3519 ++ } 24.3520 ++ } 24.3521 ++ 24.3522 ++ mblength = wcsrtombs (month, &wpp, (len + 1) * MB_CUR_MAX, &state); 24.3523 ++ assert (mblength != (-1) && wpp == NULL); 24.3524 ++ 24.3525 ++ do 24.3526 ++ { 24.3527 ++ int ix = (lo + hi) / 2; 24.3528 ++ 24.3529 ++ if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0) 24.3530 ++ hi = ix; 24.3531 ++ else 24.3532 ++ lo = ix; 24.3533 ++ } 24.3534 ++ while (hi - lo > 1); 24.3535 ++ 24.3536 ++ result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name)) 24.3537 ++ ? monthtab[lo].val : 0); 24.3538 ++ 24.3539 ++ if (ea && result) 24.3540 ++ *ea = (char*) s + strlen (monthtab[lo].name); 24.3541 ++ 24.3542 ++ free (month); 24.3543 ++ free (tmp); 24.3544 ++ free (month_wcs); 24.3545 ++ 24.3546 ++ return result; 24.3547 ++} 24.3548 ++#endif 24.3549 ++ 24.3550 + /* Compare two lines A and B trying every key in sequence until there 24.3551 + are no more keys or a difference is found. */ 24.3552 + 24.3553 + static int 24.3554 +-keycompare (struct line const *a, struct line const *b) 24.3555 ++keycompare_uni (const struct line *a, const struct line *b) 24.3556 + { 24.3557 + struct keyfield *key = keylist; 24.3558 + 24.3559 +@@ -2599,7 +3037,7 @@ keycompare (struct line const *a, struct 24.3560 + else if (key->human_numeric) 24.3561 + diff = human_numcompare (ta, tb); 24.3562 + else if (key->month) 24.3563 +- diff = getmonth (ta, NULL) - getmonth (tb, NULL); 24.3564 ++ diff = getmonth (ta, tlena, NULL) - getmonth (tb, tlenb, NULL); 24.3565 + else if (key->random) 24.3566 + diff = compare_random (ta, tlena, tb, tlenb); 24.3567 + else if (key->version) 24.3568 +@@ -2715,6 +3153,211 @@ keycompare (struct line const *a, struct 24.3569 + return key->reverse ? -diff : diff; 24.3570 + } 24.3571 + 24.3572 ++#if HAVE_MBRTOWC 24.3573 ++static int 24.3574 ++keycompare_mb (const struct line *a, const struct line *b) 24.3575 ++{ 24.3576 ++ struct keyfield *key = keylist; 24.3577 ++ 24.3578 ++ /* For the first iteration only, the key positions have been 24.3579 ++ precomputed for us. */ 24.3580 ++ char *texta = a->keybeg; 24.3581 ++ char *textb = b->keybeg; 24.3582 ++ char *lima = a->keylim; 24.3583 ++ char *limb = b->keylim; 24.3584 ++ 24.3585 ++ size_t mblength_a, mblength_b; 24.3586 ++ wchar_t wc_a, wc_b; 24.3587 ++ mbstate_t state_a, state_b; 24.3588 ++ 24.3589 ++ int diff = 0; 24.3590 ++ 24.3591 ++ memset (&state_a, '\0', sizeof(mbstate_t)); 24.3592 ++ memset (&state_b, '\0', sizeof(mbstate_t)); 24.3593 ++ /* Ignore keys with start after end. */ 24.3594 ++ if (a->keybeg - a->keylim > 0) 24.3595 ++ return 0; 24.3596 ++ 24.3597 ++ 24.3598 ++ /* Ignore and/or translate chars before comparing. */ 24.3599 ++# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \ 24.3600 ++ do \ 24.3601 ++ { \ 24.3602 ++ wchar_t uwc; \ 24.3603 ++ char mbc[MB_LEN_MAX]; \ 24.3604 ++ mbstate_t state_wc; \ 24.3605 ++ \ 24.3606 ++ for (NEW_LEN = i = 0; i < LEN;) \ 24.3607 ++ { \ 24.3608 ++ mbstate_t state_bak; \ 24.3609 ++ \ 24.3610 ++ state_bak = STATE; \ 24.3611 ++ MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE); \ 24.3612 ++ \ 24.3613 ++ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1 \ 24.3614 ++ || MBLENGTH == 0) \ 24.3615 ++ { \ 24.3616 ++ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \ 24.3617 ++ STATE = state_bak; \ 24.3618 ++ if (!ignore) \ 24.3619 ++ COPY[NEW_LEN++] = TEXT[i]; \ 24.3620 ++ i++; \ 24.3621 ++ continue; \ 24.3622 ++ } \ 24.3623 ++ \ 24.3624 ++ if (ignore) \ 24.3625 ++ { \ 24.3626 ++ if ((ignore == nonprinting && !iswprint (WC)) \ 24.3627 ++ || (ignore == nondictionary \ 24.3628 ++ && !iswalnum (WC) && !iswblank (WC))) \ 24.3629 ++ { \ 24.3630 ++ i += MBLENGTH; \ 24.3631 ++ continue; \ 24.3632 ++ } \ 24.3633 ++ } \ 24.3634 ++ \ 24.3635 ++ if (translate) \ 24.3636 ++ { \ 24.3637 ++ \ 24.3638 ++ uwc = towupper(WC); \ 24.3639 ++ if (WC == uwc) \ 24.3640 ++ { \ 24.3641 ++ memcpy (mbc, TEXT + i, MBLENGTH); \ 24.3642 ++ i += MBLENGTH; \ 24.3643 ++ } \ 24.3644 ++ else \ 24.3645 ++ { \ 24.3646 ++ i += MBLENGTH; \ 24.3647 ++ WC = uwc; \ 24.3648 ++ memset (&state_wc, '\0', sizeof (mbstate_t)); \ 24.3649 ++ \ 24.3650 ++ MBLENGTH = wcrtomb (mbc, WC, &state_wc); \ 24.3651 ++ assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0); \ 24.3652 ++ } \ 24.3653 ++ \ 24.3654 ++ for (j = 0; j < MBLENGTH; j++) \ 24.3655 ++ COPY[NEW_LEN++] = mbc[j]; \ 24.3656 ++ } \ 24.3657 ++ else \ 24.3658 ++ for (j = 0; j < MBLENGTH; j++) \ 24.3659 ++ COPY[NEW_LEN++] = TEXT[i++]; \ 24.3660 ++ } \ 24.3661 ++ COPY[NEW_LEN] = '\0'; \ 24.3662 ++ } \ 24.3663 ++ while (0) 24.3664 ++ 24.3665 ++ /* Actually compare the fields. */ 24.3666 ++ 24.3667 ++ for (;;) 24.3668 ++ { 24.3669 ++ /* Find the lengths. */ 24.3670 ++ size_t lena = lima <= texta ? 0 : lima - texta; 24.3671 ++ size_t lenb = limb <= textb ? 0 : limb - textb; 24.3672 ++ 24.3673 ++ char enda IF_LINT (= 0); 24.3674 ++ char endb IF_LINT (= 0); 24.3675 ++ 24.3676 ++ char const *translate = key->translate; 24.3677 ++ bool const *ignore = key->ignore; 24.3678 ++ 24.3679 ++ if (ignore || translate) 24.3680 ++ { 24.3681 ++ if (SIZE_MAX - lenb - 2 < lena) 24.3682 ++ xalloc_die (); 24.3683 ++ char *copy_a = (char *) xnmalloc (lena + lenb + 2, MB_CUR_MAX); 24.3684 ++ char *copy_b = copy_a + lena * MB_CUR_MAX + 1; 24.3685 ++ size_t new_len_a, new_len_b; 24.3686 ++ size_t i, j; 24.3687 ++ 24.3688 ++ IGNORE_CHARS (new_len_a, lena, texta, copy_a, 24.3689 ++ wc_a, mblength_a, state_a); 24.3690 ++ IGNORE_CHARS (new_len_b, lenb, textb, copy_b, 24.3691 ++ wc_b, mblength_b, state_b); 24.3692 ++ texta = copy_a; textb = copy_b; 24.3693 ++ lena = new_len_a; lenb = new_len_b; 24.3694 ++ } 24.3695 ++ else 24.3696 ++ { 24.3697 ++ /* Use the keys in-place, temporarily null-terminated. */ 24.3698 ++ enda = texta[lena]; texta[lena] = '\0'; 24.3699 ++ endb = textb[lenb]; textb[lenb] = '\0'; 24.3700 ++ } 24.3701 ++ 24.3702 ++ if (key->random) 24.3703 ++ diff = compare_random (texta, lena, textb, lenb); 24.3704 ++ else if (key->numeric | key->general_numeric | key->human_numeric) 24.3705 ++ { 24.3706 ++ char savea = *lima, saveb = *limb; 24.3707 ++ 24.3708 ++ *lima = *limb = '\0'; 24.3709 ++ diff = (key->numeric ? numcompare (texta, textb) 24.3710 ++ : key->general_numeric ? general_numcompare (texta, textb) 24.3711 ++ : human_numcompare (texta, textb)); 24.3712 ++ *lima = savea, *limb = saveb; 24.3713 ++ } 24.3714 ++ else if (key->version) 24.3715 ++ diff = filevercmp (texta, textb); 24.3716 ++ else if (key->month) 24.3717 ++ diff = getmonth (texta, lena, NULL) - getmonth (textb, lenb, NULL); 24.3718 ++ else if (lena == 0) 24.3719 ++ diff = - NONZERO (lenb); 24.3720 ++ else if (lenb == 0) 24.3721 ++ diff = 1; 24.3722 ++ else if (hard_LC_COLLATE && !folding) 24.3723 ++ { 24.3724 ++ diff = xmemcoll0 (texta, lena + 1, textb, lenb + 1); 24.3725 ++ } 24.3726 ++ else 24.3727 ++ { 24.3728 ++ diff = memcmp (texta, textb, MIN (lena, lenb)); 24.3729 ++ if (diff == 0) 24.3730 ++ diff = lena < lenb ? -1 : lena != lenb; 24.3731 ++ } 24.3732 ++ 24.3733 ++ if (ignore || translate) 24.3734 ++ free (texta); 24.3735 ++ else 24.3736 ++ { 24.3737 ++ texta[lena] = enda; 24.3738 ++ textb[lenb] = endb; 24.3739 ++ } 24.3740 ++ 24.3741 ++ if (diff) 24.3742 ++ goto not_equal; 24.3743 ++ 24.3744 ++ key = key->next; 24.3745 ++ if (! key) 24.3746 ++ break; 24.3747 ++ 24.3748 ++ /* Find the beginning and limit of the next field. */ 24.3749 ++ if (key->eword != -1) 24.3750 ++ lima = limfield (a, key), limb = limfield (b, key); 24.3751 ++ else 24.3752 ++ lima = a->text + a->length - 1, limb = b->text + b->length - 1; 24.3753 ++ 24.3754 ++ if (key->sword != -1) 24.3755 ++ texta = begfield (a, key), textb = begfield (b, key); 24.3756 ++ else 24.3757 ++ { 24.3758 ++ texta = a->text, textb = b->text; 24.3759 ++ if (key->skipsblanks) 24.3760 ++ { 24.3761 ++ while (texta < lima && ismbblank (texta, lima - texta, &mblength_a)) 24.3762 ++ texta += mblength_a; 24.3763 ++ while (textb < limb && ismbblank (textb, limb - textb, &mblength_b)) 24.3764 ++ textb += mblength_b; 24.3765 ++ } 24.3766 ++ } 24.3767 ++ } 24.3768 ++ 24.3769 ++not_equal: 24.3770 ++ if (key && key->reverse) 24.3771 ++ return -diff; 24.3772 ++ else 24.3773 ++ return diff; 24.3774 ++} 24.3775 ++#endif 24.3776 ++ 24.3777 + /* Compare two lines A and B, returning negative, zero, or positive 24.3778 + depending on whether A compares less than, equal to, or greater than B. */ 24.3779 + 24.3780 +@@ -2742,7 +3385,7 @@ compare (struct line const *a, struct li 24.3781 + diff = - NONZERO (blen); 24.3782 + else if (blen == 0) 24.3783 + diff = 1; 24.3784 +- else if (hard_LC_COLLATE) 24.3785 ++ else if (hard_LC_COLLATE && !folding) 24.3786 + { 24.3787 + /* Note xmemcoll0 is a performance enhancement as 24.3788 + it will not unconditionally write '\0' after the 24.3789 +@@ -4139,6 +4782,7 @@ set_ordering (char const *s, struct keyf 24.3790 + break; 24.3791 + case 'f': 24.3792 + key->translate = fold_toupper; 24.3793 ++ folding = true; 24.3794 + break; 24.3795 + case 'g': 24.3796 + key->general_numeric = true; 24.3797 +@@ -4218,7 +4862,7 @@ main (int argc, char **argv) 24.3798 + initialize_exit_failure (SORT_FAILURE); 24.3799 + 24.3800 + hard_LC_COLLATE = hard_locale (LC_COLLATE); 24.3801 +-#if HAVE_NL_LANGINFO 24.3802 ++#if HAVE_LANGINFO_CODESET 24.3803 + hard_LC_TIME = hard_locale (LC_TIME); 24.3804 + #endif 24.3805 + 24.3806 +@@ -4239,6 +4883,29 @@ main (int argc, char **argv) 24.3807 + thousands_sep = -1; 24.3808 + } 24.3809 + 24.3810 ++#if HAVE_MBRTOWC 24.3811 ++ if (MB_CUR_MAX > 1) 24.3812 ++ { 24.3813 ++ inittables = inittables_mb; 24.3814 ++ begfield = begfield_mb; 24.3815 ++ limfield = limfield_mb; 24.3816 ++ skipblanks = skipblanks_mb; 24.3817 ++ getmonth = getmonth_mb; 24.3818 ++ keycompare = keycompare_mb; 24.3819 ++ numcompare = numcompare_mb; 24.3820 ++ } 24.3821 ++ else 24.3822 ++#endif 24.3823 ++ { 24.3824 ++ inittables = inittables_uni; 24.3825 ++ begfield = begfield_uni; 24.3826 ++ limfield = limfield_uni; 24.3827 ++ skipblanks = skipblanks_uni; 24.3828 ++ getmonth = getmonth_uni; 24.3829 ++ keycompare = keycompare_uni; 24.3830 ++ numcompare = numcompare_uni; 24.3831 ++ } 24.3832 ++ 24.3833 + have_read_stdin = false; 24.3834 + inittables (); 24.3835 + 24.3836 +@@ -4513,13 +5180,34 @@ main (int argc, char **argv) 24.3837 + 24.3838 + case 't': 24.3839 + { 24.3840 +- char newtab = optarg[0]; 24.3841 +- if (! newtab) 24.3842 ++ char newtab[MB_LEN_MAX + 1]; 24.3843 ++ size_t newtab_length = 1; 24.3844 ++ strncpy (newtab, optarg, MB_LEN_MAX); 24.3845 ++ if (! newtab[0]) 24.3846 + die (SORT_FAILURE, 0, _("empty tab")); 24.3847 +- if (optarg[1]) 24.3848 ++#if HAVE_MBRTOWC 24.3849 ++ if (MB_CUR_MAX > 1) 24.3850 ++ { 24.3851 ++ wchar_t wc; 24.3852 ++ mbstate_t state; 24.3853 ++ 24.3854 ++ memset (&state, '\0', sizeof (mbstate_t)); 24.3855 ++ newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, 24.3856 ++ MB_LEN_MAX), 24.3857 ++ &state); 24.3858 ++ switch (newtab_length) 24.3859 ++ { 24.3860 ++ case (size_t) -1: 24.3861 ++ case (size_t) -2: 24.3862 ++ case 0: 24.3863 ++ newtab_length = 1; 24.3864 ++ } 24.3865 ++ } 24.3866 ++#endif 24.3867 ++ if (newtab_length == 1 && optarg[1]) 24.3868 + { 24.3869 + if (STREQ (optarg, "\\0")) 24.3870 +- newtab = '\0'; 24.3871 ++ newtab[0] = '\0'; 24.3872 + else 24.3873 + { 24.3874 + /* Provoke with 'sort -txx'. Complain about 24.3875 +@@ -4530,9 +5218,11 @@ main (int argc, char **argv) 24.3876 + quote (optarg)); 24.3877 + } 24.3878 + } 24.3879 +- if (tab != TAB_DEFAULT && tab != newtab) 24.3880 ++ if (tab_length && (tab_length != newtab_length 24.3881 ++ || memcmp (tab, newtab, tab_length) != 0)) 24.3882 + die (SORT_FAILURE, 0, _("incompatible tabs")); 24.3883 +- tab = newtab; 24.3884 ++ memcpy (tab, newtab, newtab_length); 24.3885 ++ tab_length = newtab_length; 24.3886 + } 24.3887 + break; 24.3888 + 24.3889 +@@ -4770,12 +5460,10 @@ main (int argc, char **argv) 24.3890 + sort (files, nfiles, outfile, nthreads); 24.3891 + } 24.3892 + 24.3893 +-#ifdef lint 24.3894 + if (files_from) 24.3895 + readtokens0_free (&tok); 24.3896 + else 24.3897 + free (files); 24.3898 +-#endif 24.3899 + 24.3900 + if (have_read_stdin && fclose (stdin) == EOF) 24.3901 + sort_die (_("close failed"), "-"); 24.3902 +diff -Naurp coreutils-8.27-orig/src/unexpand.c coreutils-8.27/src/unexpand.c 24.3903 +--- coreutils-8.27-orig/src/unexpand.c 2017-01-01 16:34:24.000000000 -0600 24.3904 ++++ coreutils-8.27/src/unexpand.c 2017-03-11 23:49:06.758133530 -0600 24.3905 +@@ -38,6 +38,9 @@ 24.3906 + #include <stdio.h> 24.3907 + #include <getopt.h> 24.3908 + #include <sys/types.h> 24.3909 ++ 24.3910 ++#include <mbfile.h> 24.3911 ++ 24.3912 + #include "system.h" 24.3913 + #include "die.h" 24.3914 + #include "xstrndup.h" 24.3915 +@@ -107,24 +110,47 @@ unexpand (void) 24.3916 + { 24.3917 + /* Input stream. */ 24.3918 + FILE *fp = next_file (NULL); 24.3919 ++ mb_file_t mbf; 24.3920 + 24.3921 + /* The array of pending blanks. In non-POSIX locales, blanks can 24.3922 + include characters other than spaces, so the blanks must be 24.3923 + stored, not merely counted. */ 24.3924 +- char *pending_blank; 24.3925 ++ mbf_char_t *pending_blank; 24.3926 ++ /* True if the starting locale is utf8. */ 24.3927 ++ bool using_utf_locale; 24.3928 ++ 24.3929 ++ /* True if the first file contains BOM header. */ 24.3930 ++ bool found_bom; 24.3931 ++ using_utf_locale=check_utf_locale(); 24.3932 + 24.3933 + if (!fp) 24.3934 + return; 24.3935 ++ mbf_init (mbf, fp); 24.3936 ++ found_bom=check_bom(fp,&mbf); 24.3937 + 24.3938 ++ if (using_utf_locale == false && found_bom == true) 24.3939 ++ { 24.3940 ++ /*try using some predefined locale */ 24.3941 ++ 24.3942 ++ if (set_utf_locale () != 0) 24.3943 ++ { 24.3944 ++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); 24.3945 ++ } 24.3946 ++ } 24.3947 + /* The worst case is a non-blank character, then one blank, then a 24.3948 + tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so 24.3949 + allocate MAX_COLUMN_WIDTH bytes to store the blanks. */ 24.3950 +- pending_blank = xmalloc (max_column_width); 24.3951 ++ pending_blank = xmalloc (max_column_width * sizeof (mbf_char_t)); 24.3952 ++ 24.3953 ++ if (found_bom == true) 24.3954 ++ { 24.3955 ++ print_bom(); 24.3956 ++ } 24.3957 + 24.3958 + while (true) 24.3959 + { 24.3960 + /* Input character, or EOF. */ 24.3961 +- int c; 24.3962 ++ mbf_char_t c; 24.3963 + 24.3964 + /* If true, perform translations. */ 24.3965 + bool convert = true; 24.3966 +@@ -158,12 +184,44 @@ unexpand (void) 24.3967 + 24.3968 + do 24.3969 + { 24.3970 +- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) 24.3971 +- continue; 24.3972 ++ while (true) { 24.3973 ++ mbf_getc (c, mbf); 24.3974 ++ if ((mb_iseof (c)) && (fp = next_file (fp))) 24.3975 ++ { 24.3976 ++ mbf_init (mbf, fp); 24.3977 ++ if (fp!=NULL) 24.3978 ++ { 24.3979 ++ if (check_bom(fp,&mbf)==true) 24.3980 ++ { 24.3981 ++ /*Not the first file - check BOM header*/ 24.3982 ++ if (using_utf_locale==false && found_bom==false) 24.3983 ++ { 24.3984 ++ /*BOM header in subsequent file but not in the first one. */ 24.3985 ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); 24.3986 ++ } 24.3987 ++ } 24.3988 ++ else 24.3989 ++ { 24.3990 ++ if(using_utf_locale==false && found_bom==true) 24.3991 ++ { 24.3992 ++ /*First file conatined BOM header - locale was switched to UTF 24.3993 ++ /*all subsequent files should contain BOM. */ 24.3994 ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); 24.3995 ++ } 24.3996 ++ } 24.3997 ++ } 24.3998 ++ continue; 24.3999 ++ } 24.4000 ++ else 24.4001 ++ { 24.4002 ++ break; 24.4003 ++ } 24.4004 ++ } 24.4005 ++ 24.4006 + 24.4007 + if (convert) 24.4008 + { 24.4009 +- bool blank = !! isblank (c); 24.4010 ++ bool blank = mb_isblank (c); 24.4011 + 24.4012 + if (blank) 24.4013 + { 24.4014 +@@ -180,16 +238,16 @@ unexpand (void) 24.4015 + if (next_tab_column < column) 24.4016 + die (EXIT_FAILURE, 0, _("input line is too long")); 24.4017 + 24.4018 +- if (c == '\t') 24.4019 ++ if (mb_iseq (c, '\t')) 24.4020 + { 24.4021 + column = next_tab_column; 24.4022 + 24.4023 + if (pending) 24.4024 +- pending_blank[0] = '\t'; 24.4025 ++ mb_setascii (&pending_blank[0], '\t'); 24.4026 + } 24.4027 + else 24.4028 + { 24.4029 +- column++; 24.4030 ++ column += mb_width (c); 24.4031 + 24.4032 + if (! (prev_blank && column == next_tab_column)) 24.4033 + { 24.4034 +@@ -197,13 +255,14 @@ unexpand (void) 24.4035 + will be replaced by tabs. */ 24.4036 + if (column == next_tab_column) 24.4037 + one_blank_before_tab_stop = true; 24.4038 +- pending_blank[pending++] = c; 24.4039 ++ mb_copy (&pending_blank[pending++], &c); 24.4040 + prev_blank = true; 24.4041 + continue; 24.4042 + } 24.4043 + 24.4044 + /* Replace the pending blanks by a tab or two. */ 24.4045 +- pending_blank[0] = c = '\t'; 24.4046 ++ mb_setascii (&c, '\t'); 24.4047 ++ mb_setascii (&pending_blank[0], '\t'); 24.4048 + } 24.4049 + 24.4050 + /* Discard pending blanks, unless it was a single 24.4051 +@@ -211,7 +270,7 @@ unexpand (void) 24.4052 + pending = one_blank_before_tab_stop; 24.4053 + } 24.4054 + } 24.4055 +- else if (c == '\b') 24.4056 ++ else if (mb_iseq (c, '\b')) 24.4057 + { 24.4058 + /* Go back one column, and force recalculation of the 24.4059 + next tab stop. */ 24.4060 +@@ -219,9 +278,9 @@ unexpand (void) 24.4061 + next_tab_column = column; 24.4062 + tab_index -= !!tab_index; 24.4063 + } 24.4064 +- else 24.4065 ++ else if (!mb_iseq (c, '\n')) 24.4066 + { 24.4067 +- column++; 24.4068 ++ column += mb_width (c); 24.4069 + if (!column) 24.4070 + die (EXIT_FAILURE, 0, _("input line is too long")); 24.4071 + } 24.4072 +@@ -229,8 +288,11 @@ unexpand (void) 24.4073 + if (pending) 24.4074 + { 24.4075 + if (pending > 1 && one_blank_before_tab_stop) 24.4076 +- pending_blank[0] = '\t'; 24.4077 +- if (fwrite (pending_blank, 1, pending, stdout) != pending) 24.4078 ++ mb_setascii (&pending_blank[0], '\t'); 24.4079 ++ 24.4080 ++ for (int n = 0; n < pending; ++n) 24.4081 ++ mb_putc (pending_blank[n], stdout); 24.4082 ++ if (ferror (stdout)) 24.4083 + die (EXIT_FAILURE, errno, _("write error")); 24.4084 + pending = 0; 24.4085 + one_blank_before_tab_stop = false; 24.4086 +@@ -240,16 +302,17 @@ unexpand (void) 24.4087 + convert &= convert_entire_line || blank; 24.4088 + } 24.4089 + 24.4090 +- if (c < 0) 24.4091 ++ if (mb_iseof (c)) 24.4092 + { 24.4093 + free (pending_blank); 24.4094 + return; 24.4095 + } 24.4096 + 24.4097 +- if (putchar (c) < 0) 24.4098 ++ mb_putc (c, stdout); 24.4099 ++ if (ferror (stdout)) 24.4100 + die (EXIT_FAILURE, errno, _("write error")); 24.4101 + } 24.4102 +- while (c != '\n'); 24.4103 ++ while (!mb_iseq (c, '\n')); 24.4104 + } 24.4105 + } 24.4106 + 24.4107 +diff -Naurp coreutils-8.27-orig/src/uniq.c coreutils-8.27/src/uniq.c 24.4108 +--- coreutils-8.27-orig/src/uniq.c 2017-01-01 16:34:24.000000000 -0600 24.4109 ++++ coreutils-8.27/src/uniq.c 2017-03-11 23:47:13.098285938 -0600 24.4110 +@@ -21,6 +21,17 @@ 24.4111 + #include <getopt.h> 24.4112 + #include <sys/types.h> 24.4113 + 24.4114 ++/* Get mbstate_t, mbrtowc(). */ 24.4115 ++#if HAVE_WCHAR_H 24.4116 ++# include <wchar.h> 24.4117 ++#endif 24.4118 ++ 24.4119 ++/* Get isw* functions. */ 24.4120 ++#if HAVE_WCTYPE_H 24.4121 ++# include <wctype.h> 24.4122 ++#endif 24.4123 ++#include <assert.h> 24.4124 ++ 24.4125 + #include "system.h" 24.4126 + #include "argmatch.h" 24.4127 + #include "linebuffer.h" 24.4128 +@@ -32,9 +43,21 @@ 24.4129 + #include "stdio--.h" 24.4130 + #include "xmemcoll.h" 24.4131 + #include "xstrtol.h" 24.4132 +-#include "memcasecmp.h" 24.4133 ++#include "xmemcoll.h" 24.4134 + #include "quote.h" 24.4135 + 24.4136 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 24.4137 ++ installation; work around this configuration error. */ 24.4138 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 24.4139 ++# define MB_LEN_MAX 16 24.4140 ++#endif 24.4141 ++ 24.4142 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 24.4143 ++#if HAVE_MBRTOWC && defined mbstate_t 24.4144 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 24.4145 ++#endif 24.4146 ++ 24.4147 ++ 24.4148 + /* The official name of this program (e.g., no 'g' prefix). */ 24.4149 + #define PROGRAM_NAME "uniq" 24.4150 + 24.4151 +@@ -144,6 +167,10 @@ enum 24.4152 + GROUP_OPTION = CHAR_MAX + 1 24.4153 + }; 24.4154 + 24.4155 ++/* Function pointers. */ 24.4156 ++static char * 24.4157 ++(*find_field) (struct linebuffer *line); 24.4158 ++ 24.4159 + static struct option const longopts[] = 24.4160 + { 24.4161 + {"count", no_argument, NULL, 'c'}, 24.4162 +@@ -260,7 +287,7 @@ size_opt (char const *opt, char const *m 24.4163 + return a pointer to the beginning of the line's field to be compared. */ 24.4164 + 24.4165 + static char * _GL_ATTRIBUTE_PURE 24.4166 +-find_field (struct linebuffer const *line) 24.4167 ++find_field_uni (struct linebuffer *line) 24.4168 + { 24.4169 + size_t count; 24.4170 + char const *lp = line->buffer; 24.4171 +@@ -280,6 +307,83 @@ find_field (struct linebuffer const *lin 24.4172 + return line->buffer + i; 24.4173 + } 24.4174 + 24.4175 ++#if HAVE_MBRTOWC 24.4176 ++ 24.4177 ++# define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL) \ 24.4178 ++ do \ 24.4179 ++ { \ 24.4180 ++ mbstate_t state_bak; \ 24.4181 ++ \ 24.4182 ++ CONVFAIL = 0; \ 24.4183 ++ state_bak = *STATEP; \ 24.4184 ++ \ 24.4185 ++ MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP); \ 24.4186 ++ \ 24.4187 ++ switch (MBLENGTH) \ 24.4188 ++ { \ 24.4189 ++ case (size_t)-2: \ 24.4190 ++ case (size_t)-1: \ 24.4191 ++ *STATEP = state_bak; \ 24.4192 ++ CONVFAIL++; \ 24.4193 ++ /* Fall through */ \ 24.4194 ++ case 0: \ 24.4195 ++ MBLENGTH = 1; \ 24.4196 ++ } \ 24.4197 ++ } \ 24.4198 ++ while (0) 24.4199 ++ 24.4200 ++static char * 24.4201 ++find_field_multi (struct linebuffer *line) 24.4202 ++{ 24.4203 ++ size_t count; 24.4204 ++ char *lp = line->buffer; 24.4205 ++ size_t size = line->length - 1; 24.4206 ++ size_t pos; 24.4207 ++ size_t mblength; 24.4208 ++ wchar_t wc; 24.4209 ++ mbstate_t *statep; 24.4210 ++ int convfail = 0; 24.4211 ++ 24.4212 ++ pos = 0; 24.4213 ++ statep = &(line->state); 24.4214 ++ 24.4215 ++ /* skip fields. */ 24.4216 ++ for (count = 0; count < skip_fields && pos < size; count++) 24.4217 ++ { 24.4218 ++ while (pos < size) 24.4219 ++ { 24.4220 ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 24.4221 ++ 24.4222 ++ if (convfail || !(iswblank (wc) || wc == '\n')) 24.4223 ++ { 24.4224 ++ pos += mblength; 24.4225 ++ break; 24.4226 ++ } 24.4227 ++ pos += mblength; 24.4228 ++ } 24.4229 ++ 24.4230 ++ while (pos < size) 24.4231 ++ { 24.4232 ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 24.4233 ++ 24.4234 ++ if (!convfail && (iswblank (wc) || wc == '\n')) 24.4235 ++ break; 24.4236 ++ 24.4237 ++ pos += mblength; 24.4238 ++ } 24.4239 ++ } 24.4240 ++ 24.4241 ++ /* skip fields. */ 24.4242 ++ for (count = 0; count < skip_chars && pos < size; count++) 24.4243 ++ { 24.4244 ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 24.4245 ++ pos += mblength; 24.4246 ++ } 24.4247 ++ 24.4248 ++ return lp + pos; 24.4249 ++} 24.4250 ++#endif 24.4251 ++ 24.4252 + /* Return false if two strings OLD and NEW match, true if not. 24.4253 + OLD and NEW point not to the beginnings of the lines 24.4254 + but rather to the beginnings of the fields to compare. 24.4255 +@@ -288,6 +392,8 @@ find_field (struct linebuffer const *lin 24.4256 + static bool 24.4257 + different (char *old, char *new, size_t oldlen, size_t newlen) 24.4258 + { 24.4259 ++ char *copy_old, *copy_new; 24.4260 ++ 24.4261 + if (check_chars < oldlen) 24.4262 + oldlen = check_chars; 24.4263 + if (check_chars < newlen) 24.4264 +@@ -295,14 +401,103 @@ different (char *old, char *new, size_t 24.4265 + 24.4266 + if (ignore_case) 24.4267 + { 24.4268 +- /* FIXME: This should invoke strcoll somehow. */ 24.4269 +- return oldlen != newlen || memcasecmp (old, new, oldlen); 24.4270 ++ size_t i; 24.4271 ++ 24.4272 ++ copy_old = xmalloc (oldlen + 1); 24.4273 ++ copy_new = xmalloc (oldlen + 1); 24.4274 ++ 24.4275 ++ for (i = 0; i < oldlen; i++) 24.4276 ++ { 24.4277 ++ copy_old[i] = toupper (old[i]); 24.4278 ++ copy_new[i] = toupper (new[i]); 24.4279 ++ } 24.4280 ++ bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen); 24.4281 ++ free (copy_old); 24.4282 ++ free (copy_new); 24.4283 ++ return rc; 24.4284 + } 24.4285 +- else if (hard_LC_COLLATE) 24.4286 +- return xmemcoll (old, oldlen, new, newlen) != 0; 24.4287 + else 24.4288 +- return oldlen != newlen || memcmp (old, new, oldlen); 24.4289 ++ { 24.4290 ++ copy_old = (char *)old; 24.4291 ++ copy_new = (char *)new; 24.4292 ++ } 24.4293 ++ 24.4294 ++ return xmemcoll (copy_old, oldlen, copy_new, newlen); 24.4295 ++ 24.4296 ++} 24.4297 ++ 24.4298 ++#if HAVE_MBRTOWC 24.4299 ++static int 24.4300 ++different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) 24.4301 ++{ 24.4302 ++ size_t i, j, chars; 24.4303 ++ const char *str[2]; 24.4304 ++ char *copy[2]; 24.4305 ++ size_t len[2]; 24.4306 ++ mbstate_t state[2]; 24.4307 ++ size_t mblength; 24.4308 ++ wchar_t wc, uwc; 24.4309 ++ mbstate_t state_bak; 24.4310 ++ 24.4311 ++ str[0] = old; 24.4312 ++ str[1] = new; 24.4313 ++ len[0] = oldlen; 24.4314 ++ len[1] = newlen; 24.4315 ++ state[0] = oldstate; 24.4316 ++ state[1] = newstate; 24.4317 ++ 24.4318 ++ for (i = 0; i < 2; i++) 24.4319 ++ { 24.4320 ++ copy[i] = xmalloc (len[i] + 1); 24.4321 ++ memset (copy[i], '\0', len[i] + 1); 24.4322 ++ 24.4323 ++ for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) 24.4324 ++ { 24.4325 ++ state_bak = state[i]; 24.4326 ++ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); 24.4327 ++ 24.4328 ++ switch (mblength) 24.4329 ++ { 24.4330 ++ case (size_t)-1: 24.4331 ++ case (size_t)-2: 24.4332 ++ state[i] = state_bak; 24.4333 ++ /* Fall through */ 24.4334 ++ case 0: 24.4335 ++ mblength = 1; 24.4336 ++ break; 24.4337 ++ 24.4338 ++ default: 24.4339 ++ if (ignore_case) 24.4340 ++ { 24.4341 ++ uwc = towupper (wc); 24.4342 ++ 24.4343 ++ if (uwc != wc) 24.4344 ++ { 24.4345 ++ mbstate_t state_wc; 24.4346 ++ size_t mblen; 24.4347 ++ 24.4348 ++ memset (&state_wc, '\0', sizeof(mbstate_t)); 24.4349 ++ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); 24.4350 ++ assert (mblen != (size_t)-1); 24.4351 ++ } 24.4352 ++ else 24.4353 ++ memcpy (copy[i] + j, str[i] + j, mblength); 24.4354 ++ } 24.4355 ++ else 24.4356 ++ memcpy (copy[i] + j, str[i] + j, mblength); 24.4357 ++ } 24.4358 ++ j += mblength; 24.4359 ++ } 24.4360 ++ copy[i][j] = '\0'; 24.4361 ++ len[i] = j; 24.4362 ++ } 24.4363 ++ int rc = xmemcoll (copy[0], len[0], copy[1], len[1]); 24.4364 ++ free (copy[0]); 24.4365 ++ free (copy[1]); 24.4366 ++ return rc; 24.4367 ++ 24.4368 + } 24.4369 ++#endif 24.4370 + 24.4371 + /* Output the line in linebuffer LINE to standard output 24.4372 + provided that the switches say it should be output. 24.4373 +@@ -367,19 +562,38 @@ check_file (const char *infile, const ch 24.4374 + char *prevfield IF_LINT ( = NULL); 24.4375 + size_t prevlen IF_LINT ( = 0); 24.4376 + bool first_group_printed = false; 24.4377 ++#if HAVE_MBRTOWC 24.4378 ++ mbstate_t prevstate; 24.4379 ++ 24.4380 ++ memset (&prevstate, '\0', sizeof (mbstate_t)); 24.4381 ++#endif 24.4382 + 24.4383 + while (!feof (stdin)) 24.4384 + { 24.4385 + char *thisfield; 24.4386 + size_t thislen; 24.4387 + bool new_group; 24.4388 ++#if HAVE_MBRTOWC 24.4389 ++ mbstate_t thisstate; 24.4390 ++#endif 24.4391 + 24.4392 + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) 24.4393 + break; 24.4394 + 24.4395 + thisfield = find_field (thisline); 24.4396 + thislen = thisline->length - 1 - (thisfield - thisline->buffer); 24.4397 ++#if HAVE_MBRTOWC 24.4398 ++ if (MB_CUR_MAX > 1) 24.4399 ++ { 24.4400 ++ thisstate = thisline->state; 24.4401 + 24.4402 ++ new_group = (prevline->length == 0 24.4403 ++ || different_multi (thisfield, prevfield, 24.4404 ++ thislen, prevlen, 24.4405 ++ thisstate, prevstate)); 24.4406 ++ } 24.4407 ++ else 24.4408 ++#endif 24.4409 + new_group = (prevline->length == 0 24.4410 + || different (thisfield, prevfield, thislen, prevlen)); 24.4411 + 24.4412 +@@ -397,6 +611,10 @@ check_file (const char *infile, const ch 24.4413 + SWAP_LINES (prevline, thisline); 24.4414 + prevfield = thisfield; 24.4415 + prevlen = thislen; 24.4416 ++#if HAVE_MBRTOWC 24.4417 ++ if (MB_CUR_MAX > 1) 24.4418 ++ prevstate = thisstate; 24.4419 ++#endif 24.4420 + first_group_printed = true; 24.4421 + } 24.4422 + } 24.4423 +@@ -409,17 +627,26 @@ check_file (const char *infile, const ch 24.4424 + size_t prevlen; 24.4425 + uintmax_t match_count = 0; 24.4426 + bool first_delimiter = true; 24.4427 ++#if HAVE_MBRTOWC 24.4428 ++ mbstate_t prevstate; 24.4429 ++#endif 24.4430 + 24.4431 + if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) 24.4432 + goto closefiles; 24.4433 + prevfield = find_field (prevline); 24.4434 + prevlen = prevline->length - 1 - (prevfield - prevline->buffer); 24.4435 ++#if HAVE_MBRTOWC 24.4436 ++ prevstate = prevline->state; 24.4437 ++#endif 24.4438 + 24.4439 + while (!feof (stdin)) 24.4440 + { 24.4441 + bool match; 24.4442 + char *thisfield; 24.4443 + size_t thislen; 24.4444 ++#if HAVE_MBRTOWC 24.4445 ++ mbstate_t thisstate = thisline->state; 24.4446 ++#endif 24.4447 + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) 24.4448 + { 24.4449 + if (ferror (stdin)) 24.4450 +@@ -428,6 +655,14 @@ check_file (const char *infile, const ch 24.4451 + } 24.4452 + thisfield = find_field (thisline); 24.4453 + thislen = thisline->length - 1 - (thisfield - thisline->buffer); 24.4454 ++#if HAVE_MBRTOWC 24.4455 ++ if (MB_CUR_MAX > 1) 24.4456 ++ { 24.4457 ++ match = !different_multi (thisfield, prevfield, 24.4458 ++ thislen, prevlen, thisstate, prevstate); 24.4459 ++ } 24.4460 ++ else 24.4461 ++#endif 24.4462 + match = !different (thisfield, prevfield, thislen, prevlen); 24.4463 + match_count += match; 24.4464 + 24.4465 +@@ -460,6 +695,9 @@ check_file (const char *infile, const ch 24.4466 + SWAP_LINES (prevline, thisline); 24.4467 + prevfield = thisfield; 24.4468 + prevlen = thislen; 24.4469 ++#if HAVE_MBRTOWC 24.4470 ++ prevstate = thisstate; 24.4471 ++#endif 24.4472 + if (!match) 24.4473 + match_count = 0; 24.4474 + } 24.4475 +@@ -506,6 +744,19 @@ main (int argc, char **argv) 24.4476 + 24.4477 + atexit (close_stdout); 24.4478 + 24.4479 ++#if HAVE_MBRTOWC 24.4480 ++ if (MB_CUR_MAX > 1) 24.4481 ++ { 24.4482 ++ find_field = find_field_multi; 24.4483 ++ } 24.4484 ++ else 24.4485 ++#endif 24.4486 ++ { 24.4487 ++ find_field = find_field_uni; 24.4488 ++ } 24.4489 ++ 24.4490 ++ 24.4491 ++ 24.4492 + skip_chars = 0; 24.4493 + skip_fields = 0; 24.4494 + check_chars = SIZE_MAX; 24.4495 +diff -Naurp coreutils-8.27-orig/tests/expand/mb.sh coreutils-8.27/tests/expand/mb.sh 24.4496 +--- coreutils-8.27-orig/tests/expand/mb.sh 1969-12-31 18:00:00.000000000 -0600 24.4497 ++++ coreutils-8.27/tests/expand/mb.sh 2017-03-11 23:49:06.759133489 -0600 24.4498 +@@ -0,0 +1,183 @@ 24.4499 ++#!/bin/sh 24.4500 ++ 24.4501 ++# Copyright (C) 2012-2017 Free Software Foundation, Inc. 24.4502 ++ 24.4503 ++# This program is free software: you can redistribute it and/or modify 24.4504 ++# it under the terms of the GNU General Public License as published by 24.4505 ++# the Free Software Foundation, either version 3 of the License, or 24.4506 ++# (at your option) any later version. 24.4507 ++ 24.4508 ++# This program is distributed in the hope that it will be useful, 24.4509 ++# but WITHOUT ANY WARRANTY; without even the implied warranty of 24.4510 ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24.4511 ++# GNU General Public License for more details. 24.4512 ++ 24.4513 ++# You should have received a copy of the GNU General Public License 24.4514 ++# along with this program. If not, see <http://www.gnu.org/licenses/>. 24.4515 ++ 24.4516 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 24.4517 ++print_ver_ expand 24.4518 ++ 24.4519 ++export LC_ALL=en_US.UTF-8 24.4520 ++ 24.4521 ++#input containing multibyte characters 24.4522 ++cat <<\EOF > in || framework_failure_ 24.4523 ++1234567812345678123456781 24.4524 ++. . . . 24.4525 ++a b c d 24.4526 ++. . . . 24.4527 ++ä ö ü ß 24.4528 ++. . . . 24.4529 ++EOF 24.4530 ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ 24.4531 ++ 24.4532 ++cat <<\EOF > exp || framework_failure_ 24.4533 ++1234567812345678123456781 24.4534 ++. . . . 24.4535 ++a b c d 24.4536 ++. . . . 24.4537 ++ä ö ü ß 24.4538 ++. . . . 24.4539 ++ äöü . öüä. ä xx 24.4540 ++EOF 24.4541 ++ 24.4542 ++expand < in > out || fail=1 24.4543 ++compare exp out > /dev/null 2>&1 || fail=1 24.4544 ++ 24.4545 ++#multiple files as an input 24.4546 ++cat <<\EOF >> exp || framework_failure_ 24.4547 ++1234567812345678123456781 24.4548 ++. . . . 24.4549 ++a b c d 24.4550 ++. . . . 24.4551 ++ä ö ü ß 24.4552 ++. . . . 24.4553 ++ äöü . öüä. ä xx 24.4554 ++EOF 24.4555 ++ 24.4556 ++expand ./in ./in > out || fail=1 24.4557 ++compare exp out > /dev/null 2>&1 || fail=1 24.4558 ++ 24.4559 ++#test characters with display widths != 1 24.4560 ++env printf '12345678 24.4561 ++e\t|ascii(1) 24.4562 ++\u00E9\t|composed(1) 24.4563 ++e\u0301\t|decomposed(1) 24.4564 ++\u3000\t|ideo-space(2) 24.4565 ++\uFF0D\t|full-hypen(2) 24.4566 ++' > in || framework_failure_ 24.4567 ++ 24.4568 ++env printf '12345678 24.4569 ++e |ascii(1) 24.4570 ++\u00E9 |composed(1) 24.4571 ++e\u0301 |decomposed(1) 24.4572 ++\u3000 |ideo-space(2) 24.4573 ++\uFF0D |full-hypen(2) 24.4574 ++' > exp || framework_failure_ 24.4575 ++ 24.4576 ++expand < in > out || fail=1 24.4577 ++compare exp out > /dev/null 2>&1 || fail=1 24.4578 ++ 24.4579 ++#shouldn't fail with "input line too long" 24.4580 ++#when a line starts with a control character 24.4581 ++env printf '\n' > in || framework_failure_ 24.4582 ++ 24.4583 ++expand < in > out || fail=1 24.4584 ++compare in out > /dev/null 2>&1 || fail=1 24.4585 ++ 24.4586 ++#non-Unicode characters interspersed between Unicode ones 24.4587 ++env printf '12345678 24.4588 ++\t\xFF| 24.4589 ++\xFF\t| 24.4590 ++\t\xFFä| 24.4591 ++ä\xFF\t| 24.4592 ++\tä\xFF| 24.4593 ++\xFF\tä| 24.4594 ++äbcdef\xFF\t| 24.4595 ++' > in || framework_failure_ 24.4596 ++ 24.4597 ++env printf '12345678 24.4598 ++ \xFF| 24.4599 ++\xFF | 24.4600 ++ \xFFä| 24.4601 ++ä\xFF | 24.4602 ++ ä\xFF| 24.4603 ++\xFF ä| 24.4604 ++äbcdef\xFF | 24.4605 ++' > exp || framework_failure_ 24.4606 ++ 24.4607 ++expand < in > out || fail=1 24.4608 ++compare exp out > /dev/null 2>&1 || fail=1 24.4609 ++ 24.4610 ++ 24.4611 ++ 24.4612 ++#BOM header test 1 24.4613 ++printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ 24.4614 ++1234567812345678123456781 24.4615 ++. . . . 24.4616 ++a b c d 24.4617 ++. . . . 24.4618 ++ä ö ü ß 24.4619 ++. . . . 24.4620 ++EOF 24.4621 ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ 24.4622 ++ 24.4623 ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ 24.4624 ++1234567812345678123456781 24.4625 ++. . . . 24.4626 ++a b c d 24.4627 ++. . . . 24.4628 ++ä ö ü ß 24.4629 ++. . . . 24.4630 ++ äöü . öüä. ä xx 24.4631 ++EOF 24.4632 ++ 24.4633 ++ 24.4634 ++expand < in > out || fail=1 24.4635 ++compare exp out > /dev/null 2>&1 || fail=1 24.4636 ++ 24.4637 ++LANG=C expand < in > out || fail=1 24.4638 ++compare exp out > /dev/null 2>&1 || fail=1 24.4639 ++ 24.4640 ++LC_ALL=C expand < in > out || fail=1 24.4641 ++compare exp out > /dev/null 2>&1 || fail=1 24.4642 ++ 24.4643 ++ 24.4644 ++printf '\xEF\xBB\xBF' > in1; cat <<\EOF >> in1 || framework_failure_ 24.4645 ++1234567812345678123456781 24.4646 ++. . . . 24.4647 ++a b c d 24.4648 ++. . . . 24.4649 ++ä ö ü ß 24.4650 ++. . . . 24.4651 ++EOF 24.4652 ++env printf ' äöü\t. öüä. \tä xx\n' >> in1 || framework_failure_ 24.4653 ++ 24.4654 ++ 24.4655 ++printf '\xEF\xBB\xBF' > exp; cat <<\EOF >> exp || framework_failure_ 24.4656 ++1234567812345678123456781 24.4657 ++. . . . 24.4658 ++a b c d 24.4659 ++. . . . 24.4660 ++ä ö ü ß 24.4661 ++. . . . 24.4662 ++ äöü . öüä. ä xx 24.4663 ++1234567812345678123456781 24.4664 ++. . . . 24.4665 ++a b c d 24.4666 ++. . . . 24.4667 ++ä ö ü ß 24.4668 ++. . . . 24.4669 ++ äöü . öüä. ä xx 24.4670 ++EOF 24.4671 ++ 24.4672 ++expand in1 in1 > out || fail=1 24.4673 ++compare exp out > /dev/null 2>&1 || fail=1 24.4674 ++ 24.4675 ++LANG=C expand in1 in1 > out || fail=1 24.4676 ++compare exp out > /dev/null 2>&1 || fail=1 24.4677 ++ 24.4678 ++LC_ALL=C expand in1 in1 > out || fail=1 24.4679 ++compare exp out > /dev/null 2>&1 || fail=1 24.4680 ++ 24.4681 ++exit $fail 24.4682 +diff -Naurp coreutils-8.27-orig/tests/i18n/sort.sh coreutils-8.27/tests/i18n/sort.sh 24.4683 +--- coreutils-8.27-orig/tests/i18n/sort.sh 1969-12-31 18:00:00.000000000 -0600 24.4684 ++++ coreutils-8.27/tests/i18n/sort.sh 2017-03-11 23:47:13.100285838 -0600 24.4685 +@@ -0,0 +1,29 @@ 24.4686 ++#!/bin/sh 24.4687 ++# Verify sort's multi-byte support. 24.4688 ++ 24.4689 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 24.4690 ++print_ver_ sort 24.4691 ++ 24.4692 ++export LC_ALL=en_US.UTF-8 24.4693 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 24.4694 ++ || skip_ "No UTF-8 locale available" 24.4695 ++ 24.4696 ++# Enable heap consistency checkng on older systems 24.4697 ++export MALLOC_CHECK_=2 24.4698 ++ 24.4699 ++ 24.4700 ++# check buffer overflow issue due to 24.4701 ++# expanding multi-byte representation due to case conversion 24.4702 ++# https://bugzilla.suse.com/show_bug.cgi?id=928749 24.4703 ++cat <<EOF > exp 24.4704 ++. 24.4705 ++ɑ 24.4706 ++EOF 24.4707 ++cat <<EOF | sort -f > out || fail=1 24.4708 ++. 24.4709 ++ɑ 24.4710 ++EOF 24.4711 ++compare exp out || { fail=1; cat out; } 24.4712 ++ 24.4713 ++ 24.4714 ++Exit $fail 24.4715 +diff -Naurp coreutils-8.27-orig/tests/local.mk coreutils-8.27/tests/local.mk 24.4716 +--- coreutils-8.27-orig/tests/local.mk 2017-02-28 22:25:37.000000000 -0600 24.4717 ++++ coreutils-8.27/tests/local.mk 2017-03-11 23:47:38.072058253 -0600 24.4718 +@@ -352,6 +352,8 @@ all_tests = \ 24.4719 + tests/misc/sort-discrim.sh \ 24.4720 + tests/misc/sort-files0-from.pl \ 24.4721 + tests/misc/sort-float.sh \ 24.4722 ++ tests/misc/sort-mb-tests.sh \ 24.4723 ++ tests/i18n/sort.sh \ 24.4724 + tests/misc/sort-h-thousands-sep.sh \ 24.4725 + tests/misc/sort-merge.pl \ 24.4726 + tests/misc/sort-merge-fdlimit.sh \ 24.4727 +@@ -544,6 +546,7 @@ all_tests = \ 24.4728 + tests/du/threshold.sh \ 24.4729 + tests/du/trailing-slash.sh \ 24.4730 + tests/du/two-args.sh \ 24.4731 ++ tests/expand/mb.sh \ 24.4732 + tests/id/gnu-zero-uids.sh \ 24.4733 + tests/id/no-context.sh \ 24.4734 + tests/id/context.sh \ 24.4735 +@@ -684,6 +687,7 @@ all_tests = \ 24.4736 + tests/touch/read-only.sh \ 24.4737 + tests/touch/relative.sh \ 24.4738 + tests/touch/trailing-slash.sh \ 24.4739 ++ tests/unexpand/mb.sh \ 24.4740 + $(all_root_tests) 24.4741 + 24.4742 + # See tests/factor/create-test.sh. 24.4743 +diff -Naurp coreutils-8.27-orig/tests/misc/cut.pl coreutils-8.27/tests/misc/cut.pl 24.4744 +--- coreutils-8.27-orig/tests/misc/cut.pl 2017-01-01 16:34:24.000000000 -0600 24.4745 ++++ coreutils-8.27/tests/misc/cut.pl 2017-03-11 23:47:13.100285838 -0600 24.4746 +@@ -23,9 +23,11 @@ use strict; 24.4747 + # Turn off localization of executable's output. 24.4748 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 24.4749 + 24.4750 +-my $mb_locale = $ENV{LOCALE_FR_UTF8}; 24.4751 ++my $mb_locale; 24.4752 ++# uncommented enable multibyte paths 24.4753 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 24.4754 + ! defined $mb_locale || $mb_locale eq 'none' 24.4755 +- and $mb_locale = 'C'; 24.4756 ++ and $mb_locale = 'C'; 24.4757 + 24.4758 + my $prog = 'cut'; 24.4759 + my $try = "Try '$prog --help' for more information.\n"; 24.4760 +@@ -240,6 +242,7 @@ if ($mb_locale ne 'C') 24.4761 + my @new_t = @$t; 24.4762 + my $test_name = shift @new_t; 24.4763 + 24.4764 ++ next if ($test_name =~ "newline-[12][0-9]"); 24.4765 + push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 24.4766 + } 24.4767 + push @Tests, @new; 24.4768 +diff -Naurp coreutils-8.27-orig/tests/misc/expand.pl coreutils-8.27/tests/misc/expand.pl 24.4769 +--- coreutils-8.27-orig/tests/misc/expand.pl 2017-03-01 11:16:46.000000000 -0600 24.4770 ++++ coreutils-8.27/tests/misc/expand.pl 2017-03-11 23:47:13.101285788 -0600 24.4771 +@@ -27,6 +27,15 @@ my $prog = 'expand'; 24.4772 + # Turn off localization of executable's output. 24.4773 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 24.4774 + 24.4775 ++#comment out next line to disable multibyte tests 24.4776 ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; 24.4777 ++! defined $mb_locale || $mb_locale eq 'none' 24.4778 ++ and $mb_locale = 'C'; 24.4779 ++ 24.4780 ++my $prog = 'expand'; 24.4781 ++my $try = "Try \`$prog --help' for more information.\n"; 24.4782 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 24.4783 ++ 24.4784 + my @Tests = 24.4785 + ( 24.4786 + ['t1', '--tabs=3', {IN=>"a\tb"}, {OUT=>"a b"}], 24.4787 +@@ -152,6 +161,8 @@ my @Tests = 24.4788 + ['trail9', '--tab=1,2 -t/5',{IN=>"\ta\tb\tc"}, {OUT=>" a b c"}], 24.4789 + 24.4790 + # Test errors 24.4791 ++ # FIXME: The following tests contain ‘quoting’ specific to LC_MESSAGES 24.4792 ++ # So we force LC_MESSAGES=C to make them pass. 24.4793 + ['e1', '--tabs="a"', {IN=>''}, {OUT=>''}, {EXIT=>1}, 24.4794 + {ERR => "$prog: tab size contains invalid character(s): 'a'\n"}], 24.4795 + ['e2', "-t $UINTMAX_OFLOW", {IN=>''}, {OUT=>''}, {EXIT=>1}, 24.4796 +@@ -168,6 +179,37 @@ my @Tests = 24.4797 + {ERR => "$prog: '/' specifier not at start of number: '/'\n"}], 24.4798 + ); 24.4799 + 24.4800 ++if ($mb_locale ne 'C') 24.4801 ++ { 24.4802 ++ # Duplicate each test vector, appending "-mb" to the test name and 24.4803 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 24.4804 ++ # provide coverage for the distro-added multi-byte code paths. 24.4805 ++ my @new; 24.4806 ++ foreach my $t (@Tests) 24.4807 ++ { 24.4808 ++ my @new_t = @$t; 24.4809 ++ my $test_name = shift @new_t; 24.4810 ++ 24.4811 ++ # Depending on whether expand is multi-byte-patched, 24.4812 ++ # it emits different diagnostics: 24.4813 ++ # non-MB: invalid byte or field list 24.4814 ++ # MB: invalid byte, character or field list 24.4815 ++ # Adjust the expected error output accordingly. 24.4816 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 24.4817 ++ (@new_t)) 24.4818 ++ { 24.4819 ++ my $sub = {ERR_SUBST => 's/, character//'}; 24.4820 ++ push @new_t, $sub; 24.4821 ++ push @$t, $sub; 24.4822 ++ } 24.4823 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LANG=$mb_locale LC_MESSAGES=C"}]; 24.4824 ++ } 24.4825 ++ push @Tests, @new; 24.4826 ++ } 24.4827 ++ 24.4828 ++ 24.4829 ++@Tests = triple_test \@Tests; 24.4830 ++ 24.4831 + my $save_temps = $ENV{DEBUG}; 24.4832 + my $verbose = $ENV{VERBOSE}; 24.4833 + 24.4834 +diff -Naurp coreutils-8.27-orig/tests/misc/fold.pl coreutils-8.27/tests/misc/fold.pl 24.4835 +--- coreutils-8.27-orig/tests/misc/fold.pl 2017-01-01 16:34:24.000000000 -0600 24.4836 ++++ coreutils-8.27/tests/misc/fold.pl 2017-03-11 23:47:13.101285788 -0600 24.4837 +@@ -20,9 +20,18 @@ use strict; 24.4838 + 24.4839 + (my $program_name = $0) =~ s|.*/||; 24.4840 + 24.4841 ++my $prog = 'fold'; 24.4842 ++my $try = "Try \`$prog --help' for more information.\n"; 24.4843 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 24.4844 ++ 24.4845 + # Turn off localization of executable's output. 24.4846 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 24.4847 + 24.4848 ++# uncommented to enable multibyte paths 24.4849 ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; 24.4850 ++! defined $mb_locale || $mb_locale eq 'none' 24.4851 ++ and $mb_locale = 'C'; 24.4852 ++ 24.4853 + my @Tests = 24.4854 + ( 24.4855 + ['s1', '-w2 -s', {IN=>"a\t"}, {OUT=>"a\n\t"}], 24.4856 +@@ -31,9 +40,48 @@ my @Tests = 24.4857 + ['s4', '-w4 -s', {IN=>"abc ef\n"}, {OUT=>"abc \nef\n"}], 24.4858 + ); 24.4859 + 24.4860 ++# Add _POSIX2_VERSION=199209 to the environment of each test 24.4861 ++# that uses an old-style option like +1. 24.4862 ++if ($mb_locale ne 'C') 24.4863 ++ { 24.4864 ++ # Duplicate each test vector, appending "-mb" to the test name and 24.4865 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 24.4866 ++ # provide coverage for the distro-added multi-byte code paths. 24.4867 ++ my @new; 24.4868 ++ foreach my $t (@Tests) 24.4869 ++ { 24.4870 ++ my @new_t = @$t; 24.4871 ++ my $test_name = shift @new_t; 24.4872 ++ 24.4873 ++ # Depending on whether fold is multi-byte-patched, 24.4874 ++ # it emits different diagnostics: 24.4875 ++ # non-MB: invalid byte or field list 24.4876 ++ # MB: invalid byte, character or field list 24.4877 ++ # Adjust the expected error output accordingly. 24.4878 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 24.4879 ++ (@new_t)) 24.4880 ++ { 24.4881 ++ my $sub = {ERR_SUBST => 's/, character//'}; 24.4882 ++ push @new_t, $sub; 24.4883 ++ push @$t, $sub; 24.4884 ++ } 24.4885 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 24.4886 ++ } 24.4887 ++ push @Tests, @new; 24.4888 ++ } 24.4889 ++ 24.4890 ++@Tests = triple_test \@Tests; 24.4891 ++ 24.4892 ++# Remember that triple_test creates from each test with exactly one "IN" 24.4893 ++# file two more tests (.p and .r suffix on name) corresponding to reading 24.4894 ++# input from a file and from a pipe. The pipe-reading test would fail 24.4895 ++# due to a race condition about 1 in 20 times. 24.4896 ++# Remove the IN_PIPE version of the "output-is-input" test above. 24.4897 ++# The others aren't susceptible because they have three inputs each. 24.4898 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 24.4899 ++ 24.4900 + my $save_temps = $ENV{DEBUG}; 24.4901 + my $verbose = $ENV{VERBOSE}; 24.4902 + 24.4903 +-my $prog = 'fold'; 24.4904 + my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); 24.4905 + exit $fail; 24.4906 +diff -Naurp coreutils-8.27-orig/tests/misc/join.pl coreutils-8.27/tests/misc/join.pl 24.4907 +--- coreutils-8.27-orig/tests/misc/join.pl 2017-01-01 16:34:24.000000000 -0600 24.4908 ++++ coreutils-8.27/tests/misc/join.pl 2017-03-11 23:47:13.102285737 -0600 24.4909 +@@ -25,6 +25,15 @@ my $limits = getlimits (); 24.4910 + 24.4911 + my $prog = 'join'; 24.4912 + 24.4913 ++my $try = "Try \`$prog --help' for more information.\n"; 24.4914 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 24.4915 ++ 24.4916 ++my $mb_locale; 24.4917 ++#Comment out next line to disable multibyte tests 24.4918 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 24.4919 ++! defined $mb_locale || $mb_locale eq 'none' 24.4920 ++ and $mb_locale = 'C'; 24.4921 ++ 24.4922 + my $delim = chr 0247; 24.4923 + sub t_subst ($) 24.4924 + { 24.4925 +@@ -329,8 +338,49 @@ foreach my $t (@tv) 24.4926 + push @Tests, $new_ent; 24.4927 + } 24.4928 + 24.4929 ++# Add _POSIX2_VERSION=199209 to the environment of each test 24.4930 ++# that uses an old-style option like +1. 24.4931 ++if ($mb_locale ne 'C') 24.4932 ++ { 24.4933 ++ # Duplicate each test vector, appending "-mb" to the test name and 24.4934 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 24.4935 ++ # provide coverage for the distro-added multi-byte code paths. 24.4936 ++ my @new; 24.4937 ++ foreach my $t (@Tests) 24.4938 ++ { 24.4939 ++ my @new_t = @$t; 24.4940 ++ my $test_name = shift @new_t; 24.4941 ++ 24.4942 ++ # Depending on whether join is multi-byte-patched, 24.4943 ++ # it emits different diagnostics: 24.4944 ++ # non-MB: invalid byte or field list 24.4945 ++ # MB: invalid byte, character or field list 24.4946 ++ # Adjust the expected error output accordingly. 24.4947 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 24.4948 ++ (@new_t)) 24.4949 ++ { 24.4950 ++ my $sub = {ERR_SUBST => 's/, character//'}; 24.4951 ++ push @new_t, $sub; 24.4952 ++ push @$t, $sub; 24.4953 ++ } 24.4954 ++ #Adjust the output some error messages including test_name for mb 24.4955 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR}} 24.4956 ++ (@new_t)) 24.4957 ++ { 24.4958 ++ my $sub2 = {ERR_SUBST => "s/$test_name-mb/$test_name/"}; 24.4959 ++ push @new_t, $sub2; 24.4960 ++ push @$t, $sub2; 24.4961 ++ } 24.4962 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 24.4963 ++ } 24.4964 ++ push @Tests, @new; 24.4965 ++ } 24.4966 ++ 24.4967 + @Tests = triple_test \@Tests; 24.4968 + 24.4969 ++#skip invalid-j-mb test, it is failing because of the format 24.4970 ++@Tests = grep {$_->[0] ne 'invalid-j-mb'} @Tests; 24.4971 ++ 24.4972 + my $save_temps = $ENV{DEBUG}; 24.4973 + my $verbose = $ENV{VERBOSE}; 24.4974 + 24.4975 +diff -Naurp coreutils-8.27-orig/tests/misc/sort-mb-tests.sh coreutils-8.27/tests/misc/sort-mb-tests.sh 24.4976 +--- coreutils-8.27-orig/tests/misc/sort-mb-tests.sh 1969-12-31 18:00:00.000000000 -0600 24.4977 ++++ coreutils-8.27/tests/misc/sort-mb-tests.sh 2017-03-11 23:47:13.102285737 -0600 24.4978 +@@ -0,0 +1,45 @@ 24.4979 ++#!/bin/sh 24.4980 ++# Verify sort's multi-byte support. 24.4981 ++ 24.4982 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 24.4983 ++print_ver_ sort 24.4984 ++ 24.4985 ++export LC_ALL=en_US.UTF-8 24.4986 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 24.4987 ++ || skip_ "No UTF-8 locale available" 24.4988 ++ 24.4989 ++ 24.4990 ++cat <<EOF > exp 24.4991 ++Banana@5 24.4992 ++Apple@10 24.4993 ++Citrus@20 24.4994 ++Cherry@30 24.4995 ++EOF 24.4996 ++ 24.4997 ++cat <<EOF | sort -t @ -k2 -n > out || fail=1 24.4998 ++Apple@10 24.4999 ++Banana@5 24.5000 ++Citrus@20 24.5001 ++Cherry@30 24.5002 ++EOF 24.5003 ++ 24.5004 ++compare exp out || { fail=1; cat out; } 24.5005 ++ 24.5006 ++ 24.5007 ++cat <<EOF > exp 24.5008 ++Citrus@AA20@@5 24.5009 ++Cherry@AA30@@10 24.5010 ++Apple@AA10@@20 24.5011 ++Banana@AA5@@30 24.5012 ++EOF 24.5013 ++ 24.5014 ++cat <<EOF | sort -t @ -k4 -n > out || fail=1 24.5015 ++Apple@AA10@@20 24.5016 ++Banana@AA5@@30 24.5017 ++Citrus@AA20@@5 24.5018 ++Cherry@AA30@@10 24.5019 ++EOF 24.5020 ++ 24.5021 ++compare exp out || { fail=1; cat out; } 24.5022 ++ 24.5023 ++Exit $fail 24.5024 +diff -Naurp coreutils-8.27-orig/tests/misc/sort-merge.pl coreutils-8.27/tests/misc/sort-merge.pl 24.5025 +--- coreutils-8.27-orig/tests/misc/sort-merge.pl 2017-01-01 16:34:24.000000000 -0600 24.5026 ++++ coreutils-8.27/tests/misc/sort-merge.pl 2017-03-11 23:47:13.102285737 -0600 24.5027 +@@ -26,6 +26,15 @@ my $prog = 'sort'; 24.5028 + # Turn off localization of executable's output. 24.5029 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 24.5030 + 24.5031 ++my $mb_locale; 24.5032 ++# uncommented according to upstream commit enabling multibyte paths 24.5033 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 24.5034 ++! defined $mb_locale || $mb_locale eq 'none' 24.5035 ++ and $mb_locale = 'C'; 24.5036 ++ 24.5037 ++my $try = "Try \`$prog --help' for more information.\n"; 24.5038 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 24.5039 ++ 24.5040 + # three empty files and one that says 'foo' 24.5041 + my @inputs = (+(map{{IN=> {"empty$_"=> ''}}}1..3), {IN=> {foo=> "foo\n"}}); 24.5042 + 24.5043 +@@ -77,6 +86,39 @@ my @Tests = 24.5044 + {OUT=>$big_input}], 24.5045 + ); 24.5046 + 24.5047 ++# Add _POSIX2_VERSION=199209 to the environment of each test 24.5048 ++# that uses an old-style option like +1. 24.5049 ++if ($mb_locale ne 'C') 24.5050 ++ { 24.5051 ++ # Duplicate each test vector, appending "-mb" to the test name and 24.5052 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 24.5053 ++ # provide coverage for the distro-added multi-byte code paths. 24.5054 ++ my @new; 24.5055 ++ foreach my $t (@Tests) 24.5056 ++ { 24.5057 ++ my @new_t = @$t; 24.5058 ++ my $test_name = shift @new_t; 24.5059 ++ 24.5060 ++ # Depending on whether sort is multi-byte-patched, 24.5061 ++ # it emits different diagnostics: 24.5062 ++ # non-MB: invalid byte or field list 24.5063 ++ # MB: invalid byte, character or field list 24.5064 ++ # Adjust the expected error output accordingly. 24.5065 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 24.5066 ++ (@new_t)) 24.5067 ++ { 24.5068 ++ my $sub = {ERR_SUBST => 's/, character//'}; 24.5069 ++ push @new_t, $sub; 24.5070 ++ push @$t, $sub; 24.5071 ++ } 24.5072 ++ next if ($test_name =~ "nmerge-."); 24.5073 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 24.5074 ++ } 24.5075 ++ push @Tests, @new; 24.5076 ++ } 24.5077 ++ 24.5078 ++@Tests = triple_test \@Tests; 24.5079 ++ 24.5080 + my $save_temps = $ENV{DEBUG}; 24.5081 + my $verbose = $ENV{VERBOSE}; 24.5082 + 24.5083 +diff -Naurp coreutils-8.27-orig/tests/misc/sort.pl coreutils-8.27/tests/misc/sort.pl 24.5084 +--- coreutils-8.27-orig/tests/misc/sort.pl 2017-01-21 08:53:43.000000000 -0600 24.5085 ++++ coreutils-8.27/tests/misc/sort.pl 2017-03-11 23:47:13.103285687 -0600 24.5086 +@@ -24,10 +24,15 @@ my $prog = 'sort'; 24.5087 + # Turn off localization of executable's output. 24.5088 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 24.5089 + 24.5090 +-my $mb_locale = $ENV{LOCALE_FR_UTF8}; 24.5091 ++my $mb_locale; 24.5092 ++#Comment out next line to disable multibyte tests 24.5093 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 24.5094 + ! defined $mb_locale || $mb_locale eq 'none' 24.5095 + and $mb_locale = 'C'; 24.5096 + 24.5097 ++my $try = "Try \`$prog --help' for more information.\n"; 24.5098 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 24.5099 ++ 24.5100 + # Since each test is run with a file name and with redirected stdin, 24.5101 + # the name in the diagnostic is either the file name or "-". 24.5102 + # Normalize each diagnostic to use '-'. 24.5103 +@@ -423,6 +428,38 @@ foreach my $t (@Tests) 24.5104 + } 24.5105 + } 24.5106 + 24.5107 ++if ($mb_locale ne 'C') 24.5108 ++ { 24.5109 ++ # Duplicate each test vector, appending "-mb" to the test name and 24.5110 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 24.5111 ++ # provide coverage for the distro-added multi-byte code paths. 24.5112 ++ my @new; 24.5113 ++ foreach my $t (@Tests) 24.5114 ++ { 24.5115 ++ my @new_t = @$t; 24.5116 ++ my $test_name = shift @new_t; 24.5117 ++ 24.5118 ++ # Depending on whether sort is multi-byte-patched, 24.5119 ++ # it emits different diagnostics: 24.5120 ++ # non-MB: invalid byte or field list 24.5121 ++ # MB: invalid byte, character or field list 24.5122 ++ # Adjust the expected error output accordingly. 24.5123 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 24.5124 ++ (@new_t)) 24.5125 ++ { 24.5126 ++ my $sub = {ERR_SUBST => 's/, character//'}; 24.5127 ++ push @new_t, $sub; 24.5128 ++ push @$t, $sub; 24.5129 ++ } 24.5130 ++ #disable several failing tests until investigation, disable all tests with envvars set 24.5131 ++ next if (grep {ref $_ eq 'HASH' && exists $_->{ENV}} (@new_t)); 24.5132 ++ 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"); 24.5133 ++ next if ($test_name =~ "11[ab]"); # avoid FP: expected result differs to MB result due to collation rules. 24.5134 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 24.5135 ++ } 24.5136 ++ push @Tests, @new; 24.5137 ++ } 24.5138 ++ 24.5139 + @Tests = triple_test \@Tests; 24.5140 + 24.5141 + # Remember that triple_test creates from each test with exactly one "IN" 24.5142 +@@ -432,6 +469,7 @@ foreach my $t (@Tests) 24.5143 + # Remove the IN_PIPE version of the "output-is-input" test above. 24.5144 + # The others aren't susceptible because they have three inputs each. 24.5145 + @Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 24.5146 ++@Tests = grep {$_->[0] ne 'output-is-input-mb.p'} @Tests; 24.5147 + 24.5148 + my $save_temps = $ENV{DEBUG}; 24.5149 + my $verbose = $ENV{VERBOSE}; 24.5150 +diff -Naurp coreutils-8.27-orig/tests/misc/unexpand.pl coreutils-8.27/tests/misc/unexpand.pl 24.5151 +--- coreutils-8.27-orig/tests/misc/unexpand.pl 2017-01-01 16:34:24.000000000 -0600 24.5152 ++++ coreutils-8.27/tests/misc/unexpand.pl 2017-03-11 23:47:13.103285687 -0600 24.5153 +@@ -27,6 +27,14 @@ my $limits = getlimits (); 24.5154 + 24.5155 + my $prog = 'unexpand'; 24.5156 + 24.5157 ++# comment out next line to disable multibyte tests 24.5158 ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; 24.5159 ++! defined $mb_locale || $mb_locale eq 'none' 24.5160 ++ and $mb_locale = 'C'; 24.5161 ++ 24.5162 ++my $try = "Try \`$prog --help' for more information.\n"; 24.5163 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 24.5164 ++ 24.5165 + my @Tests = 24.5166 + ( 24.5167 + ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], 24.5168 +@@ -128,6 +136,37 @@ my @Tests = 24.5169 + ['ts2', '-t5,8', {IN=>"x\t \t y\n"}, {OUT=>"x\t\t y\n"}], 24.5170 + ); 24.5171 + 24.5172 ++if ($mb_locale ne 'C') 24.5173 ++ { 24.5174 ++ # Duplicate each test vector, appending "-mb" to the test name and 24.5175 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 24.5176 ++ # provide coverage for the distro-added multi-byte code paths. 24.5177 ++ my @new; 24.5178 ++ foreach my $t (@Tests) 24.5179 ++ { 24.5180 ++ my @new_t = @$t; 24.5181 ++ my $test_name = shift @new_t; 24.5182 ++ 24.5183 ++ # Depending on whether unexpand is multi-byte-patched, 24.5184 ++ # it emits different diagnostics: 24.5185 ++ # non-MB: invalid byte or field list 24.5186 ++ # MB: invalid byte, character or field list 24.5187 ++ # Adjust the expected error output accordingly. 24.5188 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 24.5189 ++ (@new_t)) 24.5190 ++ { 24.5191 ++ my $sub = {ERR_SUBST => 's/, character//'}; 24.5192 ++ push @new_t, $sub; 24.5193 ++ push @$t, $sub; 24.5194 ++ } 24.5195 ++ next if ($test_name =~ 'b-1'); 24.5196 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 24.5197 ++ } 24.5198 ++ push @Tests, @new; 24.5199 ++ } 24.5200 ++ 24.5201 ++@Tests = triple_test \@Tests; 24.5202 ++ 24.5203 + my $save_temps = $ENV{DEBUG}; 24.5204 + my $verbose = $ENV{VERBOSE}; 24.5205 + 24.5206 +diff -Naurp coreutils-8.27-orig/tests/misc/uniq.pl coreutils-8.27/tests/misc/uniq.pl 24.5207 +--- coreutils-8.27-orig/tests/misc/uniq.pl 2017-01-01 16:34:24.000000000 -0600 24.5208 ++++ coreutils-8.27/tests/misc/uniq.pl 2017-03-11 23:47:13.103285687 -0600 24.5209 +@@ -23,9 +23,17 @@ my $limits = getlimits (); 24.5210 + my $prog = 'uniq'; 24.5211 + my $try = "Try '$prog --help' for more information.\n"; 24.5212 + 24.5213 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 24.5214 ++ 24.5215 + # Turn off localization of executable's output. 24.5216 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 24.5217 + 24.5218 ++my $mb_locale; 24.5219 ++#Comment out next line to disable multibyte tests 24.5220 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 24.5221 ++! defined $mb_locale || $mb_locale eq 'none' 24.5222 ++ and $mb_locale = 'C'; 24.5223 ++ 24.5224 + # When possible, create a "-z"-testing variant of each test. 24.5225 + sub add_z_variants($) 24.5226 + { 24.5227 +@@ -262,6 +270,53 @@ foreach my $t (@Tests) 24.5228 + and push @$t, {ENV=>'_POSIX2_VERSION=199209'}; 24.5229 + } 24.5230 + 24.5231 ++if ($mb_locale ne 'C') 24.5232 ++ { 24.5233 ++ # Duplicate each test vector, appending "-mb" to the test name and 24.5234 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 24.5235 ++ # provide coverage for the distro-added multi-byte code paths. 24.5236 ++ my @new; 24.5237 ++ foreach my $t (@Tests) 24.5238 ++ { 24.5239 ++ my @new_t = @$t; 24.5240 ++ my $test_name = shift @new_t; 24.5241 ++ 24.5242 ++ # Depending on whether uniq is multi-byte-patched, 24.5243 ++ # it emits different diagnostics: 24.5244 ++ # non-MB: invalid byte or field list 24.5245 ++ # MB: invalid byte, character or field list 24.5246 ++ # Adjust the expected error output accordingly. 24.5247 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 24.5248 ++ (@new_t)) 24.5249 ++ { 24.5250 ++ my $sub = {ERR_SUBST => 's/, character//'}; 24.5251 ++ push @new_t, $sub; 24.5252 ++ push @$t, $sub; 24.5253 ++ } 24.5254 ++ # In test #145, replace the each ‘...’ by '...'. 24.5255 ++ if ($test_name =~ "145") 24.5256 ++ { 24.5257 ++ my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"}; 24.5258 ++ push @new_t, $sub; 24.5259 ++ push @$t, $sub; 24.5260 ++ } 24.5261 ++ next if ( $test_name =~ "schar" 24.5262 ++ or $test_name =~ "^obs-plus" 24.5263 ++ or $test_name =~ "119"); 24.5264 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 24.5265 ++ } 24.5266 ++ push @Tests, @new; 24.5267 ++ } 24.5268 ++ 24.5269 ++# Remember that triple_test creates from each test with exactly one "IN" 24.5270 ++# file two more tests (.p and .r suffix on name) corresponding to reading 24.5271 ++# input from a file and from a pipe. The pipe-reading test would fail 24.5272 ++# due to a race condition about 1 in 20 times. 24.5273 ++# Remove the IN_PIPE version of the "output-is-input" test above. 24.5274 ++# The others aren't susceptible because they have three inputs each. 24.5275 ++ 24.5276 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 24.5277 ++ 24.5278 + @Tests = add_z_variants \@Tests; 24.5279 + @Tests = triple_test \@Tests; 24.5280 + 24.5281 +diff -Naurp coreutils-8.27-orig/tests/pr/pr-tests.pl coreutils-8.27/tests/pr/pr-tests.pl 24.5282 +--- coreutils-8.27-orig/tests/pr/pr-tests.pl 2017-01-01 16:34:24.000000000 -0600 24.5283 ++++ coreutils-8.27/tests/pr/pr-tests.pl 2017-03-11 23:47:13.103285687 -0600 24.5284 +@@ -24,6 +24,15 @@ use strict; 24.5285 + my $prog = 'pr'; 24.5286 + my $normalize_strerror = "s/': .*/'/"; 24.5287 + 24.5288 ++my $mb_locale; 24.5289 ++#Uncomment the following line to enable multibyte tests 24.5290 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 24.5291 ++! defined $mb_locale || $mb_locale eq 'none' 24.5292 ++ and $mb_locale = 'C'; 24.5293 ++ 24.5294 ++my $try = "Try \`$prog --help' for more information.\n"; 24.5295 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 24.5296 ++ 24.5297 + my @tv = ( 24.5298 + 24.5299 + # -b option is no longer an official option. But it's still working to 24.5300 +@@ -474,8 +483,48 @@ push @Tests, 24.5301 + {IN=>{2=>"a\n"}}, 24.5302 + {OUT=>"a\t\t\t\t \t\t\ta\n"} ]; 24.5303 + 24.5304 ++# Add _POSIX2_VERSION=199209 to the environment of each test 24.5305 ++# that uses an old-style option like +1. 24.5306 ++if ($mb_locale ne 'C') 24.5307 ++ { 24.5308 ++ # Duplicate each test vector, appending "-mb" to the test name and 24.5309 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 24.5310 ++ # provide coverage for the distro-added multi-byte code paths. 24.5311 ++ my @new; 24.5312 ++ foreach my $t (@Tests) 24.5313 ++ { 24.5314 ++ my @new_t = @$t; 24.5315 ++ my $test_name = shift @new_t; 24.5316 ++ 24.5317 ++ # Depending on whether pr is multi-byte-patched, 24.5318 ++ # it emits different diagnostics: 24.5319 ++ # non-MB: invalid byte or field list 24.5320 ++ # MB: invalid byte, character or field list 24.5321 ++ # Adjust the expected error output accordingly. 24.5322 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 24.5323 ++ (@new_t)) 24.5324 ++ { 24.5325 ++ my $sub = {ERR_SUBST => 's/, character//'}; 24.5326 ++ push @new_t, $sub; 24.5327 ++ push @$t, $sub; 24.5328 ++ } 24.5329 ++ #temporarily skip some failing tests 24.5330 ++ next if ($test_name =~ "col-0" or $test_name =~ "col-inval" or $test_name =~ "asan1"); 24.5331 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 24.5332 ++ } 24.5333 ++ push @Tests, @new; 24.5334 ++ } 24.5335 ++ 24.5336 + @Tests = triple_test \@Tests; 24.5337 + 24.5338 ++# Remember that triple_test creates from each test with exactly one "IN" 24.5339 ++# file two more tests (.p and .r suffix on name) corresponding to reading 24.5340 ++# input from a file and from a pipe. The pipe-reading test would fail 24.5341 ++# due to a race condition about 1 in 20 times. 24.5342 ++# Remove the IN_PIPE version of the "output-is-input" test above. 24.5343 ++# The others aren't susceptible because they have three inputs each. 24.5344 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 24.5345 ++ 24.5346 + my $save_temps = $ENV{DEBUG}; 24.5347 + my $verbose = $ENV{VERBOSE}; 24.5348 + 24.5349 +diff -Naurp coreutils-8.27-orig/tests/unexpand/mb.sh coreutils-8.27/tests/unexpand/mb.sh 24.5350 +--- coreutils-8.27-orig/tests/unexpand/mb.sh 1969-12-31 18:00:00.000000000 -0600 24.5351 ++++ coreutils-8.27/tests/unexpand/mb.sh 2017-03-11 23:49:06.759133489 -0600 24.5352 +@@ -0,0 +1,172 @@ 24.5353 ++#!/bin/sh 24.5354 ++ 24.5355 ++# Copyright (C) 2012-2017 Free Software Foundation, Inc. 24.5356 ++ 24.5357 ++# This program is free software: you can redistribute it and/or modify 24.5358 ++# it under the terms of the GNU General Public License as published by 24.5359 ++# the Free Software Foundation, either version 3 of the License, or 24.5360 ++# (at your option) any later version. 24.5361 ++ 24.5362 ++# This program is distributed in the hope that it will be useful, 24.5363 ++# but WITHOUT ANY WARRANTY; without even the implied warranty of 24.5364 ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24.5365 ++# GNU General Public License for more details. 24.5366 ++ 24.5367 ++# You should have received a copy of the GNU General Public License 24.5368 ++# along with this program. If not, see <http://www.gnu.org/licenses/>. 24.5369 ++ 24.5370 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 24.5371 ++print_ver_ unexpand 24.5372 ++ 24.5373 ++export LC_ALL=en_US.UTF-8 24.5374 ++ 24.5375 ++#input containing multibyte characters 24.5376 ++cat > in <<\EOF 24.5377 ++1234567812345678123456781 24.5378 ++. . . . 24.5379 ++a b c d 24.5380 ++. . . . 24.5381 ++ä ö ü ß 24.5382 ++. . . . 24.5383 ++ äöü . öüä. ä xx 24.5384 ++EOF 24.5385 ++ 24.5386 ++cat > exp <<\EOF 24.5387 ++1234567812345678123456781 24.5388 ++. . . . 24.5389 ++a b c d 24.5390 ++. . . . 24.5391 ++ä ö ü ß 24.5392 ++. . . . 24.5393 ++ äöü . öüä. ä xx 24.5394 ++EOF 24.5395 ++ 24.5396 ++unexpand -a < in > out || fail=1 24.5397 ++compare exp out > /dev/null 2>&1 || fail=1 24.5398 ++ 24.5399 ++ 24.5400 ++#multiple files as an input 24.5401 ++cat >> exp <<\EOF 24.5402 ++1234567812345678123456781 24.5403 ++. . . . 24.5404 ++a b c d 24.5405 ++. . . . 24.5406 ++ä ö ü ß 24.5407 ++. . . . 24.5408 ++ äöü . öüä. ä xx 24.5409 ++EOF 24.5410 ++ 24.5411 ++ 24.5412 ++unexpand -a ./in ./in > out || fail=1 24.5413 ++compare exp out > /dev/null 2>&1 || fail=1 24.5414 ++ 24.5415 ++#test characters with a display width larger than 1 24.5416 ++ 24.5417 ++env printf '12345678 24.5418 ++e |ascii(1) 24.5419 ++\u00E9 |composed(1) 24.5420 ++e\u0301 |decomposed(1) 24.5421 ++\u3000 |ideo-space(2) 24.5422 ++\uFF0D |full-hypen(2) 24.5423 ++' > in || framework_failure_ 24.5424 ++ 24.5425 ++env printf '12345678 24.5426 ++e\t|ascii(1) 24.5427 ++\u00E9\t|composed(1) 24.5428 ++e\u0301\t|decomposed(1) 24.5429 ++\u3000\t|ideo-space(2) 24.5430 ++\uFF0D\t|full-hypen(2) 24.5431 ++' > exp || framework_failure_ 24.5432 ++ 24.5433 ++unexpand -a < in > out || fail=1 24.5434 ++compare exp out > /dev/null 2>&1 || fail=1 24.5435 ++ 24.5436 ++#test input where a blank of width > 1 is not being substituted 24.5437 ++in="$(LC_ALL=en_US.UTF-8 printf ' \u3000 ö ü ß')" 24.5438 ++exp=' ö ü ß' 24.5439 ++ 24.5440 ++unexpand -a < in > out || fail=1 24.5441 ++compare exp out > /dev/null 2>&1 || fail=1 24.5442 ++ 24.5443 ++#non-Unicode characters interspersed between Unicode ones 24.5444 ++env printf '12345678 24.5445 ++ \xFF| 24.5446 ++\xFF | 24.5447 ++ \xFFä| 24.5448 ++ä\xFF | 24.5449 ++ ä\xFF| 24.5450 ++\xFF ä| 24.5451 ++äbcdef\xFF | 24.5452 ++' > in || framework_failure_ 24.5453 ++ 24.5454 ++env printf '12345678 24.5455 ++\t\xFF| 24.5456 ++\xFF\t| 24.5457 ++\t\xFFä| 24.5458 ++ä\xFF\t| 24.5459 ++\tä\xFF| 24.5460 ++\xFF\tä| 24.5461 ++äbcdef\xFF\t| 24.5462 ++' > exp || framework_failure_ 24.5463 ++ 24.5464 ++unexpand -a < in > out || fail=1 24.5465 ++compare exp out > /dev/null 2>&1 || fail=1 24.5466 ++ 24.5467 ++#BOM header test 1 24.5468 ++printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ 24.5469 ++1234567812345678123456781 24.5470 ++. . . . 24.5471 ++a b c d 24.5472 ++. . . . 24.5473 ++ä ö ü ß 24.5474 ++. . . . 24.5475 ++ äöü . öüä. ä xx 24.5476 ++EOF 24.5477 ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ 24.5478 ++ 24.5479 ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ 24.5480 ++1234567812345678123456781 24.5481 ++. . . . 24.5482 ++a b c d 24.5483 ++. . . . 24.5484 ++ä ö ü ß 24.5485 ++. . . . 24.5486 ++ äöü . öüä. ä xx 24.5487 ++EOF 24.5488 ++ 24.5489 ++unexpand < in > out || fail=1 24.5490 ++compare exp out > /dev/null 2>&1 || fail=1 24.5491 ++ 24.5492 ++LANG=C unexpand < in > out || fail=1 24.5493 ++compare exp out > /dev/null 2>&1 || fail=1 24.5494 ++ 24.5495 ++LC_ALL=C unexpand < in > out || fail=1 24.5496 ++compare exp out > /dev/null 2>&1 || fail=1 24.5497 ++ 24.5498 ++ 24.5499 ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ 24.5500 ++1234567812345678123456781 24.5501 ++. . . . 24.5502 ++a b c d 24.5503 ++. . . . 24.5504 ++ä ö ü ß 24.5505 ++. . . . 24.5506 ++ äöü . öüä. ä xx 24.5507 ++1234567812345678123456781 24.5508 ++. . . . 24.5509 ++a b c d 24.5510 ++. . . . 24.5511 ++ä ö ü ß 24.5512 ++. . . . 24.5513 ++ äöü . öüä. ä xx 24.5514 ++EOF 24.5515 ++ 24.5516 ++ 24.5517 ++unexpand in in > out || fail=1 24.5518 ++compare exp out > /dev/null 2>&1 || fail=1 24.5519 ++ 24.5520 ++LANG=C unexpand in in > out || fail=1 24.5521 ++compare exp out > /dev/null 2>&1 || fail=1 24.5522 ++ 24.5523 ++LC_ALL=C unexpand in in > out || fail=1 24.5524 ++compare exp out > /dev/null 2>&1 || fail=1
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/coreutils/stuff/patches/coreutils-8.29-i18n-1.patch Wed Feb 21 19:48:17 2018 +0200 25.3 @@ -0,0 +1,5521 @@ 25.4 +Submitted by: DJ Lucas (dj_AT_linuxfromscratch_DOT_org) 25.5 +Date: 2017-03-12 25.6 +Initial Package Version: 8.27 25.7 +Upstream Status: Rejected 25.8 +Origin: Based on Fedora's i18n patches at 25.9 + http://pkgs.fedoraproject.org/cgit/rpms/coreutils.git/tree/ 25.10 +Description: Fixes i18n issues with various Coreutils programs 25.11 + 25.12 +diff -Naurp coreutils-8.27-orig/bootstrap.conf coreutils-8.27/bootstrap.conf 25.13 +--- coreutils-8.27-orig/bootstrap.conf 2017-03-07 23:34:06.000000000 -0600 25.14 ++++ coreutils-8.27/bootstrap.conf 2017-03-11 23:47:38.068058445 -0600 25.15 +@@ -152,6 +152,7 @@ gnulib_modules=" 25.16 + maintainer-makefile 25.17 + malloc-gnu 25.18 + manywarnings 25.19 ++ mbfile 25.20 + mbrlen 25.21 + mbrtowc 25.22 + mbsalign 25.23 +diff -Naurp coreutils-8.27-orig/configure.ac coreutils-8.27/configure.ac 25.24 +--- coreutils-8.27-orig/configure.ac 2017-02-26 08:52:29.000000000 -0600 25.25 ++++ coreutils-8.27/configure.ac 2017-03-11 23:47:38.068058445 -0600 25.26 +@@ -429,6 +429,8 @@ fi 25.27 + # I'm leaving it here for now. This whole thing needs to be modernized... 25.28 + gl_WINSIZE_IN_PTEM 25.29 + 25.30 ++gl_MBFILE 25.31 ++ 25.32 + gl_HEADER_TIOCGWINSZ_IN_TERMIOS_H 25.33 + 25.34 + if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ 25.35 +diff -Naurp coreutils-8.27-orig/lib/linebuffer.h coreutils-8.27/lib/linebuffer.h 25.36 +--- coreutils-8.27-orig/lib/linebuffer.h 2017-01-01 16:35:38.000000000 -0600 25.37 ++++ coreutils-8.27/lib/linebuffer.h 2017-03-11 23:47:13.089286391 -0600 25.38 +@@ -21,6 +21,11 @@ 25.39 + 25.40 + # include <stdio.h> 25.41 + 25.42 ++/* Get mbstate_t. */ 25.43 ++# if HAVE_WCHAR_H 25.44 ++# include <wchar.h> 25.45 ++# endif 25.46 ++ 25.47 + /* A 'struct linebuffer' holds a line of text. */ 25.48 + 25.49 + struct linebuffer 25.50 +@@ -28,6 +33,9 @@ struct linebuffer 25.51 + size_t size; /* Allocated. */ 25.52 + size_t length; /* Used. */ 25.53 + char *buffer; 25.54 ++# if HAVE_WCHAR_H 25.55 ++ mbstate_t state; 25.56 ++# endif 25.57 + }; 25.58 + 25.59 + /* Initialize linebuffer LINEBUFFER for use. */ 25.60 +diff -Naurp coreutils-8.27-orig/lib/mbfile.c coreutils-8.27/lib/mbfile.c 25.61 +--- coreutils-8.27-orig/lib/mbfile.c 1969-12-31 18:00:00.000000000 -0600 25.62 ++++ coreutils-8.27/lib/mbfile.c 2017-03-11 23:47:38.069058397 -0600 25.63 +@@ -0,0 +1,3 @@ 25.64 ++#include <config.h> 25.65 ++#define MBFILE_INLINE _GL_EXTERN_INLINE 25.66 ++#include "mbfile.h" 25.67 +diff -Naurp coreutils-8.27-orig/lib/mbfile.h coreutils-8.27/lib/mbfile.h 25.68 +--- coreutils-8.27-orig/lib/mbfile.h 1969-12-31 18:00:00.000000000 -0600 25.69 ++++ coreutils-8.27/lib/mbfile.h 2017-03-11 23:47:38.069058397 -0600 25.70 +@@ -0,0 +1,255 @@ 25.71 ++/* Multibyte character I/O: macros for multi-byte encodings. 25.72 ++ Copyright (C) 2001, 2005, 2009-2017 Free Software Foundation, Inc. 25.73 ++ 25.74 ++ This program is free software: you can redistribute it and/or modify 25.75 ++ it under the terms of the GNU General Public License as published by 25.76 ++ the Free Software Foundation; either version 3 of the License, or 25.77 ++ (at your option) any later version. 25.78 ++ 25.79 ++ This program is distributed in the hope that it will be useful, 25.80 ++ but WITHOUT ANY WARRANTY; without even the implied warranty of 25.81 ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25.82 ++ GNU General Public License for more details. 25.83 ++ 25.84 ++ You should have received a copy of the GNU General Public License 25.85 ++ along with this program. If not, see <http://www.gnu.org/licenses/>. */ 25.86 ++ 25.87 ++/* Written by Mitsuru Chinen <mchinen@yamato.ibm.com> 25.88 ++ and Bruno Haible <bruno@clisp.org>. */ 25.89 ++ 25.90 ++/* The macros in this file implement multi-byte character input from a 25.91 ++ stream. 25.92 ++ 25.93 ++ mb_file_t 25.94 ++ is the type for multibyte character input stream, usable for variable 25.95 ++ declarations. 25.96 ++ 25.97 ++ mbf_char_t 25.98 ++ is the type for multibyte character or EOF, usable for variable 25.99 ++ declarations. 25.100 ++ 25.101 ++ mbf_init (mbf, stream) 25.102 ++ initializes the MB_FILE for reading from stream. 25.103 ++ 25.104 ++ mbf_getc (mbc, mbf) 25.105 ++ reads the next multibyte character from mbf and stores it in mbc. 25.106 ++ 25.107 ++ mb_iseof (mbc) 25.108 ++ returns true if mbc represents the EOF value. 25.109 ++ 25.110 ++ Here are the function prototypes of the macros. 25.111 ++ 25.112 ++ extern void mbf_init (mb_file_t mbf, FILE *stream); 25.113 ++ extern void mbf_getc (mbf_char_t mbc, mb_file_t mbf); 25.114 ++ extern bool mb_iseof (const mbf_char_t mbc); 25.115 ++ */ 25.116 ++ 25.117 ++#ifndef _MBFILE_H 25.118 ++#define _MBFILE_H 1 25.119 ++ 25.120 ++#include <assert.h> 25.121 ++#include <stdbool.h> 25.122 ++#include <stdio.h> 25.123 ++#include <string.h> 25.124 ++ 25.125 ++/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before 25.126 ++ <wchar.h>. 25.127 ++ BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before 25.128 ++ <wchar.h>. */ 25.129 ++#include <stdio.h> 25.130 ++#include <time.h> 25.131 ++#include <wchar.h> 25.132 ++ 25.133 ++#include "mbchar.h" 25.134 ++ 25.135 ++#ifndef _GL_INLINE_HEADER_BEGIN 25.136 ++ #error "Please include config.h first." 25.137 ++#endif 25.138 ++_GL_INLINE_HEADER_BEGIN 25.139 ++#ifndef MBFILE_INLINE 25.140 ++# define MBFILE_INLINE _GL_INLINE 25.141 ++#endif 25.142 ++ 25.143 ++struct mbfile_multi { 25.144 ++ FILE *fp; 25.145 ++ bool eof_seen; 25.146 ++ bool have_pushback; 25.147 ++ mbstate_t state; 25.148 ++ unsigned int bufcount; 25.149 ++ char buf[MBCHAR_BUF_SIZE]; 25.150 ++ struct mbchar pushback; 25.151 ++}; 25.152 ++ 25.153 ++MBFILE_INLINE void 25.154 ++mbfile_multi_getc (struct mbchar *mbc, struct mbfile_multi *mbf) 25.155 ++{ 25.156 ++ size_t bytes; 25.157 ++ 25.158 ++ /* If EOF has already been seen, don't use getc. This matters if 25.159 ++ mbf->fp is connected to an interactive tty. */ 25.160 ++ if (mbf->eof_seen) 25.161 ++ goto eof; 25.162 ++ 25.163 ++ /* Return character pushed back, if there is one. */ 25.164 ++ if (mbf->have_pushback) 25.165 ++ { 25.166 ++ mb_copy (mbc, &mbf->pushback); 25.167 ++ mbf->have_pushback = false; 25.168 ++ return; 25.169 ++ } 25.170 ++ 25.171 ++ /* Before using mbrtowc, we need at least one byte. */ 25.172 ++ if (mbf->bufcount == 0) 25.173 ++ { 25.174 ++ int c = getc (mbf->fp); 25.175 ++ if (c == EOF) 25.176 ++ { 25.177 ++ mbf->eof_seen = true; 25.178 ++ goto eof; 25.179 ++ } 25.180 ++ mbf->buf[0] = (unsigned char) c; 25.181 ++ mbf->bufcount++; 25.182 ++ } 25.183 ++ 25.184 ++ /* Handle most ASCII characters quickly, without calling mbrtowc(). */ 25.185 ++ if (mbf->bufcount == 1 && mbsinit (&mbf->state) && is_basic (mbf->buf[0])) 25.186 ++ { 25.187 ++ /* These characters are part of the basic character set. ISO C 99 25.188 ++ guarantees that their wide character code is identical to their 25.189 ++ char code. */ 25.190 ++ mbc->wc = mbc->buf[0] = mbf->buf[0]; 25.191 ++ mbc->wc_valid = true; 25.192 ++ mbc->ptr = &mbc->buf[0]; 25.193 ++ mbc->bytes = 1; 25.194 ++ mbf->bufcount = 0; 25.195 ++ return; 25.196 ++ } 25.197 ++ 25.198 ++ /* Use mbrtowc on an increasing number of bytes. Read only as many bytes 25.199 ++ from mbf->fp as needed. This is needed to give reasonable interactive 25.200 ++ behaviour when mbf->fp is connected to an interactive tty. */ 25.201 ++ for (;;) 25.202 ++ { 25.203 ++ /* We don't know whether the 'mbrtowc' function updates the state when 25.204 ++ it returns -2, - this is the ISO C 99 and glibc-2.2 behaviour - or 25.205 ++ not - amended ANSI C, glibc-2.1 and Solaris 2.7 behaviour. We 25.206 ++ don't have an autoconf test for this, yet. 25.207 ++ The new behaviour would allow us to feed the bytes one by one into 25.208 ++ mbrtowc. But the old behaviour forces us to feed all bytes since 25.209 ++ the end of the last character into mbrtowc. Since we want to retry 25.210 ++ with more bytes when mbrtowc returns -2, we must backup the state 25.211 ++ before calling mbrtowc, because implementations with the new 25.212 ++ behaviour will clobber it. */ 25.213 ++ mbstate_t backup_state = mbf->state; 25.214 ++ 25.215 ++ bytes = mbrtowc (&mbc->wc, &mbf->buf[0], mbf->bufcount, &mbf->state); 25.216 ++ 25.217 ++ if (bytes == (size_t) -1) 25.218 ++ { 25.219 ++ /* An invalid multibyte sequence was encountered. */ 25.220 ++ /* Return a single byte. */ 25.221 ++ bytes = 1; 25.222 ++ mbc->wc_valid = false; 25.223 ++ break; 25.224 ++ } 25.225 ++ else if (bytes == (size_t) -2) 25.226 ++ { 25.227 ++ /* An incomplete multibyte character. */ 25.228 ++ mbf->state = backup_state; 25.229 ++ if (mbf->bufcount == MBCHAR_BUF_SIZE) 25.230 ++ { 25.231 ++ /* An overlong incomplete multibyte sequence was encountered. */ 25.232 ++ /* Return a single byte. */ 25.233 ++ bytes = 1; 25.234 ++ mbc->wc_valid = false; 25.235 ++ break; 25.236 ++ } 25.237 ++ else 25.238 ++ { 25.239 ++ /* Read one more byte and retry mbrtowc. */ 25.240 ++ int c = getc (mbf->fp); 25.241 ++ if (c == EOF) 25.242 ++ { 25.243 ++ /* An incomplete multibyte character at the end. */ 25.244 ++ mbf->eof_seen = true; 25.245 ++ bytes = mbf->bufcount; 25.246 ++ mbc->wc_valid = false; 25.247 ++ break; 25.248 ++ } 25.249 ++ mbf->buf[mbf->bufcount] = (unsigned char) c; 25.250 ++ mbf->bufcount++; 25.251 ++ } 25.252 ++ } 25.253 ++ else 25.254 ++ { 25.255 ++ if (bytes == 0) 25.256 ++ { 25.257 ++ /* A null wide character was encountered. */ 25.258 ++ bytes = 1; 25.259 ++ assert (mbf->buf[0] == '\0'); 25.260 ++ assert (mbc->wc == 0); 25.261 ++ } 25.262 ++ mbc->wc_valid = true; 25.263 ++ break; 25.264 ++ } 25.265 ++ } 25.266 ++ 25.267 ++ /* Return the multibyte sequence mbf->buf[0..bytes-1]. */ 25.268 ++ mbc->ptr = &mbc->buf[0]; 25.269 ++ memcpy (&mbc->buf[0], &mbf->buf[0], bytes); 25.270 ++ mbc->bytes = bytes; 25.271 ++ 25.272 ++ mbf->bufcount -= bytes; 25.273 ++ if (mbf->bufcount > 0) 25.274 ++ { 25.275 ++ /* It's not worth calling memmove() for so few bytes. */ 25.276 ++ unsigned int count = mbf->bufcount; 25.277 ++ char *p = &mbf->buf[0]; 25.278 ++ 25.279 ++ do 25.280 ++ { 25.281 ++ *p = *(p + bytes); 25.282 ++ p++; 25.283 ++ } 25.284 ++ while (--count > 0); 25.285 ++ } 25.286 ++ return; 25.287 ++ 25.288 ++eof: 25.289 ++ /* An mbchar_t with bytes == 0 is used to indicate EOF. */ 25.290 ++ mbc->ptr = NULL; 25.291 ++ mbc->bytes = 0; 25.292 ++ mbc->wc_valid = false; 25.293 ++ return; 25.294 ++} 25.295 ++ 25.296 ++MBFILE_INLINE void 25.297 ++mbfile_multi_ungetc (const struct mbchar *mbc, struct mbfile_multi *mbf) 25.298 ++{ 25.299 ++ mb_copy (&mbf->pushback, mbc); 25.300 ++ mbf->have_pushback = true; 25.301 ++} 25.302 ++ 25.303 ++typedef struct mbfile_multi mb_file_t; 25.304 ++ 25.305 ++typedef mbchar_t mbf_char_t; 25.306 ++ 25.307 ++#define mbf_init(mbf, stream) \ 25.308 ++ ((mbf).fp = (stream), \ 25.309 ++ (mbf).eof_seen = false, \ 25.310 ++ (mbf).have_pushback = false, \ 25.311 ++ memset (&(mbf).state, '\0', sizeof (mbstate_t)), \ 25.312 ++ (mbf).bufcount = 0) 25.313 ++ 25.314 ++#define mbf_getc(mbc, mbf) mbfile_multi_getc (&(mbc), &(mbf)) 25.315 ++ 25.316 ++#define mbf_ungetc(mbc, mbf) mbfile_multi_ungetc (&(mbc), &(mbf)) 25.317 ++ 25.318 ++#define mb_iseof(mbc) ((mbc).bytes == 0) 25.319 ++ 25.320 ++#ifndef _GL_INLINE_HEADER_BEGIN 25.321 ++ #error "Please include config.h first." 25.322 ++#endif 25.323 ++_GL_INLINE_HEADER_BEGIN 25.324 ++ 25.325 ++#endif /* _MBFILE_H */ 25.326 +diff -Naurp coreutils-8.27-orig/m4/mbfile.m4 coreutils-8.27/m4/mbfile.m4 25.327 +--- coreutils-8.27-orig/m4/mbfile.m4 1969-12-31 18:00:00.000000000 -0600 25.328 ++++ coreutils-8.27/m4/mbfile.m4 2017-03-11 23:47:38.070058349 -0600 25.329 +@@ -0,0 +1,14 @@ 25.330 ++# mbfile.m4 serial 7 25.331 ++dnl Copyright (C) 2005, 2008-2017 Free Software Foundation, Inc. 25.332 ++dnl This file is free software; the Free Software Foundation 25.333 ++dnl gives unlimited permission to copy and/or distribute it, 25.334 ++dnl with or without modifications, as long as this notice is preserved. 25.335 ++ 25.336 ++dnl autoconf tests required for use of mbfile.h 25.337 ++dnl From Bruno Haible. 25.338 ++ 25.339 ++AC_DEFUN([gl_MBFILE], 25.340 ++[ 25.341 ++ AC_REQUIRE([AC_TYPE_MBSTATE_T]) 25.342 ++ : 25.343 ++]) 25.344 +diff -Naurp coreutils-8.27-orig/src/cut.c coreutils-8.27/src/cut.c 25.345 +--- coreutils-8.27-orig/src/cut.c 2017-01-01 16:34:24.000000000 -0600 25.346 ++++ coreutils-8.27/src/cut.c 2017-03-11 23:47:59.526048471 -0600 25.347 +@@ -28,6 +28,11 @@ 25.348 + #include <assert.h> 25.349 + #include <getopt.h> 25.350 + #include <sys/types.h> 25.351 ++ 25.352 ++/* Get mbstate_t, mbrtowc(). */ 25.353 ++#if HAVE_WCHAR_H 25.354 ++# include <wchar.h> 25.355 ++#endif 25.356 + #include "system.h" 25.357 + 25.358 + #include "error.h" 25.359 +@@ -38,6 +43,18 @@ 25.360 + 25.361 + #include "set-fields.h" 25.362 + 25.363 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 25.364 ++ installation; work around this configuration error. */ 25.365 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 25.366 ++# undef MB_LEN_MAX 25.367 ++# define MB_LEN_MAX 16 25.368 ++#endif 25.369 ++ 25.370 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 25.371 ++#if HAVE_MBRTOWC && defined mbstate_t 25.372 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 25.373 ++#endif 25.374 ++ 25.375 + /* The official name of this program (e.g., no 'g' prefix). */ 25.376 + #define PROGRAM_NAME "cut" 25.377 + 25.378 +@@ -54,6 +71,52 @@ 25.379 + } \ 25.380 + while (0) 25.381 + 25.382 ++/* Refill the buffer BUF to get a multibyte character. */ 25.383 ++#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM) \ 25.384 ++ do \ 25.385 ++ { \ 25.386 ++ if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM)) \ 25.387 ++ { \ 25.388 ++ memmove (BUF, BUFPOS, BUFLEN); \ 25.389 ++ BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \ 25.390 ++ BUFPOS = BUF; \ 25.391 ++ } \ 25.392 ++ } \ 25.393 ++ while (0) 25.394 ++ 25.395 ++/* Get wide character on BUFPOS. BUFPOS is not included after that. 25.396 ++ If byte sequence is not valid as a character, CONVFAIL is true. Otherwise false. */ 25.397 ++#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ 25.398 ++ do \ 25.399 ++ { \ 25.400 ++ mbstate_t state_bak; \ 25.401 ++ \ 25.402 ++ if (BUFLEN < 1) \ 25.403 ++ { \ 25.404 ++ WC = WEOF; \ 25.405 ++ break; \ 25.406 ++ } \ 25.407 ++ \ 25.408 ++ /* Get a wide character. */ \ 25.409 ++ CONVFAIL = false; \ 25.410 ++ state_bak = STATE; \ 25.411 ++ MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \ 25.412 ++ \ 25.413 ++ switch (MBLENGTH) \ 25.414 ++ { \ 25.415 ++ case (size_t)-1: \ 25.416 ++ case (size_t)-2: \ 25.417 ++ CONVFAIL = true; \ 25.418 ++ STATE = state_bak; \ 25.419 ++ /* Fall througn. */ \ 25.420 ++ \ 25.421 ++ case 0: \ 25.422 ++ MBLENGTH = 1; \ 25.423 ++ break; \ 25.424 ++ } \ 25.425 ++ } \ 25.426 ++ while (0) 25.427 ++ 25.428 + 25.429 + /* Pointer inside RP. When checking if a byte or field is selected 25.430 + by a finite range, we check if it is between CURRENT_RP.LO 25.431 +@@ -61,6 +124,9 @@ 25.432 + CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ 25.433 + static struct field_range_pair *current_rp; 25.434 + 25.435 ++/* Length of the delimiter given as argument to -d. */ 25.436 ++size_t delimlen; 25.437 ++ 25.438 + /* This buffer is used to support the semantics of the -s option 25.439 + (or lack of same) when the specified field list includes (does 25.440 + not include) the first field. In both of those cases, the entire 25.441 +@@ -77,15 +143,25 @@ enum operating_mode 25.442 + { 25.443 + undefined_mode, 25.444 + 25.445 +- /* Output characters that are in the given bytes. */ 25.446 ++ /* Output bytes that are at the given positions. */ 25.447 + byte_mode, 25.448 + 25.449 ++ /* Output characters that are at the given positions. */ 25.450 ++ character_mode, 25.451 ++ 25.452 + /* Output the given delimiter-separated fields. */ 25.453 + field_mode 25.454 + }; 25.455 + 25.456 + static enum operating_mode operating_mode; 25.457 + 25.458 ++/* If nonzero, when in byte mode, don't split multibyte characters. */ 25.459 ++static int byte_mode_character_aware; 25.460 ++ 25.461 ++/* If nonzero, the function for single byte locale is work 25.462 ++ if this program runs on multibyte locale. */ 25.463 ++static int force_singlebyte_mode; 25.464 ++ 25.465 + /* If true do not output lines containing no delimiter characters. 25.466 + Otherwise, all such lines are printed. This option is valid only 25.467 + with field mode. */ 25.468 +@@ -97,6 +173,9 @@ static bool complement; 25.469 + 25.470 + /* The delimiter character for field mode. */ 25.471 + static unsigned char delim; 25.472 ++#if HAVE_WCHAR_H 25.473 ++static wchar_t wcdelim; 25.474 ++#endif 25.475 + 25.476 + /* The delimiter for each line/record. */ 25.477 + static unsigned char line_delim = '\n'; 25.478 +@@ -164,7 +243,7 @@ Print selected parts of lines from each 25.479 + -f, --fields=LIST select only these fields; also print any line\n\ 25.480 + that contains no delimiter character, unless\n\ 25.481 + the -s option is specified\n\ 25.482 +- -n (ignored)\n\ 25.483 ++ -n with -b: don't split multibyte characters\n\ 25.484 + "), stdout); 25.485 + fputs (_("\ 25.486 + --complement complement the set of selected bytes, characters\n\ 25.487 +@@ -280,6 +359,82 @@ cut_bytes (FILE *stream) 25.488 + } 25.489 + } 25.490 + 25.491 ++#if HAVE_MBRTOWC 25.492 ++/* This function is in use for the following case. 25.493 ++ 25.494 ++ 1. Read from the stream STREAM, printing to standard output any selected 25.495 ++ characters. 25.496 ++ 25.497 ++ 2. Read from stream STREAM, printing to standard output any selected bytes, 25.498 ++ without splitting multibyte characters. */ 25.499 ++ 25.500 ++static void 25.501 ++cut_characters_or_cut_bytes_no_split (FILE *stream) 25.502 ++{ 25.503 ++ size_t idx; /* number of bytes or characters in the line so far. */ 25.504 ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 25.505 ++ char *bufpos; /* Next read position of BUF. */ 25.506 ++ size_t buflen; /* The length of the byte sequence in buf. */ 25.507 ++ wint_t wc; /* A gotten wide character. */ 25.508 ++ size_t mblength; /* The byte size of a multibyte character which shows 25.509 ++ as same character as WC. */ 25.510 ++ mbstate_t state; /* State of the stream. */ 25.511 ++ bool convfail = false; /* true, when conversion failed. Otherwise false. */ 25.512 ++ /* Whether to begin printing delimiters between ranges for the current line. 25.513 ++ Set after we've begun printing data corresponding to the first range. */ 25.514 ++ bool print_delimiter = false; 25.515 ++ 25.516 ++ idx = 0; 25.517 ++ buflen = 0; 25.518 ++ bufpos = buf; 25.519 ++ memset (&state, '\0', sizeof(mbstate_t)); 25.520 ++ 25.521 ++ current_rp = frp; 25.522 ++ 25.523 ++ while (1) 25.524 ++ { 25.525 ++ REFILL_BUFFER (buf, bufpos, buflen, stream); 25.526 ++ 25.527 ++ GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); 25.528 ++ (void) convfail; /* ignore unused */ 25.529 ++ 25.530 ++ if (wc == WEOF) 25.531 ++ { 25.532 ++ if (idx > 0) 25.533 ++ putchar (line_delim); 25.534 ++ break; 25.535 ++ } 25.536 ++ else if (wc == line_delim) 25.537 ++ { 25.538 ++ putchar (line_delim); 25.539 ++ idx = 0; 25.540 ++ print_delimiter = false; 25.541 ++ current_rp = frp; 25.542 ++ } 25.543 ++ else 25.544 ++ { 25.545 ++ next_item (&idx); 25.546 ++ if (print_kth (idx)) 25.547 ++ { 25.548 ++ if (output_delimiter_specified) 25.549 ++ { 25.550 ++ if (print_delimiter && is_range_start_index (idx)) 25.551 ++ { 25.552 ++ fwrite (output_delimiter_string, sizeof (char), 25.553 ++ output_delimiter_length, stdout); 25.554 ++ } 25.555 ++ print_delimiter = true; 25.556 ++ } 25.557 ++ fwrite (bufpos, mblength, sizeof(char), stdout); 25.558 ++ } 25.559 ++ } 25.560 ++ 25.561 ++ buflen -= mblength; 25.562 ++ bufpos += mblength; 25.563 ++ } 25.564 ++} 25.565 ++#endif 25.566 ++ 25.567 + /* Read from stream STREAM, printing to standard output any selected fields. */ 25.568 + 25.569 + static void 25.570 +@@ -425,13 +580,211 @@ cut_fields (FILE *stream) 25.571 + } 25.572 + } 25.573 + 25.574 ++#if HAVE_MBRTOWC 25.575 ++static void 25.576 ++cut_fields_mb (FILE *stream) 25.577 ++{ 25.578 ++ int c; 25.579 ++ size_t field_idx; 25.580 ++ int found_any_selected_field; 25.581 ++ int buffer_first_field; 25.582 ++ int empty_input; 25.583 ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 25.584 ++ char *bufpos; /* Next read position of BUF. */ 25.585 ++ size_t buflen; /* The length of the byte sequence in buf. */ 25.586 ++ wint_t wc = 0; /* A gotten wide character. */ 25.587 ++ size_t mblength; /* The byte size of a multibyte character which shows 25.588 ++ as same character as WC. */ 25.589 ++ mbstate_t state; /* State of the stream. */ 25.590 ++ bool convfail = false; /* true, when conversion failed. Otherwise false. */ 25.591 ++ 25.592 ++ current_rp = frp; 25.593 ++ 25.594 ++ found_any_selected_field = 0; 25.595 ++ field_idx = 1; 25.596 ++ bufpos = buf; 25.597 ++ buflen = 0; 25.598 ++ memset (&state, '\0', sizeof(mbstate_t)); 25.599 ++ 25.600 ++ c = getc (stream); 25.601 ++ empty_input = (c == EOF); 25.602 ++ if (c != EOF) 25.603 ++ { 25.604 ++ ungetc (c, stream); 25.605 ++ wc = 0; 25.606 ++ } 25.607 ++ else 25.608 ++ wc = WEOF; 25.609 ++ 25.610 ++ /* To support the semantics of the -s flag, we may have to buffer 25.611 ++ all of the first field to determine whether it is `delimited.' 25.612 ++ But that is unnecessary if all non-delimited lines must be printed 25.613 ++ and the first field has been selected, or if non-delimited lines 25.614 ++ must be suppressed and the first field has *not* been selected. 25.615 ++ That is because a non-delimited line has exactly one field. */ 25.616 ++ buffer_first_field = (suppress_non_delimited ^ !print_kth (1)); 25.617 ++ 25.618 ++ while (1) 25.619 ++ { 25.620 ++ if (field_idx == 1 && buffer_first_field) 25.621 ++ { 25.622 ++ int len = 0; 25.623 ++ 25.624 ++ while (1) 25.625 ++ { 25.626 ++ REFILL_BUFFER (buf, bufpos, buflen, stream); 25.627 ++ 25.628 ++ GET_NEXT_WC_FROM_BUFFER 25.629 ++ (wc, bufpos, buflen, mblength, state, convfail); 25.630 ++ 25.631 ++ if (wc == WEOF) 25.632 ++ break; 25.633 ++ 25.634 ++ field_1_buffer = xrealloc (field_1_buffer, len + mblength); 25.635 ++ memcpy (field_1_buffer + len, bufpos, mblength); 25.636 ++ len += mblength; 25.637 ++ buflen -= mblength; 25.638 ++ bufpos += mblength; 25.639 ++ 25.640 ++ if (!convfail && (wc == line_delim || wc == wcdelim)) 25.641 ++ break; 25.642 ++ } 25.643 ++ 25.644 ++ if (len <= 0 && wc == WEOF) 25.645 ++ break; 25.646 ++ 25.647 ++ /* If the first field extends to the end of line (it is not 25.648 ++ delimited) and we are printing all non-delimited lines, 25.649 ++ print this one. */ 25.650 ++ if (convfail || (!convfail && wc != wcdelim)) 25.651 ++ { 25.652 ++ if (suppress_non_delimited) 25.653 ++ { 25.654 ++ /* Empty. */ 25.655 ++ } 25.656 ++ else 25.657 ++ { 25.658 ++ fwrite (field_1_buffer, sizeof (char), len, stdout); 25.659 ++ /* Make sure the output line is newline terminated. */ 25.660 ++ if (convfail || (!convfail && wc != line_delim)) 25.661 ++ putchar (line_delim); 25.662 ++ } 25.663 ++ continue; 25.664 ++ } 25.665 ++ 25.666 ++ if (print_kth (1)) 25.667 ++ { 25.668 ++ /* Print the field, but not the trailing delimiter. */ 25.669 ++ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); 25.670 ++ found_any_selected_field = 1; 25.671 ++ } 25.672 ++ next_item (&field_idx); 25.673 ++ } 25.674 ++ 25.675 ++ if (wc != WEOF) 25.676 ++ { 25.677 ++ if (print_kth (field_idx)) 25.678 ++ { 25.679 ++ if (found_any_selected_field) 25.680 ++ { 25.681 ++ fwrite (output_delimiter_string, sizeof (char), 25.682 ++ output_delimiter_length, stdout); 25.683 ++ } 25.684 ++ found_any_selected_field = 1; 25.685 ++ } 25.686 ++ 25.687 ++ while (1) 25.688 ++ { 25.689 ++ REFILL_BUFFER (buf, bufpos, buflen, stream); 25.690 ++ 25.691 ++ GET_NEXT_WC_FROM_BUFFER 25.692 ++ (wc, bufpos, buflen, mblength, state, convfail); 25.693 ++ 25.694 ++ if (wc == WEOF) 25.695 ++ break; 25.696 ++ else if (!convfail && (wc == wcdelim || wc == line_delim)) 25.697 ++ { 25.698 ++ buflen -= mblength; 25.699 ++ bufpos += mblength; 25.700 ++ break; 25.701 ++ } 25.702 ++ 25.703 ++ if (print_kth (field_idx)) 25.704 ++ fwrite (bufpos, mblength, sizeof(char), stdout); 25.705 ++ 25.706 ++ buflen -= mblength; 25.707 ++ bufpos += mblength; 25.708 ++ } 25.709 ++ } 25.710 ++ 25.711 ++ if ((!convfail || wc == line_delim) && buflen < 1) 25.712 ++ wc = WEOF; 25.713 ++ 25.714 ++ if (!convfail && wc == wcdelim) 25.715 ++ next_item (&field_idx); 25.716 ++ else if (wc == WEOF || (!convfail && wc == line_delim)) 25.717 ++ { 25.718 ++ if (found_any_selected_field 25.719 ++ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) 25.720 ++ putchar (line_delim); 25.721 ++ if (wc == WEOF) 25.722 ++ break; 25.723 ++ field_idx = 1; 25.724 ++ current_rp = frp; 25.725 ++ found_any_selected_field = 0; 25.726 ++ } 25.727 ++ } 25.728 ++} 25.729 ++#endif 25.730 ++ 25.731 + static void 25.732 + cut_stream (FILE *stream) 25.733 + { 25.734 +- if (operating_mode == byte_mode) 25.735 +- cut_bytes (stream); 25.736 ++#if HAVE_MBRTOWC 25.737 ++ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) 25.738 ++ { 25.739 ++ switch (operating_mode) 25.740 ++ { 25.741 ++ case byte_mode: 25.742 ++ if (byte_mode_character_aware) 25.743 ++ cut_characters_or_cut_bytes_no_split (stream); 25.744 ++ else 25.745 ++ cut_bytes (stream); 25.746 ++ break; 25.747 ++ 25.748 ++ case character_mode: 25.749 ++ cut_characters_or_cut_bytes_no_split (stream); 25.750 ++ break; 25.751 ++ 25.752 ++ case field_mode: 25.753 ++ if (delimlen == 1) 25.754 ++ { 25.755 ++ /* Check if we have utf8 multibyte locale, so we can use this 25.756 ++ optimization because of uniqueness of characters, which is 25.757 ++ not true for e.g. SJIS */ 25.758 ++ char * loc = setlocale(LC_CTYPE, NULL); 25.759 ++ if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") || 25.760 ++ strstr (loc, "UTF8") || strstr (loc, "utf8"))) 25.761 ++ { 25.762 ++ cut_fields (stream); 25.763 ++ break; 25.764 ++ } 25.765 ++ } 25.766 ++ cut_fields_mb (stream); 25.767 ++ break; 25.768 ++ 25.769 ++ default: 25.770 ++ abort (); 25.771 ++ } 25.772 ++ } 25.773 + else 25.774 +- cut_fields (stream); 25.775 ++#endif 25.776 ++ { 25.777 ++ if (operating_mode == field_mode) 25.778 ++ cut_fields (stream); 25.779 ++ else 25.780 ++ cut_bytes (stream); 25.781 ++ } 25.782 + } 25.783 + 25.784 + /* Process file FILE to standard output. 25.785 +@@ -483,6 +836,7 @@ main (int argc, char **argv) 25.786 + bool ok; 25.787 + bool delim_specified = false; 25.788 + char *spec_list_string IF_LINT ( = NULL); 25.789 ++ char mbdelim[MB_LEN_MAX + 1]; 25.790 + 25.791 + initialize_main (&argc, &argv); 25.792 + set_program_name (argv[0]); 25.793 +@@ -505,7 +859,6 @@ main (int argc, char **argv) 25.794 + switch (optc) 25.795 + { 25.796 + case 'b': 25.797 +- case 'c': 25.798 + /* Build the byte list. */ 25.799 + if (operating_mode != undefined_mode) 25.800 + FATAL_ERROR (_("only one type of list may be specified")); 25.801 +@@ -513,6 +866,14 @@ main (int argc, char **argv) 25.802 + spec_list_string = optarg; 25.803 + break; 25.804 + 25.805 ++ case 'c': 25.806 ++ /* Build the character list. */ 25.807 ++ if (operating_mode != undefined_mode) 25.808 ++ FATAL_ERROR (_("only one type of list may be specified")); 25.809 ++ operating_mode = character_mode; 25.810 ++ spec_list_string = optarg; 25.811 ++ break; 25.812 ++ 25.813 + case 'f': 25.814 + /* Build the field list. */ 25.815 + if (operating_mode != undefined_mode) 25.816 +@@ -524,10 +885,38 @@ main (int argc, char **argv) 25.817 + case 'd': 25.818 + /* New delimiter. */ 25.819 + /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ 25.820 +- if (optarg[0] != '\0' && optarg[1] != '\0') 25.821 +- FATAL_ERROR (_("the delimiter must be a single character")); 25.822 +- delim = optarg[0]; 25.823 +- delim_specified = true; 25.824 ++ { 25.825 ++#if HAVE_MBRTOWC 25.826 ++ if(MB_CUR_MAX > 1) 25.827 ++ { 25.828 ++ mbstate_t state; 25.829 ++ 25.830 ++ memset (&state, '\0', sizeof(mbstate_t)); 25.831 ++ delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state); 25.832 ++ 25.833 ++ if (delimlen == (size_t)-1 || delimlen == (size_t)-2) 25.834 ++ ++force_singlebyte_mode; 25.835 ++ else 25.836 ++ { 25.837 ++ delimlen = (delimlen < 1) ? 1 : delimlen; 25.838 ++ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') 25.839 ++ FATAL_ERROR (_("the delimiter must be a single character")); 25.840 ++ memcpy (mbdelim, optarg, delimlen); 25.841 ++ mbdelim[delimlen] = '\0'; 25.842 ++ if (delimlen == 1) 25.843 ++ delim = *optarg; 25.844 ++ } 25.845 ++ } 25.846 ++ 25.847 ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) 25.848 ++#endif 25.849 ++ { 25.850 ++ if (optarg[0] != '\0' && optarg[1] != '\0') 25.851 ++ FATAL_ERROR (_("the delimiter must be a single character")); 25.852 ++ delim = (unsigned char) optarg[0]; 25.853 ++ } 25.854 ++ delim_specified = true; 25.855 ++ } 25.856 + break; 25.857 + 25.858 + case OUTPUT_DELIMITER_OPTION: 25.859 +@@ -540,6 +929,7 @@ main (int argc, char **argv) 25.860 + break; 25.861 + 25.862 + case 'n': 25.863 ++ byte_mode_character_aware = 1; 25.864 + break; 25.865 + 25.866 + case 's': 25.867 +@@ -579,15 +969,34 @@ main (int argc, char **argv) 25.868 + | (complement ? SETFLD_COMPLEMENT : 0) ); 25.869 + 25.870 + if (!delim_specified) 25.871 +- delim = '\t'; 25.872 ++ { 25.873 ++ delim = '\t'; 25.874 ++#ifdef HAVE_MBRTOWC 25.875 ++ wcdelim = L'\t'; 25.876 ++ mbdelim[0] = '\t'; 25.877 ++ mbdelim[1] = '\0'; 25.878 ++ delimlen = 1; 25.879 ++#endif 25.880 ++ } 25.881 + 25.882 + if (output_delimiter_string == NULL) 25.883 + { 25.884 +- static char dummy[2]; 25.885 +- dummy[0] = delim; 25.886 +- dummy[1] = '\0'; 25.887 +- output_delimiter_string = dummy; 25.888 +- output_delimiter_length = 1; 25.889 ++#ifdef HAVE_MBRTOWC 25.890 ++ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) 25.891 ++ { 25.892 ++ output_delimiter_string = xstrdup(mbdelim); 25.893 ++ output_delimiter_length = delimlen; 25.894 ++ } 25.895 ++ 25.896 ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) 25.897 ++#endif 25.898 ++ { 25.899 ++ static char dummy[2]; 25.900 ++ dummy[0] = delim; 25.901 ++ dummy[1] = '\0'; 25.902 ++ output_delimiter_string = dummy; 25.903 ++ output_delimiter_length = 1; 25.904 ++ } 25.905 + } 25.906 + 25.907 + if (optind == argc) 25.908 +diff -Naurp coreutils-8.27-orig/src/expand.c coreutils-8.27/src/expand.c 25.909 +--- coreutils-8.27-orig/src/expand.c 2017-02-26 15:42:25.000000000 -0600 25.910 ++++ coreutils-8.27/src/expand.c 2017-03-11 23:49:06.758133530 -0600 25.911 +@@ -37,6 +37,9 @@ 25.912 + #include <stdio.h> 25.913 + #include <getopt.h> 25.914 + #include <sys/types.h> 25.915 ++ 25.916 ++#include <mbfile.h> 25.917 ++ 25.918 + #include "system.h" 25.919 + #include "die.h" 25.920 + #include "xstrndup.h" 25.921 +@@ -100,19 +103,41 @@ expand (void) 25.922 + { 25.923 + /* Input stream. */ 25.924 + FILE *fp = next_file (NULL); 25.925 ++ mb_file_t mbf; 25.926 ++ mbf_char_t c; 25.927 ++ /* True if the starting locale is utf8. */ 25.928 ++ bool using_utf_locale; 25.929 ++ 25.930 ++ /* True if the first file contains BOM header. */ 25.931 ++ bool found_bom; 25.932 ++ using_utf_locale=check_utf_locale(); 25.933 + 25.934 + if (!fp) 25.935 + return; 25.936 ++ mbf_init (mbf, fp); 25.937 ++ found_bom=check_bom(fp,&mbf); 25.938 + 25.939 +- while (true) 25.940 ++ if (using_utf_locale == false && found_bom == true) 25.941 ++ { 25.942 ++ /*try using some predefined locale */ 25.943 ++ 25.944 ++ if (set_utf_locale () != 0) 25.945 + { 25.946 +- /* Input character, or EOF. */ 25.947 +- int c; 25.948 ++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); 25.949 ++ } 25.950 ++ } 25.951 ++ 25.952 + 25.953 ++ if (found_bom == true) 25.954 ++ { 25.955 ++ print_bom(); 25.956 ++ } 25.957 ++ 25.958 ++ while (true) 25.959 ++ { 25.960 + /* If true, perform translations. */ 25.961 + bool convert = true; 25.962 + 25.963 +- 25.964 + /* The following variables have valid values only when CONVERT 25.965 + is true: */ 25.966 + 25.967 +@@ -122,17 +147,48 @@ expand (void) 25.968 + /* Index in TAB_LIST of next tab stop to examine. */ 25.969 + size_t tab_index = 0; 25.970 + 25.971 +- 25.972 + /* Convert a line of text. */ 25.973 + 25.974 + do 25.975 + { 25.976 +- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) 25.977 +- continue; 25.978 ++ while (true) { 25.979 ++ mbf_getc (c, mbf); 25.980 ++ if ((mb_iseof (c)) && (fp = next_file (fp))) 25.981 ++ { 25.982 ++ mbf_init (mbf, fp); 25.983 ++ if (fp!=NULL) 25.984 ++ { 25.985 ++ if (check_bom(fp,&mbf)==true) 25.986 ++ { 25.987 ++ /*Not the first file - check BOM header*/ 25.988 ++ if (using_utf_locale==false && found_bom==false) 25.989 ++ { 25.990 ++ /*BOM header in subsequent file but not in the first one. */ 25.991 ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); 25.992 ++ } 25.993 ++ } 25.994 ++ else 25.995 ++ { 25.996 ++ if(using_utf_locale==false && found_bom==true) 25.997 ++ { 25.998 ++ /*First file conatined BOM header - locale was switched to UTF 25.999 ++ /*all subsequent files should contain BOM. */ 25.1000 ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); 25.1001 ++ } 25.1002 ++ } 25.1003 ++ } 25.1004 ++ continue; 25.1005 ++ } 25.1006 ++ else 25.1007 ++ { 25.1008 ++ break; 25.1009 ++ } 25.1010 ++ } 25.1011 ++ 25.1012 + 25.1013 + if (convert) 25.1014 + { 25.1015 +- if (c == '\t') 25.1016 ++ if (mb_iseq (c, '\t')) 25.1017 + { 25.1018 + /* Column the next input tab stop is on. */ 25.1019 + uintmax_t next_tab_column; 25.1020 +@@ -151,32 +207,34 @@ expand (void) 25.1021 + if (putchar (' ') < 0) 25.1022 + die (EXIT_FAILURE, errno, _("write error")); 25.1023 + 25.1024 +- c = ' '; 25.1025 ++ mb_setascii (&c, ' '); 25.1026 + } 25.1027 +- else if (c == '\b') 25.1028 ++ else if (mb_iseq (c, '\b')) 25.1029 + { 25.1030 + /* Go back one column, and force recalculation of the 25.1031 + next tab stop. */ 25.1032 + column -= !!column; 25.1033 + tab_index -= !!tab_index; 25.1034 + } 25.1035 +- else 25.1036 ++ /* A leading control character could make us trip over. */ 25.1037 ++ else if (!mb_iscntrl (c)) 25.1038 + { 25.1039 +- column++; 25.1040 ++ column += mb_width (c); 25.1041 + if (!column) 25.1042 + die (EXIT_FAILURE, 0, _("input line is too long")); 25.1043 + } 25.1044 + 25.1045 +- convert &= convert_entire_line || !! isblank (c); 25.1046 ++ convert &= convert_entire_line || mb_isblank (c); 25.1047 + } 25.1048 + 25.1049 +- if (c < 0) 25.1050 ++ if (mb_iseof (c)) 25.1051 + return; 25.1052 + 25.1053 +- if (putchar (c) < 0) 25.1054 ++ mb_putc (c, stdout); 25.1055 ++ if (ferror (stdout)) 25.1056 + die (EXIT_FAILURE, errno, _("write error")); 25.1057 + } 25.1058 +- while (c != '\n'); 25.1059 ++ while (!mb_iseq (c, '\n')); 25.1060 + } 25.1061 + } 25.1062 + 25.1063 +diff -Naurp coreutils-8.27-orig/src/expand-common.c coreutils-8.27/src/expand-common.c 25.1064 +--- coreutils-8.27-orig/src/expand-common.c 2017-03-01 11:22:55.000000000 -0600 25.1065 ++++ coreutils-8.27/src/expand-common.c 2017-03-11 23:49:06.757133570 -0600 25.1066 +@@ -18,6 +18,7 @@ 25.1067 + 25.1068 + #include <stdio.h> 25.1069 + #include <sys/types.h> 25.1070 ++#include <mbfile.h> 25.1071 + #include "system.h" 25.1072 + #include "die.h" 25.1073 + #include "error.h" 25.1074 +@@ -105,6 +106,119 @@ set_extend_size (uintmax_t tabval) 25.1075 + return ok; 25.1076 + } 25.1077 + 25.1078 ++extern int 25.1079 ++set_utf_locale (void) 25.1080 ++{ 25.1081 ++ /*try using some predefined locale */ 25.1082 ++ const char* predef_locales[] = {"C.UTF8","en_US.UTF8","en_GB.UTF8"}; 25.1083 ++ 25.1084 ++ const int predef_locales_count=3; 25.1085 ++ for (int i=0;i<predef_locales_count;i++) 25.1086 ++ { 25.1087 ++ if (setlocale(LC_ALL,predef_locales[i])!=NULL) 25.1088 ++ { 25.1089 ++ break; 25.1090 ++ } 25.1091 ++ else if (i==predef_locales_count-1) 25.1092 ++ { 25.1093 ++ return 1; 25.1094 ++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); 25.1095 ++ } 25.1096 ++ } 25.1097 ++ return 0; 25.1098 ++} 25.1099 ++ 25.1100 ++extern bool 25.1101 ++check_utf_locale(void) 25.1102 ++{ 25.1103 ++ char* locale = setlocale (LC_CTYPE , NULL); 25.1104 ++ if (locale == NULL) 25.1105 ++ { 25.1106 ++ return false; 25.1107 ++ } 25.1108 ++ else if (strcasestr(locale, "utf8") == NULL && strcasestr(locale, "utf-8") == NULL) 25.1109 ++ { 25.1110 ++ return false; 25.1111 ++ } 25.1112 ++ return true; 25.1113 ++} 25.1114 ++ 25.1115 ++extern bool 25.1116 ++check_bom(FILE* fp, mb_file_t *mbf) 25.1117 ++{ 25.1118 ++ int c; 25.1119 ++ 25.1120 ++ 25.1121 ++ c=fgetc(fp); 25.1122 ++ 25.1123 ++ /*test BOM header of the first file */ 25.1124 ++ mbf->bufcount=0; 25.1125 ++ if (c == 0xEF) 25.1126 ++ { 25.1127 ++ c=fgetc(fp); 25.1128 ++ } 25.1129 ++ else 25.1130 ++ { 25.1131 ++ if (c != EOF) 25.1132 ++ { 25.1133 ++ ungetc(c,fp); 25.1134 ++ } 25.1135 ++ return false; 25.1136 ++ } 25.1137 ++ 25.1138 ++ if (c == 0xBB) 25.1139 ++ { 25.1140 ++ c=fgetc(fp); 25.1141 ++ } 25.1142 ++ else 25.1143 ++ { 25.1144 ++ if ( c!= EOF ) 25.1145 ++ { 25.1146 ++ mbf->buf[0]=(unsigned char) 0xEF; 25.1147 ++ mbf->bufcount=1; 25.1148 ++ ungetc(c,fp); 25.1149 ++ return false; 25.1150 ++ } 25.1151 ++ else 25.1152 ++ { 25.1153 ++ ungetc(0xEF,fp); 25.1154 ++ return false; 25.1155 ++ } 25.1156 ++ } 25.1157 ++ if (c == 0xBF) 25.1158 ++ { 25.1159 ++ mbf->bufcount=0; 25.1160 ++ return true; 25.1161 ++ } 25.1162 ++ else 25.1163 ++ { 25.1164 ++ if (c != EOF) 25.1165 ++ { 25.1166 ++ mbf->buf[0]=(unsigned char) 0xEF; 25.1167 ++ mbf->buf[1]=(unsigned char) 0xBB; 25.1168 ++ mbf->bufcount=2; 25.1169 ++ ungetc(c,fp); 25.1170 ++ return false; 25.1171 ++ } 25.1172 ++ else 25.1173 ++ { 25.1174 ++ mbf->buf[0]=(unsigned char) 0xEF; 25.1175 ++ mbf->bufcount=1; 25.1176 ++ ungetc(0xBB,fp); 25.1177 ++ return false; 25.1178 ++ } 25.1179 ++ } 25.1180 ++ return false; 25.1181 ++} 25.1182 ++ 25.1183 ++extern void 25.1184 ++print_bom(void) 25.1185 ++{ 25.1186 ++ putc (0xEF, stdout); 25.1187 ++ putc (0xBB, stdout); 25.1188 ++ putc (0xBF, stdout); 25.1189 ++} 25.1190 ++ 25.1191 + /* Add the comma or blank separated list of tab stops STOPS 25.1192 + to the list of tab stops. */ 25.1193 + extern void 25.1194 +diff -Naurp coreutils-8.27-orig/src/expand-common.h coreutils-8.27/src/expand-common.h 25.1195 +--- coreutils-8.27-orig/src/expand-common.h 2017-01-01 16:34:24.000000000 -0600 25.1196 ++++ coreutils-8.27/src/expand-common.h 2017-03-11 23:49:06.758133530 -0600 25.1197 +@@ -34,6 +34,18 @@ extern size_t max_column_width; 25.1198 + /* The desired exit status. */ 25.1199 + extern int exit_status; 25.1200 + 25.1201 ++extern int 25.1202 ++set_utf_locale (void); 25.1203 ++ 25.1204 ++extern bool 25.1205 ++check_utf_locale(void); 25.1206 ++ 25.1207 ++extern bool 25.1208 ++check_bom(FILE* fp, mb_file_t *mbf); 25.1209 ++ 25.1210 ++extern void 25.1211 ++print_bom(void); 25.1212 ++ 25.1213 + /* Add tab stop TABVAL to the end of 'tab_list'. */ 25.1214 + extern void 25.1215 + add_tab_stop (uintmax_t tabval); 25.1216 +diff -Naurp coreutils-8.27-orig/src/fold.c coreutils-8.27/src/fold.c 25.1217 +--- coreutils-8.27-orig/src/fold.c 2017-01-01 16:34:24.000000000 -0600 25.1218 ++++ coreutils-8.27/src/fold.c 2017-03-11 23:49:30.982169404 -0600 25.1219 +@@ -22,12 +22,34 @@ 25.1220 + #include <getopt.h> 25.1221 + #include <sys/types.h> 25.1222 + 25.1223 ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ 25.1224 ++#if HAVE_WCHAR_H 25.1225 ++# include <wchar.h> 25.1226 ++#endif 25.1227 ++ 25.1228 ++/* Get iswprint(), iswblank(), wcwidth(). */ 25.1229 ++#if HAVE_WCTYPE_H 25.1230 ++# include <wctype.h> 25.1231 ++#endif 25.1232 ++ 25.1233 + #include "system.h" 25.1234 + #include "die.h" 25.1235 + #include "error.h" 25.1236 + #include "fadvise.h" 25.1237 + #include "xdectoint.h" 25.1238 + 25.1239 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 25.1240 ++ installation; work around this configuration error. */ 25.1241 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 25.1242 ++# undef MB_LEN_MAX 25.1243 ++# define MB_LEN_MAX 16 25.1244 ++#endif 25.1245 ++ 25.1246 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 25.1247 ++#if HAVE_MBRTOWC && defined mbstate_t 25.1248 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 25.1249 ++#endif 25.1250 ++ 25.1251 + #define TAB_WIDTH 8 25.1252 + 25.1253 + /* The official name of this program (e.g., no 'g' prefix). */ 25.1254 +@@ -35,20 +57,41 @@ 25.1255 + 25.1256 + #define AUTHORS proper_name ("David MacKenzie") 25.1257 + 25.1258 ++#define FATAL_ERROR(Message) \ 25.1259 ++ do \ 25.1260 ++ { \ 25.1261 ++ error (0, 0, (Message)); \ 25.1262 ++ usage (2); \ 25.1263 ++ } \ 25.1264 ++ while (0) 25.1265 ++ 25.1266 ++enum operating_mode 25.1267 ++{ 25.1268 ++ /* Fold texts by columns that are at the given positions. */ 25.1269 ++ column_mode, 25.1270 ++ 25.1271 ++ /* Fold texts by bytes that are at the given positions. */ 25.1272 ++ byte_mode, 25.1273 ++ 25.1274 ++ /* Fold texts by characters that are at the given positions. */ 25.1275 ++ character_mode, 25.1276 ++}; 25.1277 ++ 25.1278 ++/* The argument shows current mode. (Default: column_mode) */ 25.1279 ++static enum operating_mode operating_mode; 25.1280 ++ 25.1281 + /* If nonzero, try to break on whitespace. */ 25.1282 + static bool break_spaces; 25.1283 + 25.1284 +-/* If nonzero, count bytes, not column positions. */ 25.1285 +-static bool count_bytes; 25.1286 +- 25.1287 + /* If nonzero, at least one of the files we read was standard input. */ 25.1288 + static bool have_read_stdin; 25.1289 + 25.1290 +-static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::"; 25.1291 ++static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::"; 25.1292 + 25.1293 + static struct option const longopts[] = 25.1294 + { 25.1295 + {"bytes", no_argument, NULL, 'b'}, 25.1296 ++ {"characters", no_argument, NULL, 'c'}, 25.1297 + {"spaces", no_argument, NULL, 's'}, 25.1298 + {"width", required_argument, NULL, 'w'}, 25.1299 + {GETOPT_HELP_OPTION_DECL}, 25.1300 +@@ -76,6 +119,7 @@ Wrap input lines in each FILE, writing t 25.1301 + 25.1302 + fputs (_("\ 25.1303 + -b, --bytes count bytes rather than columns\n\ 25.1304 ++ -c, --characters count characters rather than columns\n\ 25.1305 + -s, --spaces break at spaces\n\ 25.1306 + -w, --width=WIDTH use WIDTH columns instead of 80\n\ 25.1307 + "), stdout); 25.1308 +@@ -93,7 +137,7 @@ Wrap input lines in each FILE, writing t 25.1309 + static size_t 25.1310 + adjust_column (size_t column, char c) 25.1311 + { 25.1312 +- if (!count_bytes) 25.1313 ++ if (operating_mode != byte_mode) 25.1314 + { 25.1315 + if (c == '\b') 25.1316 + { 25.1317 +@@ -116,30 +160,14 @@ adjust_column (size_t column, char c) 25.1318 + to stdout, with maximum line length WIDTH. 25.1319 + Return true if successful. */ 25.1320 + 25.1321 +-static bool 25.1322 +-fold_file (char const *filename, size_t width) 25.1323 ++static void 25.1324 ++fold_text (FILE *istream, size_t width, int *saved_errno) 25.1325 + { 25.1326 +- FILE *istream; 25.1327 + int c; 25.1328 + size_t column = 0; /* Screen column where next char will go. */ 25.1329 + size_t offset_out = 0; /* Index in 'line_out' for next char. */ 25.1330 + static char *line_out = NULL; 25.1331 + static size_t allocated_out = 0; 25.1332 +- int saved_errno; 25.1333 +- 25.1334 +- if (STREQ (filename, "-")) 25.1335 +- { 25.1336 +- istream = stdin; 25.1337 +- have_read_stdin = true; 25.1338 +- } 25.1339 +- else 25.1340 +- istream = fopen (filename, "r"); 25.1341 +- 25.1342 +- if (istream == NULL) 25.1343 +- { 25.1344 +- error (0, errno, "%s", quotef (filename)); 25.1345 +- return false; 25.1346 +- } 25.1347 + 25.1348 + fadvise (istream, FADVISE_SEQUENTIAL); 25.1349 + 25.1350 +@@ -169,6 +197,15 @@ fold_file (char const *filename, size_t 25.1351 + bool found_blank = false; 25.1352 + size_t logical_end = offset_out; 25.1353 + 25.1354 ++ /* If LINE_OUT has no wide character, 25.1355 ++ put a new wide character in LINE_OUT 25.1356 ++ if column is bigger than width. */ 25.1357 ++ if (offset_out == 0) 25.1358 ++ { 25.1359 ++ line_out[offset_out++] = c; 25.1360 ++ continue; 25.1361 ++ } 25.1362 ++ 25.1363 + /* Look for the last blank. */ 25.1364 + while (logical_end) 25.1365 + { 25.1366 +@@ -215,11 +252,220 @@ fold_file (char const *filename, size_t 25.1367 + line_out[offset_out++] = c; 25.1368 + } 25.1369 + 25.1370 +- saved_errno = errno; 25.1371 ++ *saved_errno = errno; 25.1372 ++ 25.1373 ++ if (offset_out) 25.1374 ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); 25.1375 ++ 25.1376 ++} 25.1377 ++ 25.1378 ++#if HAVE_MBRTOWC 25.1379 ++static void 25.1380 ++fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) 25.1381 ++{ 25.1382 ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 25.1383 ++ size_t buflen = 0; /* The length of the byte sequence in buf. */ 25.1384 ++ char *bufpos = buf; /* Next read position of BUF. */ 25.1385 ++ wint_t wc; /* A gotten wide character. */ 25.1386 ++ size_t mblength; /* The byte size of a multibyte character which shows 25.1387 ++ as same character as WC. */ 25.1388 ++ mbstate_t state, state_bak; /* State of the stream. */ 25.1389 ++ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ 25.1390 ++ 25.1391 ++ static char *line_out = NULL; 25.1392 ++ size_t offset_out = 0; /* Index in `line_out' for next char. */ 25.1393 ++ static size_t allocated_out = 0; 25.1394 ++ 25.1395 ++ int increment; 25.1396 ++ size_t column = 0; 25.1397 ++ 25.1398 ++ size_t last_blank_pos; 25.1399 ++ size_t last_blank_column; 25.1400 ++ int is_blank_seen; 25.1401 ++ int last_blank_increment = 0; 25.1402 ++ int is_bs_following_last_blank; 25.1403 ++ size_t bs_following_last_blank_num; 25.1404 ++ int is_cr_after_last_blank; 25.1405 ++ 25.1406 ++#define CLEAR_FLAGS \ 25.1407 ++ do \ 25.1408 ++ { \ 25.1409 ++ last_blank_pos = 0; \ 25.1410 ++ last_blank_column = 0; \ 25.1411 ++ is_blank_seen = 0; \ 25.1412 ++ is_bs_following_last_blank = 0; \ 25.1413 ++ bs_following_last_blank_num = 0; \ 25.1414 ++ is_cr_after_last_blank = 0; \ 25.1415 ++ } \ 25.1416 ++ while (0) 25.1417 ++ 25.1418 ++#define START_NEW_LINE \ 25.1419 ++ do \ 25.1420 ++ { \ 25.1421 ++ putchar ('\n'); \ 25.1422 ++ column = 0; \ 25.1423 ++ offset_out = 0; \ 25.1424 ++ CLEAR_FLAGS; \ 25.1425 ++ } \ 25.1426 ++ while (0) 25.1427 ++ 25.1428 ++ CLEAR_FLAGS; 25.1429 ++ memset (&state, '\0', sizeof(mbstate_t)); 25.1430 ++ 25.1431 ++ for (;; bufpos += mblength, buflen -= mblength) 25.1432 ++ { 25.1433 ++ if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream)) 25.1434 ++ { 25.1435 ++ memmove (buf, bufpos, buflen); 25.1436 ++ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream); 25.1437 ++ bufpos = buf; 25.1438 ++ } 25.1439 ++ 25.1440 ++ if (buflen < 1) 25.1441 ++ break; 25.1442 ++ 25.1443 ++ /* Get a wide character. */ 25.1444 ++ state_bak = state; 25.1445 ++ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state); 25.1446 ++ 25.1447 ++ switch (mblength) 25.1448 ++ { 25.1449 ++ case (size_t)-1: 25.1450 ++ case (size_t)-2: 25.1451 ++ convfail++; 25.1452 ++ state = state_bak; 25.1453 ++ /* Fall through. */ 25.1454 ++ 25.1455 ++ case 0: 25.1456 ++ mblength = 1; 25.1457 ++ break; 25.1458 ++ } 25.1459 ++ 25.1460 ++rescan: 25.1461 ++ if (convfail) 25.1462 ++ increment = 1; 25.1463 ++ else if (wc == L'\n') 25.1464 ++ { 25.1465 ++ /* preserve newline */ 25.1466 ++ fwrite (line_out, sizeof(char), offset_out, stdout); 25.1467 ++ START_NEW_LINE; 25.1468 ++ continue; 25.1469 ++ } 25.1470 ++ else if (operating_mode == byte_mode) /* byte mode */ 25.1471 ++ increment = mblength; 25.1472 ++ else if (operating_mode == character_mode) /* character mode */ 25.1473 ++ increment = 1; 25.1474 ++ else /* column mode */ 25.1475 ++ { 25.1476 ++ switch (wc) 25.1477 ++ { 25.1478 ++ case L'\b': 25.1479 ++ increment = (column > 0) ? -1 : 0; 25.1480 ++ break; 25.1481 ++ 25.1482 ++ case L'\r': 25.1483 ++ increment = -1 * column; 25.1484 ++ break; 25.1485 ++ 25.1486 ++ case L'\t': 25.1487 ++ increment = 8 - column % 8; 25.1488 ++ break; 25.1489 ++ 25.1490 ++ default: 25.1491 ++ increment = wcwidth (wc); 25.1492 ++ increment = (increment < 0) ? 0 : increment; 25.1493 ++ } 25.1494 ++ } 25.1495 ++ 25.1496 ++ if (column + increment > width && break_spaces && last_blank_pos) 25.1497 ++ { 25.1498 ++ fwrite (line_out, sizeof(char), last_blank_pos, stdout); 25.1499 ++ putchar ('\n'); 25.1500 ++ 25.1501 ++ offset_out = offset_out - last_blank_pos; 25.1502 ++ column = column - last_blank_column + ((is_cr_after_last_blank) 25.1503 ++ ? last_blank_increment : bs_following_last_blank_num); 25.1504 ++ memmove (line_out, line_out + last_blank_pos, offset_out); 25.1505 ++ CLEAR_FLAGS; 25.1506 ++ goto rescan; 25.1507 ++ } 25.1508 ++ 25.1509 ++ if (column + increment > width && column != 0) 25.1510 ++ { 25.1511 ++ fwrite (line_out, sizeof(char), offset_out, stdout); 25.1512 ++ START_NEW_LINE; 25.1513 ++ goto rescan; 25.1514 ++ } 25.1515 ++ 25.1516 ++ if (allocated_out < offset_out + mblength) 25.1517 ++ { 25.1518 ++ line_out = X2REALLOC (line_out, &allocated_out); 25.1519 ++ } 25.1520 ++ 25.1521 ++ memcpy (line_out + offset_out, bufpos, mblength); 25.1522 ++ offset_out += mblength; 25.1523 ++ column += increment; 25.1524 ++ 25.1525 ++ if (is_blank_seen && !convfail && wc == L'\r') 25.1526 ++ is_cr_after_last_blank = 1; 25.1527 ++ 25.1528 ++ if (is_bs_following_last_blank && !convfail && wc == L'\b') 25.1529 ++ ++bs_following_last_blank_num; 25.1530 ++ else 25.1531 ++ is_bs_following_last_blank = 0; 25.1532 ++ 25.1533 ++ if (break_spaces && !convfail && iswblank (wc)) 25.1534 ++ { 25.1535 ++ last_blank_pos = offset_out; 25.1536 ++ last_blank_column = column; 25.1537 ++ is_blank_seen = 1; 25.1538 ++ last_blank_increment = increment; 25.1539 ++ is_bs_following_last_blank = 1; 25.1540 ++ bs_following_last_blank_num = 0; 25.1541 ++ is_cr_after_last_blank = 0; 25.1542 ++ } 25.1543 ++ } 25.1544 ++ 25.1545 ++ *saved_errno = errno; 25.1546 + 25.1547 + if (offset_out) 25.1548 + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); 25.1549 + 25.1550 ++} 25.1551 ++#endif 25.1552 ++ 25.1553 ++/* Fold file FILENAME, or standard input if FILENAME is "-", 25.1554 ++ to stdout, with maximum line length WIDTH. 25.1555 ++ Return 0 if successful, 1 if an error occurs. */ 25.1556 ++ 25.1557 ++static bool 25.1558 ++fold_file (char const *filename, size_t width) 25.1559 ++{ 25.1560 ++ FILE *istream; 25.1561 ++ int saved_errno; 25.1562 ++ 25.1563 ++ if (STREQ (filename, "-")) 25.1564 ++ { 25.1565 ++ istream = stdin; 25.1566 ++ have_read_stdin = 1; 25.1567 ++ } 25.1568 ++ else 25.1569 ++ istream = fopen (filename, "r"); 25.1570 ++ 25.1571 ++ if (istream == NULL) 25.1572 ++ { 25.1573 ++ error (0, errno, "%s", filename); 25.1574 ++ return 1; 25.1575 ++ } 25.1576 ++ 25.1577 ++ /* Define how ISTREAM is being folded. */ 25.1578 ++#if HAVE_MBRTOWC 25.1579 ++ if (MB_CUR_MAX > 1) 25.1580 ++ fold_multibyte_text (istream, width, &saved_errno); 25.1581 ++ else 25.1582 ++#endif 25.1583 ++ fold_text (istream, width, &saved_errno); 25.1584 ++ 25.1585 + if (ferror (istream)) 25.1586 + { 25.1587 + error (0, saved_errno, "%s", quotef (filename)); 25.1588 +@@ -252,7 +498,8 @@ main (int argc, char **argv) 25.1589 + 25.1590 + atexit (close_stdout); 25.1591 + 25.1592 +- break_spaces = count_bytes = have_read_stdin = false; 25.1593 ++ operating_mode = column_mode; 25.1594 ++ break_spaces = have_read_stdin = false; 25.1595 + 25.1596 + while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) 25.1597 + { 25.1598 +@@ -261,7 +508,15 @@ main (int argc, char **argv) 25.1599 + switch (optc) 25.1600 + { 25.1601 + case 'b': /* Count bytes rather than columns. */ 25.1602 +- count_bytes = true; 25.1603 ++ if (operating_mode != column_mode) 25.1604 ++ FATAL_ERROR (_("only one way of folding may be specified")); 25.1605 ++ operating_mode = byte_mode; 25.1606 ++ break; 25.1607 ++ 25.1608 ++ case 'c': 25.1609 ++ if (operating_mode != column_mode) 25.1610 ++ FATAL_ERROR (_("only one way of folding may be specified")); 25.1611 ++ operating_mode = character_mode; 25.1612 + break; 25.1613 + 25.1614 + case 's': /* Break at word boundaries. */ 25.1615 +diff -Naurp coreutils-8.27-orig/src/join.c coreutils-8.27/src/join.c 25.1616 +--- coreutils-8.27-orig/src/join.c 2017-01-01 16:34:24.000000000 -0600 25.1617 ++++ coreutils-8.27/src/join.c 2017-03-11 23:47:13.091286290 -0600 25.1618 +@@ -22,19 +22,33 @@ 25.1619 + #include <sys/types.h> 25.1620 + #include <getopt.h> 25.1621 + 25.1622 ++/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth(). */ 25.1623 ++#if HAVE_WCHAR_H 25.1624 ++# include <wchar.h> 25.1625 ++#endif 25.1626 ++ 25.1627 ++/* Get iswblank(), towupper. */ 25.1628 ++#if HAVE_WCTYPE_H 25.1629 ++# include <wctype.h> 25.1630 ++#endif 25.1631 ++ 25.1632 + #include "system.h" 25.1633 + #include "die.h" 25.1634 + #include "error.h" 25.1635 + #include "fadvise.h" 25.1636 + #include "hard-locale.h" 25.1637 + #include "linebuffer.h" 25.1638 +-#include "memcasecmp.h" 25.1639 + #include "quote.h" 25.1640 + #include "stdio--.h" 25.1641 + #include "xmemcoll.h" 25.1642 + #include "xstrtol.h" 25.1643 + #include "argmatch.h" 25.1644 + 25.1645 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 25.1646 ++#if HAVE_MBRTOWC && defined mbstate_t 25.1647 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 25.1648 ++#endif 25.1649 ++ 25.1650 + /* The official name of this program (e.g., no 'g' prefix). */ 25.1651 + #define PROGRAM_NAME "join" 25.1652 + 25.1653 +@@ -136,10 +150,12 @@ static struct outlist outlist_head; 25.1654 + /* Last element in 'outlist', where a new element can be added. */ 25.1655 + static struct outlist *outlist_end = &outlist_head; 25.1656 + 25.1657 +-/* Tab character separating fields. If negative, fields are separated 25.1658 +- by any nonempty string of blanks, otherwise by exactly one 25.1659 +- tab character whose value (when cast to unsigned char) equals TAB. */ 25.1660 +-static int tab = -1; 25.1661 ++/* Tab character separating fields. If NULL, fields are separated 25.1662 ++ by any nonempty string of blanks. */ 25.1663 ++static char *tab = NULL; 25.1664 ++ 25.1665 ++/* The number of bytes used for tab. */ 25.1666 ++static size_t tablen = 0; 25.1667 + 25.1668 + /* If nonzero, check that the input is correctly ordered. */ 25.1669 + static enum 25.1670 +@@ -276,13 +292,14 @@ xfields (struct line *line) 25.1671 + if (ptr == lim) 25.1672 + return; 25.1673 + 25.1674 +- if (0 <= tab && tab != '\n') 25.1675 ++ if (tab != NULL) 25.1676 + { 25.1677 ++ unsigned char t = tab[0]; 25.1678 + char *sep; 25.1679 +- for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1) 25.1680 ++ for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1) 25.1681 + extract_field (line, ptr, sep - ptr); 25.1682 + } 25.1683 +- else if (tab < 0) 25.1684 ++ else 25.1685 + { 25.1686 + /* Skip leading blanks before the first field. */ 25.1687 + while (field_sep (*ptr)) 25.1688 +@@ -306,6 +323,147 @@ xfields (struct line *line) 25.1689 + extract_field (line, ptr, lim - ptr); 25.1690 + } 25.1691 + 25.1692 ++#if HAVE_MBRTOWC 25.1693 ++static void 25.1694 ++xfields_multibyte (struct line *line) 25.1695 ++{ 25.1696 ++ char *ptr = line->buf.buffer; 25.1697 ++ char const *lim = ptr + line->buf.length - 1; 25.1698 ++ wchar_t wc = 0; 25.1699 ++ size_t mblength = 1; 25.1700 ++ mbstate_t state, state_bak; 25.1701 ++ 25.1702 ++ memset (&state, 0, sizeof (mbstate_t)); 25.1703 ++ 25.1704 ++ if (ptr >= lim) 25.1705 ++ return; 25.1706 ++ 25.1707 ++ if (tab != NULL) 25.1708 ++ { 25.1709 ++ char *sep = ptr; 25.1710 ++ for (; ptr < lim; ptr = sep + mblength) 25.1711 ++ { 25.1712 ++ sep = ptr; 25.1713 ++ while (sep < lim) 25.1714 ++ { 25.1715 ++ state_bak = state; 25.1716 ++ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 25.1717 ++ 25.1718 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 25.1719 ++ { 25.1720 ++ mblength = 1; 25.1721 ++ state = state_bak; 25.1722 ++ } 25.1723 ++ mblength = (mblength < 1) ? 1 : mblength; 25.1724 ++ 25.1725 ++ if (mblength == tablen && !memcmp (sep, tab, mblength)) 25.1726 ++ break; 25.1727 ++ else 25.1728 ++ { 25.1729 ++ sep += mblength; 25.1730 ++ continue; 25.1731 ++ } 25.1732 ++ } 25.1733 ++ 25.1734 ++ if (sep >= lim) 25.1735 ++ break; 25.1736 ++ 25.1737 ++ extract_field (line, ptr, sep - ptr); 25.1738 ++ } 25.1739 ++ } 25.1740 ++ else 25.1741 ++ { 25.1742 ++ /* Skip leading blanks before the first field. */ 25.1743 ++ while(ptr < lim) 25.1744 ++ { 25.1745 ++ state_bak = state; 25.1746 ++ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 25.1747 ++ 25.1748 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 25.1749 ++ { 25.1750 ++ mblength = 1; 25.1751 ++ state = state_bak; 25.1752 ++ break; 25.1753 ++ } 25.1754 ++ mblength = (mblength < 1) ? 1 : mblength; 25.1755 ++ 25.1756 ++ if (!iswblank(wc) && wc != '\n') 25.1757 ++ break; 25.1758 ++ ptr += mblength; 25.1759 ++ } 25.1760 ++ 25.1761 ++ do 25.1762 ++ { 25.1763 ++ char *sep; 25.1764 ++ state_bak = state; 25.1765 ++ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 25.1766 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 25.1767 ++ { 25.1768 ++ mblength = 1; 25.1769 ++ state = state_bak; 25.1770 ++ break; 25.1771 ++ } 25.1772 ++ mblength = (mblength < 1) ? 1 : mblength; 25.1773 ++ 25.1774 ++ sep = ptr + mblength; 25.1775 ++ while (sep < lim) 25.1776 ++ { 25.1777 ++ state_bak = state; 25.1778 ++ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 25.1779 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 25.1780 ++ { 25.1781 ++ mblength = 1; 25.1782 ++ state = state_bak; 25.1783 ++ break; 25.1784 ++ } 25.1785 ++ mblength = (mblength < 1) ? 1 : mblength; 25.1786 ++ 25.1787 ++ if (iswblank (wc) || wc == '\n') 25.1788 ++ break; 25.1789 ++ 25.1790 ++ sep += mblength; 25.1791 ++ } 25.1792 ++ 25.1793 ++ extract_field (line, ptr, sep - ptr); 25.1794 ++ if (sep >= lim) 25.1795 ++ return; 25.1796 ++ 25.1797 ++ state_bak = state; 25.1798 ++ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 25.1799 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 25.1800 ++ { 25.1801 ++ mblength = 1; 25.1802 ++ state = state_bak; 25.1803 ++ break; 25.1804 ++ } 25.1805 ++ mblength = (mblength < 1) ? 1 : mblength; 25.1806 ++ 25.1807 ++ ptr = sep + mblength; 25.1808 ++ while (ptr < lim) 25.1809 ++ { 25.1810 ++ state_bak = state; 25.1811 ++ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 25.1812 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 25.1813 ++ { 25.1814 ++ mblength = 1; 25.1815 ++ state = state_bak; 25.1816 ++ break; 25.1817 ++ } 25.1818 ++ mblength = (mblength < 1) ? 1 : mblength; 25.1819 ++ 25.1820 ++ if (!iswblank (wc) && wc != '\n') 25.1821 ++ break; 25.1822 ++ 25.1823 ++ ptr += mblength; 25.1824 ++ } 25.1825 ++ } 25.1826 ++ while (ptr < lim); 25.1827 ++ } 25.1828 ++ 25.1829 ++ extract_field (line, ptr, lim - ptr); 25.1830 ++} 25.1831 ++#endif 25.1832 ++ 25.1833 + static void 25.1834 + freeline (struct line *line) 25.1835 + { 25.1836 +@@ -327,56 +485,133 @@ keycmp (struct line const *line1, struct 25.1837 + size_t jf_1, size_t jf_2) 25.1838 + { 25.1839 + /* Start of field to compare in each file. */ 25.1840 +- char *beg1; 25.1841 +- char *beg2; 25.1842 +- 25.1843 +- size_t len1; 25.1844 +- size_t len2; /* Length of fields to compare. */ 25.1845 ++ char *beg[2]; 25.1846 ++ char *copy[2]; 25.1847 ++ size_t len[2]; /* Length of fields to compare. */ 25.1848 + int diff; 25.1849 ++ int i, j; 25.1850 ++ int mallocd = 0; 25.1851 + 25.1852 + if (jf_1 < line1->nfields) 25.1853 + { 25.1854 +- beg1 = line1->fields[jf_1].beg; 25.1855 +- len1 = line1->fields[jf_1].len; 25.1856 ++ beg[0] = line1->fields[jf_1].beg; 25.1857 ++ len[0] = line1->fields[jf_1].len; 25.1858 + } 25.1859 + else 25.1860 + { 25.1861 +- beg1 = NULL; 25.1862 +- len1 = 0; 25.1863 ++ beg[0] = NULL; 25.1864 ++ len[0] = 0; 25.1865 + } 25.1866 + 25.1867 + if (jf_2 < line2->nfields) 25.1868 + { 25.1869 +- beg2 = line2->fields[jf_2].beg; 25.1870 +- len2 = line2->fields[jf_2].len; 25.1871 ++ beg[1] = line2->fields[jf_2].beg; 25.1872 ++ len[1] = line2->fields[jf_2].len; 25.1873 + } 25.1874 + else 25.1875 + { 25.1876 +- beg2 = NULL; 25.1877 +- len2 = 0; 25.1878 ++ beg[1] = NULL; 25.1879 ++ len[1] = 0; 25.1880 + } 25.1881 + 25.1882 +- if (len1 == 0) 25.1883 +- return len2 == 0 ? 0 : -1; 25.1884 +- if (len2 == 0) 25.1885 ++ if (len[0] == 0) 25.1886 ++ return len[1] == 0 ? 0 : -1; 25.1887 ++ if (len[1] == 0) 25.1888 + return 1; 25.1889 + 25.1890 + if (ignore_case) 25.1891 + { 25.1892 +- /* FIXME: ignore_case does not work with NLS (in particular, 25.1893 +- with multibyte chars). */ 25.1894 +- diff = memcasecmp (beg1, beg2, MIN (len1, len2)); 25.1895 ++#ifdef HAVE_MBRTOWC 25.1896 ++ if (MB_CUR_MAX > 1) 25.1897 ++ { 25.1898 ++ size_t mblength; 25.1899 ++ wchar_t wc, uwc; 25.1900 ++ mbstate_t state, state_bak; 25.1901 ++ 25.1902 ++ memset (&state, '\0', sizeof (mbstate_t)); 25.1903 ++ 25.1904 ++ for (i = 0; i < 2; i++) 25.1905 ++ { 25.1906 ++ mallocd = 1; 25.1907 ++ copy[i] = xmalloc (len[i] + 1); 25.1908 ++ memset (copy[i], '\0',len[i] + 1); 25.1909 ++ 25.1910 ++ for (j = 0; j < MIN (len[0], len[1]);) 25.1911 ++ { 25.1912 ++ state_bak = state; 25.1913 ++ mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state); 25.1914 ++ 25.1915 ++ switch (mblength) 25.1916 ++ { 25.1917 ++ case (size_t) -1: 25.1918 ++ case (size_t) -2: 25.1919 ++ state = state_bak; 25.1920 ++ /* Fall through */ 25.1921 ++ case 0: 25.1922 ++ mblength = 1; 25.1923 ++ break; 25.1924 ++ 25.1925 ++ default: 25.1926 ++ uwc = towupper (wc); 25.1927 ++ 25.1928 ++ if (uwc != wc) 25.1929 ++ { 25.1930 ++ mbstate_t state_wc; 25.1931 ++ size_t mblen; 25.1932 ++ 25.1933 ++ memset (&state_wc, '\0', sizeof (mbstate_t)); 25.1934 ++ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); 25.1935 ++ assert (mblen != (size_t)-1); 25.1936 ++ } 25.1937 ++ else 25.1938 ++ memcpy (copy[i] + j, beg[i] + j, mblength); 25.1939 ++ } 25.1940 ++ j += mblength; 25.1941 ++ } 25.1942 ++ copy[i][j] = '\0'; 25.1943 ++ } 25.1944 ++ } 25.1945 ++ else 25.1946 ++#endif 25.1947 ++ { 25.1948 ++ for (i = 0; i < 2; i++) 25.1949 ++ { 25.1950 ++ mallocd = 1; 25.1951 ++ copy[i] = xmalloc (len[i] + 1); 25.1952 ++ 25.1953 ++ for (j = 0; j < MIN (len[0], len[1]); j++) 25.1954 ++ copy[i][j] = toupper (beg[i][j]); 25.1955 ++ 25.1956 ++ copy[i][j] = '\0'; 25.1957 ++ } 25.1958 ++ } 25.1959 + } 25.1960 + else 25.1961 + { 25.1962 +- if (hard_LC_COLLATE) 25.1963 +- return xmemcoll (beg1, len1, beg2, len2); 25.1964 +- diff = memcmp (beg1, beg2, MIN (len1, len2)); 25.1965 ++ copy[0] = beg[0]; 25.1966 ++ copy[1] = beg[1]; 25.1967 + } 25.1968 + 25.1969 ++ if (hard_LC_COLLATE) 25.1970 ++ { 25.1971 ++ diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); 25.1972 ++ 25.1973 ++ if (mallocd) 25.1974 ++ for (i = 0; i < 2; i++) 25.1975 ++ free (copy[i]); 25.1976 ++ 25.1977 ++ return diff; 25.1978 ++ } 25.1979 ++ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); 25.1980 ++ 25.1981 ++ if (mallocd) 25.1982 ++ for (i = 0; i < 2; i++) 25.1983 ++ free (copy[i]); 25.1984 ++ 25.1985 ++ 25.1986 + if (diff) 25.1987 + return diff; 25.1988 +- return len1 < len2 ? -1 : len1 != len2; 25.1989 ++ return len[0] - len[1]; 25.1990 + } 25.1991 + 25.1992 + /* Check that successive input lines PREV and CURRENT from input file 25.1993 +@@ -468,6 +703,11 @@ get_line (FILE *fp, struct line **linep, 25.1994 + } 25.1995 + ++line_no[which - 1]; 25.1996 + 25.1997 ++#if HAVE_MBRTOWC 25.1998 ++ if (MB_CUR_MAX > 1) 25.1999 ++ xfields_multibyte (line); 25.2000 ++ else 25.2001 ++#endif 25.2002 + xfields (line); 25.2003 + 25.2004 + if (prevline[which - 1]) 25.2005 +@@ -567,21 +807,28 @@ prfield (size_t n, struct line const *li 25.2006 + 25.2007 + /* Output all the fields in line, other than the join field. */ 25.2008 + 25.2009 ++#define PUT_TAB_CHAR \ 25.2010 ++ do \ 25.2011 ++ { \ 25.2012 ++ (tab != NULL) ? \ 25.2013 ++ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ 25.2014 ++ } \ 25.2015 ++ while (0) 25.2016 ++ 25.2017 + static void 25.2018 + prfields (struct line const *line, size_t join_field, size_t autocount) 25.2019 + { 25.2020 + size_t i; 25.2021 + size_t nfields = autoformat ? autocount : line->nfields; 25.2022 +- char output_separator = tab < 0 ? ' ' : tab; 25.2023 + 25.2024 + for (i = 0; i < join_field && i < nfields; ++i) 25.2025 + { 25.2026 +- putchar (output_separator); 25.2027 ++ PUT_TAB_CHAR; 25.2028 + prfield (i, line); 25.2029 + } 25.2030 + for (i = join_field + 1; i < nfields; ++i) 25.2031 + { 25.2032 +- putchar (output_separator); 25.2033 ++ PUT_TAB_CHAR; 25.2034 + prfield (i, line); 25.2035 + } 25.2036 + } 25.2037 +@@ -592,7 +839,6 @@ static void 25.2038 + prjoin (struct line const *line1, struct line const *line2) 25.2039 + { 25.2040 + const struct outlist *outlist; 25.2041 +- char output_separator = tab < 0 ? ' ' : tab; 25.2042 + size_t field; 25.2043 + struct line const *line; 25.2044 + 25.2045 +@@ -626,7 +872,7 @@ prjoin (struct line const *line1, struct 25.2046 + o = o->next; 25.2047 + if (o == NULL) 25.2048 + break; 25.2049 +- putchar (output_separator); 25.2050 ++ PUT_TAB_CHAR; 25.2051 + } 25.2052 + putchar (eolchar); 25.2053 + } 25.2054 +@@ -1104,20 +1350,43 @@ main (int argc, char **argv) 25.2055 + 25.2056 + case 't': 25.2057 + { 25.2058 +- unsigned char newtab = optarg[0]; 25.2059 ++ char *newtab = NULL; 25.2060 ++ size_t newtablen; 25.2061 ++ newtab = xstrdup (optarg); 25.2062 ++#if HAVE_MBRTOWC 25.2063 ++ if (MB_CUR_MAX > 1) 25.2064 ++ { 25.2065 ++ mbstate_t state; 25.2066 ++ 25.2067 ++ memset (&state, 0, sizeof (mbstate_t)); 25.2068 ++ newtablen = mbrtowc (NULL, newtab, 25.2069 ++ strnlen (newtab, MB_LEN_MAX), 25.2070 ++ &state); 25.2071 ++ if (newtablen == (size_t) 0 25.2072 ++ || newtablen == (size_t) -1 25.2073 ++ || newtablen == (size_t) -2) 25.2074 ++ newtablen = 1; 25.2075 ++ } 25.2076 ++ else 25.2077 ++#endif 25.2078 ++ newtablen = 1; 25.2079 + if (! newtab) 25.2080 +- newtab = '\n'; /* '' => process the whole line. */ 25.2081 ++ newtab = (char*)"\n"; /* '' => process the whole line. */ 25.2082 + else if (optarg[1]) 25.2083 + { 25.2084 +- if (STREQ (optarg, "\\0")) 25.2085 +- newtab = '\0'; 25.2086 +- else 25.2087 +- die (EXIT_FAILURE, 0, _("multi-character tab %s"), 25.2088 +- quote (optarg)); 25.2089 ++ if (newtablen == 1 && newtab[1]) 25.2090 ++ { 25.2091 ++ if (STREQ (newtab, "\\0")) 25.2092 ++ newtab[0] = '\0'; 25.2093 ++ } 25.2094 ++ } 25.2095 ++ if (tab != NULL && strcmp (tab, newtab)) 25.2096 ++ { 25.2097 ++ free (newtab); 25.2098 ++ die (EXIT_FAILURE, 0, _("incompatible tabs")); 25.2099 + } 25.2100 +- if (0 <= tab && tab != newtab) 25.2101 +- die (EXIT_FAILURE, 0, _("incompatible tabs")); 25.2102 + tab = newtab; 25.2103 ++ tablen = newtablen; 25.2104 + } 25.2105 + break; 25.2106 + 25.2107 +diff -Naurp coreutils-8.27-orig/src/pr.c coreutils-8.27/src/pr.c 25.2108 +--- coreutils-8.27-orig/src/pr.c 2017-01-01 16:34:24.000000000 -0600 25.2109 ++++ coreutils-8.27/src/pr.c 2017-03-11 23:47:13.094286139 -0600 25.2110 +@@ -311,6 +311,24 @@ 25.2111 + 25.2112 + #include <getopt.h> 25.2113 + #include <sys/types.h> 25.2114 ++ 25.2115 ++/* Get MB_LEN_MAX. */ 25.2116 ++#include <limits.h> 25.2117 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 25.2118 ++ installation; work around this configuration error. */ 25.2119 ++#if !defined MB_LEN_MAX || MB_LEN_MAX == 1 25.2120 ++# define MB_LEN_MAX 16 25.2121 ++#endif 25.2122 ++ 25.2123 ++/* Get MB_CUR_MAX. */ 25.2124 ++#include <stdlib.h> 25.2125 ++ 25.2126 ++/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */ 25.2127 ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ 25.2128 ++#if HAVE_WCHAR_H 25.2129 ++# include <wchar.h> 25.2130 ++#endif 25.2131 ++ 25.2132 + #include "system.h" 25.2133 + #include "die.h" 25.2134 + #include "error.h" 25.2135 +@@ -324,6 +342,18 @@ 25.2136 + #include "xstrtol.h" 25.2137 + #include "xdectoint.h" 25.2138 + 25.2139 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 25.2140 ++#if HAVE_MBRTOWC && defined mbstate_t 25.2141 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 25.2142 ++#endif 25.2143 ++ 25.2144 ++#ifndef HAVE_DECL_WCWIDTH 25.2145 ++"this configure-time declaration test was not run" 25.2146 ++#endif 25.2147 ++#if !HAVE_DECL_WCWIDTH 25.2148 ++extern int wcwidth (); 25.2149 ++#endif 25.2150 ++ 25.2151 + /* The official name of this program (e.g., no 'g' prefix). */ 25.2152 + #define PROGRAM_NAME "pr" 25.2153 + 25.2154 +@@ -416,7 +446,20 @@ struct COLUMN 25.2155 + 25.2156 + typedef struct COLUMN COLUMN; 25.2157 + 25.2158 +-static int char_to_clump (char c); 25.2159 ++/* Funtion pointers to switch functions for single byte locale or for 25.2160 ++ multibyte locale. If multibyte functions do not exist in your sysytem, 25.2161 ++ these pointers always point the function for single byte locale. */ 25.2162 ++static void (*print_char) (char c); 25.2163 ++static int (*char_to_clump) (char c); 25.2164 ++ 25.2165 ++/* Functions for single byte locale. */ 25.2166 ++static void print_char_single (char c); 25.2167 ++static int char_to_clump_single (char c); 25.2168 ++ 25.2169 ++/* Functions for multibyte locale. */ 25.2170 ++static void print_char_multi (char c); 25.2171 ++static int char_to_clump_multi (char c); 25.2172 ++ 25.2173 + static bool read_line (COLUMN *p); 25.2174 + static bool print_page (void); 25.2175 + static bool print_stored (COLUMN *p); 25.2176 +@@ -428,6 +471,7 @@ static void add_line_number (COLUMN *p); 25.2177 + static void getoptnum (const char *n_str, int min, int *num, 25.2178 + const char *errfmt); 25.2179 + static void getoptarg (char *arg, char switch_char, char *character, 25.2180 ++ int *character_length, int *character_width, 25.2181 + int *number); 25.2182 + static void print_files (int number_of_files, char **av); 25.2183 + static void init_parameters (int number_of_files); 25.2184 +@@ -441,7 +485,6 @@ static void store_char (char c); 25.2185 + static void pad_down (unsigned int lines); 25.2186 + static void read_rest_of_line (COLUMN *p); 25.2187 + static void skip_read (COLUMN *p, int column_number); 25.2188 +-static void print_char (char c); 25.2189 + static void cleanup (void); 25.2190 + static void print_sep_string (void); 25.2191 + static void separator_string (const char *optarg_S); 25.2192 +@@ -453,7 +496,7 @@ static COLUMN *column_vector; 25.2193 + we store the leftmost columns contiguously in buff. 25.2194 + To print a line from buff, get the index of the first character 25.2195 + from line_vector[i], and print up to line_vector[i + 1]. */ 25.2196 +-static char *buff; 25.2197 ++static unsigned char *buff; 25.2198 + 25.2199 + /* Index of the position in buff where the next character 25.2200 + will be stored. */ 25.2201 +@@ -557,7 +600,7 @@ static int chars_per_column; 25.2202 + static bool untabify_input = false; 25.2203 + 25.2204 + /* (-e) The input tab character. */ 25.2205 +-static char input_tab_char = '\t'; 25.2206 ++static char input_tab_char[MB_LEN_MAX] = "\t"; 25.2207 + 25.2208 + /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... 25.2209 + where the leftmost column is 1. */ 25.2210 +@@ -567,7 +610,10 @@ static int chars_per_input_tab = 8; 25.2211 + static bool tabify_output = false; 25.2212 + 25.2213 + /* (-i) The output tab character. */ 25.2214 +-static char output_tab_char = '\t'; 25.2215 ++static char output_tab_char[MB_LEN_MAX] = "\t"; 25.2216 ++ 25.2217 ++/* (-i) The byte length of output tab character. */ 25.2218 ++static int output_tab_char_length = 1; 25.2219 + 25.2220 + /* (-i) The width of the output tab. */ 25.2221 + static int chars_per_output_tab = 8; 25.2222 +@@ -637,7 +683,13 @@ static int line_number; 25.2223 + static bool numbered_lines = false; 25.2224 + 25.2225 + /* (-n) Character which follows each line number. */ 25.2226 +-static char number_separator = '\t'; 25.2227 ++static char number_separator[MB_LEN_MAX] = "\t"; 25.2228 ++ 25.2229 ++/* (-n) The byte length of the character which follows each line number. */ 25.2230 ++static int number_separator_length = 1; 25.2231 ++ 25.2232 ++/* (-n) The character width of the character which follows each line number. */ 25.2233 ++static int number_separator_width = 0; 25.2234 + 25.2235 + /* (-n) line counting starts with 1st line of input file (not with 1st 25.2236 + line of 1st page printed). */ 25.2237 +@@ -690,6 +742,7 @@ static bool use_col_separator = false; 25.2238 + -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ 25.2239 + static char const *col_sep_string = ""; 25.2240 + static int col_sep_length = 0; 25.2241 ++static int col_sep_width = 0; 25.2242 + static char *column_separator = (char *) " "; 25.2243 + static char *line_separator = (char *) "\t"; 25.2244 + 25.2245 +@@ -851,6 +904,13 @@ separator_string (const char *optarg_S) 25.2246 + integer_overflow (); 25.2247 + col_sep_length = len; 25.2248 + col_sep_string = optarg_S; 25.2249 ++ 25.2250 ++#if HAVE_MBRTOWC 25.2251 ++ if (MB_CUR_MAX > 1) 25.2252 ++ col_sep_width = mbswidth (col_sep_string, 0); 25.2253 ++ else 25.2254 ++#endif 25.2255 ++ col_sep_width = col_sep_length; 25.2256 + } 25.2257 + 25.2258 + int 25.2259 +@@ -875,6 +935,21 @@ main (int argc, char **argv) 25.2260 + 25.2261 + atexit (close_stdout); 25.2262 + 25.2263 ++/* Define which functions are used, the ones for single byte locale or the ones 25.2264 ++ for multibyte locale. */ 25.2265 ++#if HAVE_MBRTOWC 25.2266 ++ if (MB_CUR_MAX > 1) 25.2267 ++ { 25.2268 ++ print_char = print_char_multi; 25.2269 ++ char_to_clump = char_to_clump_multi; 25.2270 ++ } 25.2271 ++ else 25.2272 ++#endif 25.2273 ++ { 25.2274 ++ print_char = print_char_single; 25.2275 ++ char_to_clump = char_to_clump_single; 25.2276 ++ } 25.2277 ++ 25.2278 + n_files = 0; 25.2279 + file_names = (argc > 1 25.2280 + ? xnmalloc (argc - 1, sizeof (char *)) 25.2281 +@@ -951,8 +1026,12 @@ main (int argc, char **argv) 25.2282 + break; 25.2283 + case 'e': 25.2284 + if (optarg) 25.2285 +- getoptarg (optarg, 'e', &input_tab_char, 25.2286 +- &chars_per_input_tab); 25.2287 ++ { 25.2288 ++ int dummy_length, dummy_width; 25.2289 ++ 25.2290 ++ getoptarg (optarg, 'e', input_tab_char, &dummy_length, 25.2291 ++ &dummy_width, &chars_per_input_tab); 25.2292 ++ } 25.2293 + /* Could check tab width > 0. */ 25.2294 + untabify_input = true; 25.2295 + break; 25.2296 +@@ -965,8 +1044,12 @@ main (int argc, char **argv) 25.2297 + break; 25.2298 + case 'i': 25.2299 + if (optarg) 25.2300 +- getoptarg (optarg, 'i', &output_tab_char, 25.2301 +- &chars_per_output_tab); 25.2302 ++ { 25.2303 ++ int dummy_width; 25.2304 ++ 25.2305 ++ getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length, 25.2306 ++ &dummy_width, &chars_per_output_tab); 25.2307 ++ } 25.2308 + /* Could check tab width > 0. */ 25.2309 + tabify_output = true; 25.2310 + break; 25.2311 +@@ -984,8 +1067,8 @@ main (int argc, char **argv) 25.2312 + case 'n': 25.2313 + numbered_lines = true; 25.2314 + if (optarg) 25.2315 +- getoptarg (optarg, 'n', &number_separator, 25.2316 +- &chars_per_number); 25.2317 ++ getoptarg (optarg, 'n', number_separator, &number_separator_length, 25.2318 ++ &number_separator_width, &chars_per_number); 25.2319 + break; 25.2320 + case 'N': 25.2321 + skip_count = false; 25.2322 +@@ -1010,6 +1093,7 @@ main (int argc, char **argv) 25.2323 + /* Reset an additional input of -s, -S dominates -s */ 25.2324 + col_sep_string = ""; 25.2325 + col_sep_length = 0; 25.2326 ++ col_sep_width = 0; 25.2327 + use_col_separator = true; 25.2328 + if (optarg) 25.2329 + separator_string (optarg); 25.2330 +@@ -1166,10 +1250,45 @@ getoptnum (const char *n_str, int min, i 25.2331 + a number. */ 25.2332 + 25.2333 + static void 25.2334 +-getoptarg (char *arg, char switch_char, char *character, int *number) 25.2335 ++getoptarg (char *arg, char switch_char, char *character, int *character_length, 25.2336 ++ int *character_width, int *number) 25.2337 + { 25.2338 + if (!ISDIGIT (*arg)) 25.2339 +- *character = *arg++; 25.2340 ++ { 25.2341 ++#ifdef HAVE_MBRTOWC 25.2342 ++ if (MB_CUR_MAX > 1) /* for multibyte locale. */ 25.2343 ++ { 25.2344 ++ wchar_t wc; 25.2345 ++ size_t mblength; 25.2346 ++ int width; 25.2347 ++ mbstate_t state = {'\0'}; 25.2348 ++ 25.2349 ++ mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state); 25.2350 ++ 25.2351 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 25.2352 ++ { 25.2353 ++ *character_length = 1; 25.2354 ++ *character_width = 1; 25.2355 ++ } 25.2356 ++ else 25.2357 ++ { 25.2358 ++ *character_length = (mblength < 1) ? 1 : mblength; 25.2359 ++ width = wcwidth (wc); 25.2360 ++ *character_width = (width < 0) ? 0 : width; 25.2361 ++ } 25.2362 ++ 25.2363 ++ strncpy (character, arg, *character_length); 25.2364 ++ arg += *character_length; 25.2365 ++ } 25.2366 ++ else /* for single byte locale. */ 25.2367 ++#endif 25.2368 ++ { 25.2369 ++ *character = *arg++; 25.2370 ++ *character_length = 1; 25.2371 ++ *character_width = 1; 25.2372 ++ } 25.2373 ++ } 25.2374 ++ 25.2375 + if (*arg) 25.2376 + { 25.2377 + long int tmp_long; 25.2378 +@@ -1191,6 +1310,11 @@ static void 25.2379 + init_parameters (int number_of_files) 25.2380 + { 25.2381 + int chars_used_by_number = 0; 25.2382 ++ int mb_len = 1; 25.2383 ++#if HAVE_MBRTOWC 25.2384 ++ if (MB_CUR_MAX > 1) 25.2385 ++ mb_len = MB_LEN_MAX; 25.2386 ++#endif 25.2387 + 25.2388 + lines_per_body = lines_per_page - lines_per_header - lines_per_footer; 25.2389 + if (lines_per_body <= 0) 25.2390 +@@ -1228,7 +1352,7 @@ init_parameters (int number_of_files) 25.2391 + else 25.2392 + col_sep_string = column_separator; 25.2393 + 25.2394 +- col_sep_length = 1; 25.2395 ++ col_sep_length = col_sep_width = 1; 25.2396 + use_col_separator = true; 25.2397 + } 25.2398 + /* It's rather pointless to define a TAB separator with column 25.2399 +@@ -1258,11 +1382,11 @@ init_parameters (int number_of_files) 25.2400 + + TAB_WIDTH (chars_per_input_tab, chars_per_number); */ 25.2401 + 25.2402 + /* Estimate chars_per_text without any margin and keep it constant. */ 25.2403 +- if (number_separator == '\t') 25.2404 ++ if (number_separator[0] == '\t') 25.2405 + number_width = (chars_per_number 25.2406 + + TAB_WIDTH (chars_per_default_tab, chars_per_number)); 25.2407 + else 25.2408 +- number_width = chars_per_number + 1; 25.2409 ++ number_width = chars_per_number + number_separator_width; 25.2410 + 25.2411 + /* The number is part of the column width unless we are 25.2412 + printing files in parallel. */ 25.2413 +@@ -1271,7 +1395,7 @@ init_parameters (int number_of_files) 25.2414 + } 25.2415 + 25.2416 + int sep_chars, useful_chars; 25.2417 +- if (INT_MULTIPLY_WRAPV (columns - 1, col_sep_length, &sep_chars)) 25.2418 ++ if (INT_MULTIPLY_WRAPV (columns - 1, col_sep_width, &sep_chars)) 25.2419 + sep_chars = INT_MAX; 25.2420 + if (INT_SUBTRACT_WRAPV (chars_per_line - chars_used_by_number, sep_chars, 25.2421 + &useful_chars)) 25.2422 +@@ -1294,7 +1418,7 @@ init_parameters (int number_of_files) 25.2423 + We've to use 8 as the lower limit, if we use chars_per_default_tab = 8 25.2424 + to expand a tab which is not an input_tab-char. */ 25.2425 + free (clump_buff); 25.2426 +- clump_buff = xmalloc (MAX (8, chars_per_input_tab)); 25.2427 ++ clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab)); 25.2428 + } 25.2429 + 25.2430 + /* Open the necessary files, 25.2431 +@@ -1402,7 +1526,7 @@ init_funcs (void) 25.2432 + 25.2433 + /* Enlarge p->start_position of first column to use the same form of 25.2434 + padding_not_printed with all columns. */ 25.2435 +- h = h + col_sep_length; 25.2436 ++ h = h + col_sep_width; 25.2437 + 25.2438 + /* This loop takes care of all but the rightmost column. */ 25.2439 + 25.2440 +@@ -1436,7 +1560,7 @@ init_funcs (void) 25.2441 + } 25.2442 + else 25.2443 + { 25.2444 +- h = h_next + col_sep_length; 25.2445 ++ h = h_next + col_sep_width; 25.2446 + h_next = h + chars_per_column; 25.2447 + } 25.2448 + } 25.2449 +@@ -1727,9 +1851,9 @@ static void 25.2450 + align_column (COLUMN *p) 25.2451 + { 25.2452 + padding_not_printed = p->start_position; 25.2453 +- if (col_sep_length < padding_not_printed) 25.2454 ++ if (col_sep_width < padding_not_printed) 25.2455 + { 25.2456 +- pad_across_to (padding_not_printed - col_sep_length); 25.2457 ++ pad_across_to (padding_not_printed - col_sep_width); 25.2458 + padding_not_printed = ANYWHERE; 25.2459 + } 25.2460 + 25.2461 +@@ -2004,13 +2128,13 @@ store_char (char c) 25.2462 + /* May be too generous. */ 25.2463 + buff = X2REALLOC (buff, &buff_allocated); 25.2464 + } 25.2465 +- buff[buff_current++] = c; 25.2466 ++ buff[buff_current++] = (unsigned char) c; 25.2467 + } 25.2468 + 25.2469 + static void 25.2470 + add_line_number (COLUMN *p) 25.2471 + { 25.2472 +- int i; 25.2473 ++ int i, j; 25.2474 + char *s; 25.2475 + int num_width; 25.2476 + 25.2477 +@@ -2027,22 +2151,24 @@ add_line_number (COLUMN *p) 25.2478 + /* Tabification is assumed for multiple columns, also for n-separators, 25.2479 + but 'default n-separator = TAB' hasn't been given priority over 25.2480 + equal column_width also specified by POSIX. */ 25.2481 +- if (number_separator == '\t') 25.2482 ++ if (number_separator[0] == '\t') 25.2483 + { 25.2484 + i = number_width - chars_per_number; 25.2485 + while (i-- > 0) 25.2486 + (p->char_func) (' '); 25.2487 + } 25.2488 + else 25.2489 +- (p->char_func) (number_separator); 25.2490 ++ for (j = 0; j < number_separator_length; j++) 25.2491 ++ (p->char_func) (number_separator[j]); 25.2492 + } 25.2493 + else 25.2494 + /* To comply with POSIX, we avoid any expansion of default TAB 25.2495 + separator with a single column output. No column_width requirement 25.2496 + has to be considered. */ 25.2497 + { 25.2498 +- (p->char_func) (number_separator); 25.2499 +- if (number_separator == '\t') 25.2500 ++ for (j = 0; j < number_separator_length; j++) 25.2501 ++ (p->char_func) (number_separator[j]); 25.2502 ++ if (number_separator[0] == '\t') 25.2503 + output_position = POS_AFTER_TAB (chars_per_output_tab, 25.2504 + output_position); 25.2505 + } 25.2506 +@@ -2203,7 +2329,7 @@ print_white_space (void) 25.2507 + while (goal - h_old > 1 25.2508 + && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) 25.2509 + { 25.2510 +- putchar (output_tab_char); 25.2511 ++ fwrite (output_tab_char, sizeof(char), output_tab_char_length, stdout); 25.2512 + h_old = h_new; 25.2513 + } 25.2514 + while (++h_old <= goal) 25.2515 +@@ -2223,6 +2349,7 @@ print_sep_string (void) 25.2516 + { 25.2517 + char const *s = col_sep_string; 25.2518 + int l = col_sep_length; 25.2519 ++ int not_space_flag; 25.2520 + 25.2521 + if (separators_not_printed <= 0) 25.2522 + { 25.2523 +@@ -2234,6 +2361,7 @@ print_sep_string (void) 25.2524 + { 25.2525 + for (; separators_not_printed > 0; --separators_not_printed) 25.2526 + { 25.2527 ++ not_space_flag = 0; 25.2528 + while (l-- > 0) 25.2529 + { 25.2530 + /* 3 types of sep_strings: spaces only, spaces and chars, 25.2531 +@@ -2247,12 +2375,15 @@ print_sep_string (void) 25.2532 + } 25.2533 + else 25.2534 + { 25.2535 ++ not_space_flag = 1; 25.2536 + if (spaces_not_printed > 0) 25.2537 + print_white_space (); 25.2538 + putchar (*s++); 25.2539 +- ++output_position; 25.2540 + } 25.2541 + } 25.2542 ++ if (not_space_flag) 25.2543 ++ output_position += col_sep_width; 25.2544 ++ 25.2545 + /* sep_string ends with some spaces */ 25.2546 + if (spaces_not_printed > 0) 25.2547 + print_white_space (); 25.2548 +@@ -2280,7 +2411,7 @@ print_clump (COLUMN *p, int n, char *clu 25.2549 + required number of tabs and spaces. */ 25.2550 + 25.2551 + static void 25.2552 +-print_char (char c) 25.2553 ++print_char_single (char c) 25.2554 + { 25.2555 + if (tabify_output) 25.2556 + { 25.2557 +@@ -2304,6 +2435,74 @@ print_char (char c) 25.2558 + putchar (c); 25.2559 + } 25.2560 + 25.2561 ++#ifdef HAVE_MBRTOWC 25.2562 ++static void 25.2563 ++print_char_multi (char c) 25.2564 ++{ 25.2565 ++ static size_t mbc_pos = 0; 25.2566 ++ static char mbc[MB_LEN_MAX] = {'\0'}; 25.2567 ++ static mbstate_t state = {'\0'}; 25.2568 ++ mbstate_t state_bak; 25.2569 ++ wchar_t wc; 25.2570 ++ size_t mblength; 25.2571 ++ int width; 25.2572 ++ 25.2573 ++ if (tabify_output) 25.2574 ++ { 25.2575 ++ state_bak = state; 25.2576 ++ mbc[mbc_pos++] = c; 25.2577 ++ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); 25.2578 ++ 25.2579 ++ while (mbc_pos > 0) 25.2580 ++ { 25.2581 ++ switch (mblength) 25.2582 ++ { 25.2583 ++ case (size_t)-2: 25.2584 ++ state = state_bak; 25.2585 ++ return; 25.2586 ++ 25.2587 ++ case (size_t)-1: 25.2588 ++ state = state_bak; 25.2589 ++ ++output_position; 25.2590 ++ putchar (mbc[0]); 25.2591 ++ memmove (mbc, mbc + 1, MB_CUR_MAX - 1); 25.2592 ++ --mbc_pos; 25.2593 ++ break; 25.2594 ++ 25.2595 ++ case 0: 25.2596 ++ mblength = 1; 25.2597 ++ 25.2598 ++ default: 25.2599 ++ if (wc == L' ') 25.2600 ++ { 25.2601 ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 25.2602 ++ --mbc_pos; 25.2603 ++ ++spaces_not_printed; 25.2604 ++ return; 25.2605 ++ } 25.2606 ++ else if (spaces_not_printed > 0) 25.2607 ++ print_white_space (); 25.2608 ++ 25.2609 ++ /* Nonprintables are assumed to have width 0, except L'\b'. */ 25.2610 ++ if ((width = wcwidth (wc)) < 1) 25.2611 ++ { 25.2612 ++ if (wc == L'\b') 25.2613 ++ --output_position; 25.2614 ++ } 25.2615 ++ else 25.2616 ++ output_position += width; 25.2617 ++ 25.2618 ++ fwrite (mbc, sizeof(char), mblength, stdout); 25.2619 ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 25.2620 ++ mbc_pos -= mblength; 25.2621 ++ } 25.2622 ++ } 25.2623 ++ return; 25.2624 ++ } 25.2625 ++ putchar (c); 25.2626 ++} 25.2627 ++#endif 25.2628 ++ 25.2629 + /* Skip to page PAGE before printing. 25.2630 + PAGE may be larger than total number of pages. */ 25.2631 + 25.2632 +@@ -2483,9 +2682,9 @@ read_line (COLUMN *p) 25.2633 + align_empty_cols = false; 25.2634 + } 25.2635 + 25.2636 +- if (col_sep_length < padding_not_printed) 25.2637 ++ if (col_sep_width < padding_not_printed) 25.2638 + { 25.2639 +- pad_across_to (padding_not_printed - col_sep_length); 25.2640 ++ pad_across_to (padding_not_printed - col_sep_width); 25.2641 + padding_not_printed = ANYWHERE; 25.2642 + } 25.2643 + 25.2644 +@@ -2555,7 +2754,7 @@ print_stored (COLUMN *p) 25.2645 + int i; 25.2646 + 25.2647 + int line = p->current_line++; 25.2648 +- char *first = &buff[line_vector[line]]; 25.2649 ++ unsigned char *first = &buff[line_vector[line]]; 25.2650 + /* FIXME 25.2651 + UMR: Uninitialized memory read: 25.2652 + * This is occurring while in: 25.2653 +@@ -2567,7 +2766,7 @@ print_stored (COLUMN *p) 25.2654 + xmalloc [xmalloc.c:94] 25.2655 + init_store_cols [pr.c:1648] 25.2656 + */ 25.2657 +- char *last = &buff[line_vector[line + 1]]; 25.2658 ++ unsigned char *last = &buff[line_vector[line + 1]]; 25.2659 + 25.2660 + pad_vertically = true; 25.2661 + 25.2662 +@@ -2586,9 +2785,9 @@ print_stored (COLUMN *p) 25.2663 + } 25.2664 + } 25.2665 + 25.2666 +- if (col_sep_length < padding_not_printed) 25.2667 ++ if (col_sep_width < padding_not_printed) 25.2668 + { 25.2669 +- pad_across_to (padding_not_printed - col_sep_length); 25.2670 ++ pad_across_to (padding_not_printed - col_sep_width); 25.2671 + padding_not_printed = ANYWHERE; 25.2672 + } 25.2673 + 25.2674 +@@ -2601,8 +2800,8 @@ print_stored (COLUMN *p) 25.2675 + if (spaces_not_printed == 0) 25.2676 + { 25.2677 + output_position = p->start_position + end_vector[line]; 25.2678 +- if (p->start_position - col_sep_length == chars_per_margin) 25.2679 +- output_position -= col_sep_length; 25.2680 ++ if (p->start_position - col_sep_width == chars_per_margin) 25.2681 ++ output_position -= col_sep_width; 25.2682 + } 25.2683 + 25.2684 + return true; 25.2685 +@@ -2621,7 +2820,7 @@ print_stored (COLUMN *p) 25.2686 + number of characters is 1.) */ 25.2687 + 25.2688 + static int 25.2689 +-char_to_clump (char c) 25.2690 ++char_to_clump_single (char c) 25.2691 + { 25.2692 + unsigned char uc = c; 25.2693 + char *s = clump_buff; 25.2694 +@@ -2631,10 +2830,10 @@ char_to_clump (char c) 25.2695 + int chars; 25.2696 + int chars_per_c = 8; 25.2697 + 25.2698 +- if (c == input_tab_char) 25.2699 ++ if (c == input_tab_char[0]) 25.2700 + chars_per_c = chars_per_input_tab; 25.2701 + 25.2702 +- if (c == input_tab_char || c == '\t') 25.2703 ++ if (c == input_tab_char[0] || c == '\t') 25.2704 + { 25.2705 + width = TAB_WIDTH (chars_per_c, input_position); 25.2706 + 25.2707 +@@ -2715,6 +2914,164 @@ char_to_clump (char c) 25.2708 + return chars; 25.2709 + } 25.2710 + 25.2711 ++#ifdef HAVE_MBRTOWC 25.2712 ++static int 25.2713 ++char_to_clump_multi (char c) 25.2714 ++{ 25.2715 ++ static size_t mbc_pos = 0; 25.2716 ++ static char mbc[MB_LEN_MAX] = {'\0'}; 25.2717 ++ static mbstate_t state = {'\0'}; 25.2718 ++ mbstate_t state_bak; 25.2719 ++ wchar_t wc; 25.2720 ++ size_t mblength; 25.2721 ++ int wc_width; 25.2722 ++ register char *s = clump_buff; 25.2723 ++ register int i, j; 25.2724 ++ char esc_buff[4]; 25.2725 ++ int width; 25.2726 ++ int chars; 25.2727 ++ int chars_per_c = 8; 25.2728 ++ 25.2729 ++ state_bak = state; 25.2730 ++ mbc[mbc_pos++] = c; 25.2731 ++ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); 25.2732 ++ 25.2733 ++ width = 0; 25.2734 ++ chars = 0; 25.2735 ++ while (mbc_pos > 0) 25.2736 ++ { 25.2737 ++ switch (mblength) 25.2738 ++ { 25.2739 ++ case (size_t)-2: 25.2740 ++ state = state_bak; 25.2741 ++ return 0; 25.2742 ++ 25.2743 ++ case (size_t)-1: 25.2744 ++ state = state_bak; 25.2745 ++ mblength = 1; 25.2746 ++ 25.2747 ++ if (use_esc_sequence || use_cntrl_prefix) 25.2748 ++ { 25.2749 ++ width = +4; 25.2750 ++ chars = +4; 25.2751 ++ *s++ = '\\'; 25.2752 ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[0]); 25.2753 ++ for (i = 0; i <= 2; ++i) 25.2754 ++ *s++ = (int) esc_buff[i]; 25.2755 ++ } 25.2756 ++ else 25.2757 ++ { 25.2758 ++ width += 1; 25.2759 ++ chars += 1; 25.2760 ++ *s++ = mbc[0]; 25.2761 ++ } 25.2762 ++ break; 25.2763 ++ 25.2764 ++ case 0: 25.2765 ++ mblength = 1; 25.2766 ++ /* Fall through */ 25.2767 ++ 25.2768 ++ default: 25.2769 ++ if (memcmp (mbc, input_tab_char, mblength) == 0) 25.2770 ++ chars_per_c = chars_per_input_tab; 25.2771 ++ 25.2772 ++ if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t') 25.2773 ++ { 25.2774 ++ int width_inc; 25.2775 ++ 25.2776 ++ width_inc = TAB_WIDTH (chars_per_c, input_position); 25.2777 ++ width += width_inc; 25.2778 ++ 25.2779 ++ if (untabify_input) 25.2780 ++ { 25.2781 ++ for (i = width_inc; i; --i) 25.2782 ++ *s++ = ' '; 25.2783 ++ chars += width_inc; 25.2784 ++ } 25.2785 ++ else 25.2786 ++ { 25.2787 ++ for (i = 0; i < mblength; i++) 25.2788 ++ *s++ = mbc[i]; 25.2789 ++ chars += mblength; 25.2790 ++ } 25.2791 ++ } 25.2792 ++ else if ((wc_width = wcwidth (wc)) < 1) 25.2793 ++ { 25.2794 ++ if (use_esc_sequence) 25.2795 ++ { 25.2796 ++ for (i = 0; i < mblength; i++) 25.2797 ++ { 25.2798 ++ width += 4; 25.2799 ++ chars += 4; 25.2800 ++ *s++ = '\\'; 25.2801 ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); 25.2802 ++ for (j = 0; j <= 2; ++j) 25.2803 ++ *s++ = (int) esc_buff[j]; 25.2804 ++ } 25.2805 ++ } 25.2806 ++ else if (use_cntrl_prefix) 25.2807 ++ { 25.2808 ++ if (wc < 0200) 25.2809 ++ { 25.2810 ++ width += 2; 25.2811 ++ chars += 2; 25.2812 ++ *s++ = '^'; 25.2813 ++ *s++ = wc ^ 0100; 25.2814 ++ } 25.2815 ++ else 25.2816 ++ { 25.2817 ++ for (i = 0; i < mblength; i++) 25.2818 ++ { 25.2819 ++ width += 4; 25.2820 ++ chars += 4; 25.2821 ++ *s++ = '\\'; 25.2822 ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); 25.2823 ++ for (j = 0; j <= 2; ++j) 25.2824 ++ *s++ = (int) esc_buff[j]; 25.2825 ++ } 25.2826 ++ } 25.2827 ++ } 25.2828 ++ else if (wc == L'\b') 25.2829 ++ { 25.2830 ++ width += -1; 25.2831 ++ chars += 1; 25.2832 ++ *s++ = c; 25.2833 ++ } 25.2834 ++ else 25.2835 ++ { 25.2836 ++ width += 0; 25.2837 ++ chars += mblength; 25.2838 ++ for (i = 0; i < mblength; i++) 25.2839 ++ *s++ = mbc[i]; 25.2840 ++ } 25.2841 ++ } 25.2842 ++ else 25.2843 ++ { 25.2844 ++ width += wc_width; 25.2845 ++ chars += mblength; 25.2846 ++ for (i = 0; i < mblength; i++) 25.2847 ++ *s++ = mbc[i]; 25.2848 ++ } 25.2849 ++ } 25.2850 ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 25.2851 ++ mbc_pos -= mblength; 25.2852 ++ } 25.2853 ++ 25.2854 ++ /* Too many backspaces must put us in position 0 -- never negative. */ 25.2855 ++ if (width < 0 && input_position == 0) 25.2856 ++ { 25.2857 ++ chars = 0; 25.2858 ++ input_position = 0; 25.2859 ++ } 25.2860 ++ else if (width < 0 && input_position <= -width) 25.2861 ++ input_position = 0; 25.2862 ++ else 25.2863 ++ input_position += width; 25.2864 ++ 25.2865 ++ return chars; 25.2866 ++} 25.2867 ++#endif 25.2868 ++ 25.2869 + /* We've just printed some files and need to clean up things before 25.2870 + looking for more options and printing the next batch of files. 25.2871 + 25.2872 +diff -Naurp coreutils-8.27-orig/src/sort.c coreutils-8.27/src/sort.c 25.2873 +--- coreutils-8.27-orig/src/sort.c 2017-01-01 16:34:24.000000000 -0600 25.2874 ++++ coreutils-8.27/src/sort.c 2017-03-11 23:49:22.416505389 -0600 25.2875 +@@ -29,6 +29,14 @@ 25.2876 + #include <sys/wait.h> 25.2877 + #include <signal.h> 25.2878 + #include <assert.h> 25.2879 ++#if HAVE_WCHAR_H 25.2880 ++# include <wchar.h> 25.2881 ++#endif 25.2882 ++/* Get isw* functions. */ 25.2883 ++#if HAVE_WCTYPE_H 25.2884 ++# include <wctype.h> 25.2885 ++#endif 25.2886 ++ 25.2887 + #include "system.h" 25.2888 + #include "argmatch.h" 25.2889 + #include "die.h" 25.2890 +@@ -165,14 +173,39 @@ static int decimal_point; 25.2891 + /* Thousands separator; if -1, then there isn't one. */ 25.2892 + static int thousands_sep; 25.2893 + 25.2894 ++/* True if -f is specified. */ 25.2895 ++static bool folding; 25.2896 ++ 25.2897 + /* Nonzero if the corresponding locales are hard. */ 25.2898 + static bool hard_LC_COLLATE; 25.2899 +-#if HAVE_NL_LANGINFO 25.2900 ++#if HAVE_LANGINFO_CODESET 25.2901 + static bool hard_LC_TIME; 25.2902 + #endif 25.2903 + 25.2904 + #define NONZERO(x) ((x) != 0) 25.2905 + 25.2906 ++/* get a multibyte character's byte length. */ 25.2907 ++#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE) \ 25.2908 ++ do \ 25.2909 ++ { \ 25.2910 ++ wchar_t wc; \ 25.2911 ++ mbstate_t state_bak; \ 25.2912 ++ \ 25.2913 ++ state_bak = STATE; \ 25.2914 ++ mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE); \ 25.2915 ++ \ 25.2916 ++ switch (MBLENGTH) \ 25.2917 ++ { \ 25.2918 ++ case (size_t)-1: \ 25.2919 ++ case (size_t)-2: \ 25.2920 ++ STATE = state_bak; \ 25.2921 ++ /* Fall through. */ \ 25.2922 ++ case 0: \ 25.2923 ++ MBLENGTH = 1; \ 25.2924 ++ } \ 25.2925 ++ } \ 25.2926 ++ while (0) 25.2927 ++ 25.2928 + /* The kind of blanks for '-b' to skip in various options. */ 25.2929 + enum blanktype { bl_start, bl_end, bl_both }; 25.2930 + 25.2931 +@@ -346,13 +379,11 @@ static bool reverse; 25.2932 + they were read if all keys compare equal. */ 25.2933 + static bool stable; 25.2934 + 25.2935 +-/* If TAB has this value, blanks separate fields. */ 25.2936 +-enum { TAB_DEFAULT = CHAR_MAX + 1 }; 25.2937 +- 25.2938 +-/* Tab character separating fields. If TAB_DEFAULT, then fields are 25.2939 ++/* Tab character separating fields. If tab_length is 0, then fields are 25.2940 + separated by the empty string between a non-blank character and a blank 25.2941 + character. */ 25.2942 +-static int tab = TAB_DEFAULT; 25.2943 ++static char tab[MB_LEN_MAX + 1]; 25.2944 ++static size_t tab_length = 0; 25.2945 + 25.2946 + /* Flag to remove consecutive duplicate lines from the output. 25.2947 + Only the last of a sequence of equal lines will be output. */ 25.2948 +@@ -811,6 +842,46 @@ reap_all (void) 25.2949 + reap (-1); 25.2950 + } 25.2951 + 25.2952 ++/* Function pointers. */ 25.2953 ++static void 25.2954 ++(*inittables) (void); 25.2955 ++static char * 25.2956 ++(*begfield) (const struct line*, const struct keyfield *); 25.2957 ++static char * 25.2958 ++(*limfield) (const struct line*, const struct keyfield *); 25.2959 ++static void 25.2960 ++(*skipblanks) (char **ptr, char *lim); 25.2961 ++static int 25.2962 ++(*getmonth) (char const *, size_t, char **); 25.2963 ++static int 25.2964 ++(*keycompare) (const struct line *, const struct line *); 25.2965 ++static int 25.2966 ++(*numcompare) (const char *, const char *); 25.2967 ++ 25.2968 ++/* Test for white space multibyte character. 25.2969 ++ Set LENGTH the byte length of investigated multibyte character. */ 25.2970 ++#if HAVE_MBRTOWC 25.2971 ++static int 25.2972 ++ismbblank (const char *str, size_t len, size_t *length) 25.2973 ++{ 25.2974 ++ size_t mblength; 25.2975 ++ wchar_t wc; 25.2976 ++ mbstate_t state; 25.2977 ++ 25.2978 ++ memset (&state, '\0', sizeof(mbstate_t)); 25.2979 ++ mblength = mbrtowc (&wc, str, len, &state); 25.2980 ++ 25.2981 ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) 25.2982 ++ { 25.2983 ++ *length = 1; 25.2984 ++ return 0; 25.2985 ++ } 25.2986 ++ 25.2987 ++ *length = (mblength < 1) ? 1 : mblength; 25.2988 ++ return iswblank (wc) || wc == '\n'; 25.2989 ++} 25.2990 ++#endif 25.2991 ++ 25.2992 + /* Clean up any remaining temporary files. */ 25.2993 + 25.2994 + static void 25.2995 +@@ -1255,7 +1326,7 @@ zaptemp (char const *name) 25.2996 + free (node); 25.2997 + } 25.2998 + 25.2999 +-#if HAVE_NL_LANGINFO 25.3000 ++#if HAVE_LANGINFO_CODESET 25.3001 + 25.3002 + static int 25.3003 + struct_month_cmp (void const *m1, void const *m2) 25.3004 +@@ -1270,7 +1341,7 @@ struct_month_cmp (void const *m1, void c 25.3005 + /* Initialize the character class tables. */ 25.3006 + 25.3007 + static void 25.3008 +-inittables (void) 25.3009 ++inittables_uni (void) 25.3010 + { 25.3011 + size_t i; 25.3012 + 25.3013 +@@ -1282,7 +1353,7 @@ inittables (void) 25.3014 + fold_toupper[i] = toupper (i); 25.3015 + } 25.3016 + 25.3017 +-#if HAVE_NL_LANGINFO 25.3018 ++#if HAVE_LANGINFO_CODESET 25.3019 + /* If we're not in the "C" locale, read different names for months. */ 25.3020 + if (hard_LC_TIME) 25.3021 + { 25.3022 +@@ -1364,6 +1435,84 @@ specify_nmerge (int oi, char c, char con 25.3023 + xstrtol_fatal (e, oi, c, long_options, s); 25.3024 + } 25.3025 + 25.3026 ++#if HAVE_MBRTOWC 25.3027 ++static void 25.3028 ++inittables_mb (void) 25.3029 ++{ 25.3030 ++ int i, j, k, l; 25.3031 ++ char *name, *s, *lc_time, *lc_ctype; 25.3032 ++ size_t s_len, mblength; 25.3033 ++ char mbc[MB_LEN_MAX]; 25.3034 ++ wchar_t wc, pwc; 25.3035 ++ mbstate_t state_mb, state_wc; 25.3036 ++ 25.3037 ++ lc_time = setlocale (LC_TIME, ""); 25.3038 ++ if (lc_time) 25.3039 ++ lc_time = xstrdup (lc_time); 25.3040 ++ 25.3041 ++ lc_ctype = setlocale (LC_CTYPE, ""); 25.3042 ++ if (lc_ctype) 25.3043 ++ lc_ctype = xstrdup (lc_ctype); 25.3044 ++ 25.3045 ++ if (lc_time && lc_ctype) 25.3046 ++ /* temporarily set LC_CTYPE to match LC_TIME, so that we can convert 25.3047 ++ * the names of months to upper case */ 25.3048 ++ setlocale (LC_CTYPE, lc_time); 25.3049 ++ 25.3050 ++ for (i = 0; i < MONTHS_PER_YEAR; i++) 25.3051 ++ { 25.3052 ++ s = (char *) nl_langinfo (ABMON_1 + i); 25.3053 ++ s_len = strlen (s); 25.3054 ++ monthtab[i].name = name = (char *) xmalloc (s_len + 1); 25.3055 ++ monthtab[i].val = i + 1; 25.3056 ++ 25.3057 ++ memset (&state_mb, '\0', sizeof (mbstate_t)); 25.3058 ++ memset (&state_wc, '\0', sizeof (mbstate_t)); 25.3059 ++ 25.3060 ++ for (j = 0; j < s_len;) 25.3061 ++ { 25.3062 ++ if (!ismbblank (s + j, s_len - j, &mblength)) 25.3063 ++ break; 25.3064 ++ j += mblength; 25.3065 ++ } 25.3066 ++ 25.3067 ++ for (k = 0; j < s_len;) 25.3068 ++ { 25.3069 ++ mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb); 25.3070 ++ assert (mblength != (size_t)-1 && mblength != (size_t)-2); 25.3071 ++ if (mblength == 0) 25.3072 ++ break; 25.3073 ++ 25.3074 ++ pwc = towupper (wc); 25.3075 ++ if (pwc == wc) 25.3076 ++ { 25.3077 ++ memcpy (mbc, s + j, mblength); 25.3078 ++ j += mblength; 25.3079 ++ } 25.3080 ++ else 25.3081 ++ { 25.3082 ++ j += mblength; 25.3083 ++ mblength = wcrtomb (mbc, pwc, &state_wc); 25.3084 ++ assert (mblength != (size_t)0 && mblength != (size_t)-1); 25.3085 ++ } 25.3086 ++ 25.3087 ++ for (l = 0; l < mblength; l++) 25.3088 ++ name[k++] = mbc[l]; 25.3089 ++ } 25.3090 ++ name[k] = '\0'; 25.3091 ++ } 25.3092 ++ qsort ((void *) monthtab, MONTHS_PER_YEAR, 25.3093 ++ sizeof (struct month), struct_month_cmp); 25.3094 ++ 25.3095 ++ if (lc_time && lc_ctype) 25.3096 ++ /* restore the original locales */ 25.3097 ++ setlocale (LC_CTYPE, lc_ctype); 25.3098 ++ 25.3099 ++ free (lc_ctype); 25.3100 ++ free (lc_time); 25.3101 ++} 25.3102 ++#endif 25.3103 ++ 25.3104 + /* Specify the amount of main memory to use when sorting. */ 25.3105 + static void 25.3106 + specify_sort_size (int oi, char c, char const *s) 25.3107 +@@ -1597,7 +1746,7 @@ buffer_linelim (struct buffer const *buf 25.3108 + by KEY in LINE. */ 25.3109 + 25.3110 + static char * 25.3111 +-begfield (struct line const *line, struct keyfield const *key) 25.3112 ++begfield_uni (const struct line *line, const struct keyfield *key) 25.3113 + { 25.3114 + char *ptr = line->text, *lim = ptr + line->length - 1; 25.3115 + size_t sword = key->sword; 25.3116 +@@ -1606,10 +1755,10 @@ begfield (struct line const *line, struc 25.3117 + /* The leading field separator itself is included in a field when -t 25.3118 + is absent. */ 25.3119 + 25.3120 +- if (tab != TAB_DEFAULT) 25.3121 ++ if (tab_length) 25.3122 + while (ptr < lim && sword--) 25.3123 + { 25.3124 +- while (ptr < lim && *ptr != tab) 25.3125 ++ while (ptr < lim && *ptr != tab[0]) 25.3126 + ++ptr; 25.3127 + if (ptr < lim) 25.3128 + ++ptr; 25.3129 +@@ -1635,11 +1784,70 @@ begfield (struct line const *line, struc 25.3130 + return ptr; 25.3131 + } 25.3132 + 25.3133 ++#if HAVE_MBRTOWC 25.3134 ++static char * 25.3135 ++begfield_mb (const struct line *line, const struct keyfield *key) 25.3136 ++{ 25.3137 ++ int i; 25.3138 ++ char *ptr = line->text, *lim = ptr + line->length - 1; 25.3139 ++ size_t sword = key->sword; 25.3140 ++ size_t schar = key->schar; 25.3141 ++ size_t mblength; 25.3142 ++ mbstate_t state; 25.3143 ++ 25.3144 ++ memset (&state, '\0', sizeof(mbstate_t)); 25.3145 ++ 25.3146 ++ if (tab_length) 25.3147 ++ while (ptr < lim && sword--) 25.3148 ++ { 25.3149 ++ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) 25.3150 ++ { 25.3151 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 25.3152 ++ ptr += mblength; 25.3153 ++ } 25.3154 ++ if (ptr < lim) 25.3155 ++ { 25.3156 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 25.3157 ++ ptr += mblength; 25.3158 ++ } 25.3159 ++ } 25.3160 ++ else 25.3161 ++ while (ptr < lim && sword--) 25.3162 ++ { 25.3163 ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 25.3164 ++ ptr += mblength; 25.3165 ++ if (ptr < lim) 25.3166 ++ { 25.3167 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 25.3168 ++ ptr += mblength; 25.3169 ++ } 25.3170 ++ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) 25.3171 ++ ptr += mblength; 25.3172 ++ } 25.3173 ++ 25.3174 ++ if (key->skipsblanks) 25.3175 ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 25.3176 ++ ptr += mblength; 25.3177 ++ 25.3178 ++ for (i = 0; i < schar; i++) 25.3179 ++ { 25.3180 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 25.3181 ++ 25.3182 ++ if (ptr + mblength > lim) 25.3183 ++ break; 25.3184 ++ else 25.3185 ++ ptr += mblength; 25.3186 ++ } 25.3187 ++ 25.3188 ++ return ptr; 25.3189 ++} 25.3190 ++#endif 25.3191 ++ 25.3192 + /* Return the limit of (a pointer to the first character after) the field 25.3193 + in LINE specified by KEY. */ 25.3194 + 25.3195 + static char * 25.3196 +-limfield (struct line const *line, struct keyfield const *key) 25.3197 ++limfield_uni (const struct line *line, const struct keyfield *key) 25.3198 + { 25.3199 + char *ptr = line->text, *lim = ptr + line->length - 1; 25.3200 + size_t eword = key->eword, echar = key->echar; 25.3201 +@@ -1654,10 +1862,10 @@ limfield (struct line const *line, struc 25.3202 + 'beginning' is the first character following the delimiting TAB. 25.3203 + Otherwise, leave PTR pointing at the first 'blank' character after 25.3204 + the preceding field. */ 25.3205 +- if (tab != TAB_DEFAULT) 25.3206 ++ if (tab_length) 25.3207 + while (ptr < lim && eword--) 25.3208 + { 25.3209 +- while (ptr < lim && *ptr != tab) 25.3210 ++ while (ptr < lim && *ptr != tab[0]) 25.3211 + ++ptr; 25.3212 + if (ptr < lim && (eword || echar)) 25.3213 + ++ptr; 25.3214 +@@ -1703,10 +1911,10 @@ limfield (struct line const *line, struc 25.3215 + */ 25.3216 + 25.3217 + /* Make LIM point to the end of (one byte past) the current field. */ 25.3218 +- if (tab != TAB_DEFAULT) 25.3219 ++ if (tab_length) 25.3220 + { 25.3221 + char *newlim; 25.3222 +- newlim = memchr (ptr, tab, lim - ptr); 25.3223 ++ newlim = memchr (ptr, tab[0], lim - ptr); 25.3224 + if (newlim) 25.3225 + lim = newlim; 25.3226 + } 25.3227 +@@ -1737,6 +1945,130 @@ limfield (struct line const *line, struc 25.3228 + return ptr; 25.3229 + } 25.3230 + 25.3231 ++#if HAVE_MBRTOWC 25.3232 ++static char * 25.3233 ++limfield_mb (const struct line *line, const struct keyfield *key) 25.3234 ++{ 25.3235 ++ char *ptr = line->text, *lim = ptr + line->length - 1; 25.3236 ++ size_t eword = key->eword, echar = key->echar; 25.3237 ++ int i; 25.3238 ++ size_t mblength; 25.3239 ++ mbstate_t state; 25.3240 ++ 25.3241 ++ if (echar == 0) 25.3242 ++ eword++; /* skip all of end field. */ 25.3243 ++ 25.3244 ++ memset (&state, '\0', sizeof(mbstate_t)); 25.3245 ++ 25.3246 ++ if (tab_length) 25.3247 ++ while (ptr < lim && eword--) 25.3248 ++ { 25.3249 ++ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) 25.3250 ++ { 25.3251 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 25.3252 ++ ptr += mblength; 25.3253 ++ } 25.3254 ++ if (ptr < lim && (eword | echar)) 25.3255 ++ { 25.3256 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 25.3257 ++ ptr += mblength; 25.3258 ++ } 25.3259 ++ } 25.3260 ++ else 25.3261 ++ while (ptr < lim && eword--) 25.3262 ++ { 25.3263 ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 25.3264 ++ ptr += mblength; 25.3265 ++ if (ptr < lim) 25.3266 ++ { 25.3267 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 25.3268 ++ ptr += mblength; 25.3269 ++ } 25.3270 ++ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) 25.3271 ++ ptr += mblength; 25.3272 ++ } 25.3273 ++ 25.3274 ++ 25.3275 ++# ifdef POSIX_UNSPECIFIED 25.3276 ++ /* Make LIM point to the end of (one byte past) the current field. */ 25.3277 ++ if (tab_length) 25.3278 ++ { 25.3279 ++ char *newlim, *p; 25.3280 ++ 25.3281 ++ newlim = NULL; 25.3282 ++ for (p = ptr; p < lim;) 25.3283 ++ { 25.3284 ++ if (memcmp (p, tab, tab_length) == 0) 25.3285 ++ { 25.3286 ++ newlim = p; 25.3287 ++ break; 25.3288 ++ } 25.3289 ++ 25.3290 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 25.3291 ++ p += mblength; 25.3292 ++ } 25.3293 ++ } 25.3294 ++ else 25.3295 ++ { 25.3296 ++ char *newlim; 25.3297 ++ newlim = ptr; 25.3298 ++ 25.3299 ++ while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength)) 25.3300 ++ newlim += mblength; 25.3301 ++ if (ptr < lim) 25.3302 ++ { 25.3303 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 25.3304 ++ ptr += mblength; 25.3305 ++ } 25.3306 ++ while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength)) 25.3307 ++ newlim += mblength; 25.3308 ++ lim = newlim; 25.3309 ++ } 25.3310 ++# endif 25.3311 ++ 25.3312 ++ if (echar != 0) 25.3313 ++ { 25.3314 ++ /* If we're skipping leading blanks, don't start counting characters 25.3315 ++ * until after skipping past any leading blanks. */ 25.3316 ++ if (key->skipeblanks) 25.3317 ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 25.3318 ++ ptr += mblength; 25.3319 ++ 25.3320 ++ memset (&state, '\0', sizeof(mbstate_t)); 25.3321 ++ 25.3322 ++ /* Advance PTR by ECHAR (if possible), but no further than LIM. */ 25.3323 ++ for (i = 0; i < echar; i++) 25.3324 ++ { 25.3325 ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 25.3326 ++ 25.3327 ++ if (ptr + mblength > lim) 25.3328 ++ break; 25.3329 ++ else 25.3330 ++ ptr += mblength; 25.3331 ++ } 25.3332 ++ } 25.3333 ++ 25.3334 ++ return ptr; 25.3335 ++} 25.3336 ++#endif 25.3337 ++ 25.3338 ++static void 25.3339 ++skipblanks_uni (char **ptr, char *lim) 25.3340 ++{ 25.3341 ++ while (*ptr < lim && blanks[to_uchar (**ptr)]) 25.3342 ++ ++(*ptr); 25.3343 ++} 25.3344 ++ 25.3345 ++#if HAVE_MBRTOWC 25.3346 ++static void 25.3347 ++skipblanks_mb (char **ptr, char *lim) 25.3348 ++{ 25.3349 ++ size_t mblength; 25.3350 ++ while (*ptr < lim && ismbblank (*ptr, lim - *ptr, &mblength)) 25.3351 ++ (*ptr) += mblength; 25.3352 ++} 25.3353 ++#endif 25.3354 ++ 25.3355 + /* Fill BUF reading from FP, moving buf->left bytes from the end 25.3356 + of buf->buf to the beginning first. If EOF is reached and the 25.3357 + file wasn't terminated by a newline, supply one. Set up BUF's line 25.3358 +@@ -1823,8 +2155,22 @@ fillbuf (struct buffer *buf, FILE *fp, c 25.3359 + else 25.3360 + { 25.3361 + if (key->skipsblanks) 25.3362 +- while (blanks[to_uchar (*line_start)]) 25.3363 +- line_start++; 25.3364 ++ { 25.3365 ++#if HAVE_MBRTOWC 25.3366 ++ if (MB_CUR_MAX > 1) 25.3367 ++ { 25.3368 ++ size_t mblength; 25.3369 ++ while (line_start < line->keylim && 25.3370 ++ ismbblank (line_start, 25.3371 ++ line->keylim - line_start, 25.3372 ++ &mblength)) 25.3373 ++ line_start += mblength; 25.3374 ++ } 25.3375 ++ else 25.3376 ++#endif 25.3377 ++ while (blanks[to_uchar (*line_start)]) 25.3378 ++ line_start++; 25.3379 ++ } 25.3380 + line->keybeg = line_start; 25.3381 + } 25.3382 + } 25.3383 +@@ -1958,12 +2304,10 @@ find_unit_order (char const *number) 25.3384 + <none/unknown> < K/k < M < G < T < P < E < Z < Y */ 25.3385 + 25.3386 + static int 25.3387 +-human_numcompare (char const *a, char const *b) 25.3388 ++human_numcompare (char *a, char *b) 25.3389 + { 25.3390 +- while (blanks[to_uchar (*a)]) 25.3391 +- a++; 25.3392 +- while (blanks[to_uchar (*b)]) 25.3393 +- b++; 25.3394 ++ skipblanks(&a, a + strlen(a)); 25.3395 ++ skipblanks(&b, b + strlen(b)); 25.3396 + 25.3397 + int diff = find_unit_order (a) - find_unit_order (b); 25.3398 + return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); 25.3399 +@@ -1974,7 +2318,7 @@ human_numcompare (char const *a, char co 25.3400 + hideously fast. */ 25.3401 + 25.3402 + static int 25.3403 +-numcompare (char const *a, char const *b) 25.3404 ++numcompare_uni (const char *a, const char *b) 25.3405 + { 25.3406 + while (blanks[to_uchar (*a)]) 25.3407 + a++; 25.3408 +@@ -1984,6 +2328,25 @@ numcompare (char const *a, char const *b 25.3409 + return strnumcmp (a, b, decimal_point, thousands_sep); 25.3410 + } 25.3411 + 25.3412 ++#if HAVE_MBRTOWC 25.3413 ++static int 25.3414 ++numcompare_mb (const char *a, const char *b) 25.3415 ++{ 25.3416 ++ size_t mblength, len; 25.3417 ++ len = strlen (a); /* okay for UTF-8 */ 25.3418 ++ while (*a && ismbblank (a, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) 25.3419 ++ { 25.3420 ++ a += mblength; 25.3421 ++ len -= mblength; 25.3422 ++ } 25.3423 ++ len = strlen (b); /* okay for UTF-8 */ 25.3424 ++ while (*b && ismbblank (b, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) 25.3425 ++ b += mblength; 25.3426 ++ 25.3427 ++ return strnumcmp (a, b, decimal_point, thousands_sep); 25.3428 ++} 25.3429 ++#endif /* HAV_EMBRTOWC */ 25.3430 ++ 25.3431 + /* Work around a problem whereby the long double value returned by glibc's 25.3432 + strtold ("NaN", ...) contains uninitialized bits: clear all bytes of 25.3433 + A and B before calling strtold. FIXME: remove this function once 25.3434 +@@ -2034,7 +2397,7 @@ general_numcompare (char const *sa, char 25.3435 + Return 0 if the name in S is not recognized. */ 25.3436 + 25.3437 + static int 25.3438 +-getmonth (char const *month, char **ea) 25.3439 ++getmonth_uni (char const *month, size_t len, char **ea) 25.3440 + { 25.3441 + size_t lo = 0; 25.3442 + size_t hi = MONTHS_PER_YEAR; 25.3443 +@@ -2310,15 +2673,14 @@ debug_key (struct line const *line, stru 25.3444 + char saved = *lim; 25.3445 + *lim = '\0'; 25.3446 + 25.3447 +- while (blanks[to_uchar (*beg)]) 25.3448 +- beg++; 25.3449 ++ skipblanks (&beg, lim); 25.3450 + 25.3451 + char *tighter_lim = beg; 25.3452 + 25.3453 + if (lim < beg) 25.3454 + tighter_lim = lim; 25.3455 + else if (key->month) 25.3456 +- getmonth (beg, &tighter_lim); 25.3457 ++ getmonth (beg, lim-beg, &tighter_lim); 25.3458 + else if (key->general_numeric) 25.3459 + ignore_value (strtold (beg, &tighter_lim)); 25.3460 + else if (key->numeric || key->human_numeric) 25.3461 +@@ -2452,7 +2814,7 @@ key_warnings (struct keyfield const *gke 25.3462 + /* Warn about significant leading blanks. */ 25.3463 + bool implicit_skip = key_numeric (key) || key->month; 25.3464 + bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ 25.3465 +- if (!zero_width && !gkey_only && tab == TAB_DEFAULT && !line_offset 25.3466 ++ if (!zero_width && !gkey_only && !tab_length && !line_offset 25.3467 + && ((!key->skipsblanks && !implicit_skip) 25.3468 + || (!key->skipsblanks && key->schar) 25.3469 + || (!key->skipeblanks && key->echar))) 25.3470 +@@ -2510,11 +2872,87 @@ key_warnings (struct keyfield const *gke 25.3471 + error (0, 0, _("option '-r' only applies to last-resort comparison")); 25.3472 + } 25.3473 + 25.3474 ++#if HAVE_MBRTOWC 25.3475 ++static int 25.3476 ++getmonth_mb (const char *s, size_t len, char **ea) 25.3477 ++{ 25.3478 ++ char *month; 25.3479 ++ register size_t i; 25.3480 ++ register int lo = 0, hi = MONTHS_PER_YEAR, result; 25.3481 ++ char *tmp; 25.3482 ++ size_t wclength, mblength; 25.3483 ++ const char *pp; 25.3484 ++ const wchar_t *wpp; 25.3485 ++ wchar_t *month_wcs; 25.3486 ++ mbstate_t state; 25.3487 ++ 25.3488 ++ while (len > 0 && ismbblank (s, len, &mblength)) 25.3489 ++ { 25.3490 ++ s += mblength; 25.3491 ++ len -= mblength; 25.3492 ++ } 25.3493 ++ 25.3494 ++ if (len == 0) 25.3495 ++ return 0; 25.3496 ++ 25.3497 ++ if (SIZE_MAX - len < 1) 25.3498 ++ xalloc_die (); 25.3499 ++ 25.3500 ++ month = (char *) xnmalloc (len + 1, MB_CUR_MAX); 25.3501 ++ 25.3502 ++ pp = tmp = (char *) xnmalloc (len + 1, MB_CUR_MAX); 25.3503 ++ memcpy (tmp, s, len); 25.3504 ++ tmp[len] = '\0'; 25.3505 ++ wpp = month_wcs = (wchar_t *) xnmalloc (len + 1, sizeof (wchar_t)); 25.3506 ++ memset (&state, '\0', sizeof (mbstate_t)); 25.3507 ++ 25.3508 ++ wclength = mbsrtowcs (month_wcs, &pp, len + 1, &state); 25.3509 ++ if (wclength == (size_t)-1 || pp != NULL) 25.3510 ++ error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s)); 25.3511 ++ 25.3512 ++ for (i = 0; i < wclength; i++) 25.3513 ++ { 25.3514 ++ month_wcs[i] = towupper(month_wcs[i]); 25.3515 ++ if (iswblank (month_wcs[i])) 25.3516 ++ { 25.3517 ++ month_wcs[i] = L'\0'; 25.3518 ++ break; 25.3519 ++ } 25.3520 ++ } 25.3521 ++ 25.3522 ++ mblength = wcsrtombs (month, &wpp, (len + 1) * MB_CUR_MAX, &state); 25.3523 ++ assert (mblength != (-1) && wpp == NULL); 25.3524 ++ 25.3525 ++ do 25.3526 ++ { 25.3527 ++ int ix = (lo + hi) / 2; 25.3528 ++ 25.3529 ++ if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0) 25.3530 ++ hi = ix; 25.3531 ++ else 25.3532 ++ lo = ix; 25.3533 ++ } 25.3534 ++ while (hi - lo > 1); 25.3535 ++ 25.3536 ++ result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name)) 25.3537 ++ ? monthtab[lo].val : 0); 25.3538 ++ 25.3539 ++ if (ea && result) 25.3540 ++ *ea = (char*) s + strlen (monthtab[lo].name); 25.3541 ++ 25.3542 ++ free (month); 25.3543 ++ free (tmp); 25.3544 ++ free (month_wcs); 25.3545 ++ 25.3546 ++ return result; 25.3547 ++} 25.3548 ++#endif 25.3549 ++ 25.3550 + /* Compare two lines A and B trying every key in sequence until there 25.3551 + are no more keys or a difference is found. */ 25.3552 + 25.3553 + static int 25.3554 +-keycompare (struct line const *a, struct line const *b) 25.3555 ++keycompare_uni (const struct line *a, const struct line *b) 25.3556 + { 25.3557 + struct keyfield *key = keylist; 25.3558 + 25.3559 +@@ -2599,7 +3037,7 @@ keycompare (struct line const *a, struct 25.3560 + else if (key->human_numeric) 25.3561 + diff = human_numcompare (ta, tb); 25.3562 + else if (key->month) 25.3563 +- diff = getmonth (ta, NULL) - getmonth (tb, NULL); 25.3564 ++ diff = getmonth (ta, tlena, NULL) - getmonth (tb, tlenb, NULL); 25.3565 + else if (key->random) 25.3566 + diff = compare_random (ta, tlena, tb, tlenb); 25.3567 + else if (key->version) 25.3568 +@@ -2715,6 +3153,211 @@ keycompare (struct line const *a, struct 25.3569 + return key->reverse ? -diff : diff; 25.3570 + } 25.3571 + 25.3572 ++#if HAVE_MBRTOWC 25.3573 ++static int 25.3574 ++keycompare_mb (const struct line *a, const struct line *b) 25.3575 ++{ 25.3576 ++ struct keyfield *key = keylist; 25.3577 ++ 25.3578 ++ /* For the first iteration only, the key positions have been 25.3579 ++ precomputed for us. */ 25.3580 ++ char *texta = a->keybeg; 25.3581 ++ char *textb = b->keybeg; 25.3582 ++ char *lima = a->keylim; 25.3583 ++ char *limb = b->keylim; 25.3584 ++ 25.3585 ++ size_t mblength_a, mblength_b; 25.3586 ++ wchar_t wc_a, wc_b; 25.3587 ++ mbstate_t state_a, state_b; 25.3588 ++ 25.3589 ++ int diff = 0; 25.3590 ++ 25.3591 ++ memset (&state_a, '\0', sizeof(mbstate_t)); 25.3592 ++ memset (&state_b, '\0', sizeof(mbstate_t)); 25.3593 ++ /* Ignore keys with start after end. */ 25.3594 ++ if (a->keybeg - a->keylim > 0) 25.3595 ++ return 0; 25.3596 ++ 25.3597 ++ 25.3598 ++ /* Ignore and/or translate chars before comparing. */ 25.3599 ++# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \ 25.3600 ++ do \ 25.3601 ++ { \ 25.3602 ++ wchar_t uwc; \ 25.3603 ++ char mbc[MB_LEN_MAX]; \ 25.3604 ++ mbstate_t state_wc; \ 25.3605 ++ \ 25.3606 ++ for (NEW_LEN = i = 0; i < LEN;) \ 25.3607 ++ { \ 25.3608 ++ mbstate_t state_bak; \ 25.3609 ++ \ 25.3610 ++ state_bak = STATE; \ 25.3611 ++ MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE); \ 25.3612 ++ \ 25.3613 ++ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1 \ 25.3614 ++ || MBLENGTH == 0) \ 25.3615 ++ { \ 25.3616 ++ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \ 25.3617 ++ STATE = state_bak; \ 25.3618 ++ if (!ignore) \ 25.3619 ++ COPY[NEW_LEN++] = TEXT[i]; \ 25.3620 ++ i++; \ 25.3621 ++ continue; \ 25.3622 ++ } \ 25.3623 ++ \ 25.3624 ++ if (ignore) \ 25.3625 ++ { \ 25.3626 ++ if ((ignore == nonprinting && !iswprint (WC)) \ 25.3627 ++ || (ignore == nondictionary \ 25.3628 ++ && !iswalnum (WC) && !iswblank (WC))) \ 25.3629 ++ { \ 25.3630 ++ i += MBLENGTH; \ 25.3631 ++ continue; \ 25.3632 ++ } \ 25.3633 ++ } \ 25.3634 ++ \ 25.3635 ++ if (translate) \ 25.3636 ++ { \ 25.3637 ++ \ 25.3638 ++ uwc = towupper(WC); \ 25.3639 ++ if (WC == uwc) \ 25.3640 ++ { \ 25.3641 ++ memcpy (mbc, TEXT + i, MBLENGTH); \ 25.3642 ++ i += MBLENGTH; \ 25.3643 ++ } \ 25.3644 ++ else \ 25.3645 ++ { \ 25.3646 ++ i += MBLENGTH; \ 25.3647 ++ WC = uwc; \ 25.3648 ++ memset (&state_wc, '\0', sizeof (mbstate_t)); \ 25.3649 ++ \ 25.3650 ++ MBLENGTH = wcrtomb (mbc, WC, &state_wc); \ 25.3651 ++ assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0); \ 25.3652 ++ } \ 25.3653 ++ \ 25.3654 ++ for (j = 0; j < MBLENGTH; j++) \ 25.3655 ++ COPY[NEW_LEN++] = mbc[j]; \ 25.3656 ++ } \ 25.3657 ++ else \ 25.3658 ++ for (j = 0; j < MBLENGTH; j++) \ 25.3659 ++ COPY[NEW_LEN++] = TEXT[i++]; \ 25.3660 ++ } \ 25.3661 ++ COPY[NEW_LEN] = '\0'; \ 25.3662 ++ } \ 25.3663 ++ while (0) 25.3664 ++ 25.3665 ++ /* Actually compare the fields. */ 25.3666 ++ 25.3667 ++ for (;;) 25.3668 ++ { 25.3669 ++ /* Find the lengths. */ 25.3670 ++ size_t lena = lima <= texta ? 0 : lima - texta; 25.3671 ++ size_t lenb = limb <= textb ? 0 : limb - textb; 25.3672 ++ 25.3673 ++ char enda IF_LINT (= 0); 25.3674 ++ char endb IF_LINT (= 0); 25.3675 ++ 25.3676 ++ char const *translate = key->translate; 25.3677 ++ bool const *ignore = key->ignore; 25.3678 ++ 25.3679 ++ if (ignore || translate) 25.3680 ++ { 25.3681 ++ if (SIZE_MAX - lenb - 2 < lena) 25.3682 ++ xalloc_die (); 25.3683 ++ char *copy_a = (char *) xnmalloc (lena + lenb + 2, MB_CUR_MAX); 25.3684 ++ char *copy_b = copy_a + lena * MB_CUR_MAX + 1; 25.3685 ++ size_t new_len_a, new_len_b; 25.3686 ++ size_t i, j; 25.3687 ++ 25.3688 ++ IGNORE_CHARS (new_len_a, lena, texta, copy_a, 25.3689 ++ wc_a, mblength_a, state_a); 25.3690 ++ IGNORE_CHARS (new_len_b, lenb, textb, copy_b, 25.3691 ++ wc_b, mblength_b, state_b); 25.3692 ++ texta = copy_a; textb = copy_b; 25.3693 ++ lena = new_len_a; lenb = new_len_b; 25.3694 ++ } 25.3695 ++ else 25.3696 ++ { 25.3697 ++ /* Use the keys in-place, temporarily null-terminated. */ 25.3698 ++ enda = texta[lena]; texta[lena] = '\0'; 25.3699 ++ endb = textb[lenb]; textb[lenb] = '\0'; 25.3700 ++ } 25.3701 ++ 25.3702 ++ if (key->random) 25.3703 ++ diff = compare_random (texta, lena, textb, lenb); 25.3704 ++ else if (key->numeric | key->general_numeric | key->human_numeric) 25.3705 ++ { 25.3706 ++ char savea = *lima, saveb = *limb; 25.3707 ++ 25.3708 ++ *lima = *limb = '\0'; 25.3709 ++ diff = (key->numeric ? numcompare (texta, textb) 25.3710 ++ : key->general_numeric ? general_numcompare (texta, textb) 25.3711 ++ : human_numcompare (texta, textb)); 25.3712 ++ *lima = savea, *limb = saveb; 25.3713 ++ } 25.3714 ++ else if (key->version) 25.3715 ++ diff = filevercmp (texta, textb); 25.3716 ++ else if (key->month) 25.3717 ++ diff = getmonth (texta, lena, NULL) - getmonth (textb, lenb, NULL); 25.3718 ++ else if (lena == 0) 25.3719 ++ diff = - NONZERO (lenb); 25.3720 ++ else if (lenb == 0) 25.3721 ++ diff = 1; 25.3722 ++ else if (hard_LC_COLLATE && !folding) 25.3723 ++ { 25.3724 ++ diff = xmemcoll0 (texta, lena + 1, textb, lenb + 1); 25.3725 ++ } 25.3726 ++ else 25.3727 ++ { 25.3728 ++ diff = memcmp (texta, textb, MIN (lena, lenb)); 25.3729 ++ if (diff == 0) 25.3730 ++ diff = lena < lenb ? -1 : lena != lenb; 25.3731 ++ } 25.3732 ++ 25.3733 ++ if (ignore || translate) 25.3734 ++ free (texta); 25.3735 ++ else 25.3736 ++ { 25.3737 ++ texta[lena] = enda; 25.3738 ++ textb[lenb] = endb; 25.3739 ++ } 25.3740 ++ 25.3741 ++ if (diff) 25.3742 ++ goto not_equal; 25.3743 ++ 25.3744 ++ key = key->next; 25.3745 ++ if (! key) 25.3746 ++ break; 25.3747 ++ 25.3748 ++ /* Find the beginning and limit of the next field. */ 25.3749 ++ if (key->eword != -1) 25.3750 ++ lima = limfield (a, key), limb = limfield (b, key); 25.3751 ++ else 25.3752 ++ lima = a->text + a->length - 1, limb = b->text + b->length - 1; 25.3753 ++ 25.3754 ++ if (key->sword != -1) 25.3755 ++ texta = begfield (a, key), textb = begfield (b, key); 25.3756 ++ else 25.3757 ++ { 25.3758 ++ texta = a->text, textb = b->text; 25.3759 ++ if (key->skipsblanks) 25.3760 ++ { 25.3761 ++ while (texta < lima && ismbblank (texta, lima - texta, &mblength_a)) 25.3762 ++ texta += mblength_a; 25.3763 ++ while (textb < limb && ismbblank (textb, limb - textb, &mblength_b)) 25.3764 ++ textb += mblength_b; 25.3765 ++ } 25.3766 ++ } 25.3767 ++ } 25.3768 ++ 25.3769 ++not_equal: 25.3770 ++ if (key && key->reverse) 25.3771 ++ return -diff; 25.3772 ++ else 25.3773 ++ return diff; 25.3774 ++} 25.3775 ++#endif 25.3776 ++ 25.3777 + /* Compare two lines A and B, returning negative, zero, or positive 25.3778 + depending on whether A compares less than, equal to, or greater than B. */ 25.3779 + 25.3780 +@@ -2742,7 +3385,7 @@ compare (struct line const *a, struct li 25.3781 + diff = - NONZERO (blen); 25.3782 + else if (blen == 0) 25.3783 + diff = 1; 25.3784 +- else if (hard_LC_COLLATE) 25.3785 ++ else if (hard_LC_COLLATE && !folding) 25.3786 + { 25.3787 + /* Note xmemcoll0 is a performance enhancement as 25.3788 + it will not unconditionally write '\0' after the 25.3789 +@@ -4139,6 +4782,7 @@ set_ordering (char const *s, struct keyf 25.3790 + break; 25.3791 + case 'f': 25.3792 + key->translate = fold_toupper; 25.3793 ++ folding = true; 25.3794 + break; 25.3795 + case 'g': 25.3796 + key->general_numeric = true; 25.3797 +@@ -4218,7 +4862,7 @@ main (int argc, char **argv) 25.3798 + initialize_exit_failure (SORT_FAILURE); 25.3799 + 25.3800 + hard_LC_COLLATE = hard_locale (LC_COLLATE); 25.3801 +-#if HAVE_NL_LANGINFO 25.3802 ++#if HAVE_LANGINFO_CODESET 25.3803 + hard_LC_TIME = hard_locale (LC_TIME); 25.3804 + #endif 25.3805 + 25.3806 +@@ -4239,6 +4883,29 @@ main (int argc, char **argv) 25.3807 + thousands_sep = -1; 25.3808 + } 25.3809 + 25.3810 ++#if HAVE_MBRTOWC 25.3811 ++ if (MB_CUR_MAX > 1) 25.3812 ++ { 25.3813 ++ inittables = inittables_mb; 25.3814 ++ begfield = begfield_mb; 25.3815 ++ limfield = limfield_mb; 25.3816 ++ skipblanks = skipblanks_mb; 25.3817 ++ getmonth = getmonth_mb; 25.3818 ++ keycompare = keycompare_mb; 25.3819 ++ numcompare = numcompare_mb; 25.3820 ++ } 25.3821 ++ else 25.3822 ++#endif 25.3823 ++ { 25.3824 ++ inittables = inittables_uni; 25.3825 ++ begfield = begfield_uni; 25.3826 ++ limfield = limfield_uni; 25.3827 ++ skipblanks = skipblanks_uni; 25.3828 ++ getmonth = getmonth_uni; 25.3829 ++ keycompare = keycompare_uni; 25.3830 ++ numcompare = numcompare_uni; 25.3831 ++ } 25.3832 ++ 25.3833 + have_read_stdin = false; 25.3834 + inittables (); 25.3835 + 25.3836 +@@ -4513,13 +5180,34 @@ main (int argc, char **argv) 25.3837 + 25.3838 + case 't': 25.3839 + { 25.3840 +- char newtab = optarg[0]; 25.3841 +- if (! newtab) 25.3842 ++ char newtab[MB_LEN_MAX + 1]; 25.3843 ++ size_t newtab_length = 1; 25.3844 ++ strncpy (newtab, optarg, MB_LEN_MAX); 25.3845 ++ if (! newtab[0]) 25.3846 + die (SORT_FAILURE, 0, _("empty tab")); 25.3847 +- if (optarg[1]) 25.3848 ++#if HAVE_MBRTOWC 25.3849 ++ if (MB_CUR_MAX > 1) 25.3850 ++ { 25.3851 ++ wchar_t wc; 25.3852 ++ mbstate_t state; 25.3853 ++ 25.3854 ++ memset (&state, '\0', sizeof (mbstate_t)); 25.3855 ++ newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, 25.3856 ++ MB_LEN_MAX), 25.3857 ++ &state); 25.3858 ++ switch (newtab_length) 25.3859 ++ { 25.3860 ++ case (size_t) -1: 25.3861 ++ case (size_t) -2: 25.3862 ++ case 0: 25.3863 ++ newtab_length = 1; 25.3864 ++ } 25.3865 ++ } 25.3866 ++#endif 25.3867 ++ if (newtab_length == 1 && optarg[1]) 25.3868 + { 25.3869 + if (STREQ (optarg, "\\0")) 25.3870 +- newtab = '\0'; 25.3871 ++ newtab[0] = '\0'; 25.3872 + else 25.3873 + { 25.3874 + /* Provoke with 'sort -txx'. Complain about 25.3875 +@@ -4530,9 +5218,11 @@ main (int argc, char **argv) 25.3876 + quote (optarg)); 25.3877 + } 25.3878 + } 25.3879 +- if (tab != TAB_DEFAULT && tab != newtab) 25.3880 ++ if (tab_length && (tab_length != newtab_length 25.3881 ++ || memcmp (tab, newtab, tab_length) != 0)) 25.3882 + die (SORT_FAILURE, 0, _("incompatible tabs")); 25.3883 +- tab = newtab; 25.3884 ++ memcpy (tab, newtab, newtab_length); 25.3885 ++ tab_length = newtab_length; 25.3886 + } 25.3887 + break; 25.3888 + 25.3889 +@@ -4770,12 +5460,10 @@ main (int argc, char **argv) 25.3890 + sort (files, nfiles, outfile, nthreads); 25.3891 + } 25.3892 + 25.3893 +-#ifdef lint 25.3894 + if (files_from) 25.3895 + readtokens0_free (&tok); 25.3896 + else 25.3897 + free (files); 25.3898 +-#endif 25.3899 + 25.3900 + if (have_read_stdin && fclose (stdin) == EOF) 25.3901 + sort_die (_("close failed"), "-"); 25.3902 +diff -Naurp coreutils-8.27-orig/src/unexpand.c coreutils-8.27/src/unexpand.c 25.3903 +--- coreutils-8.27-orig/src/unexpand.c 2017-01-01 16:34:24.000000000 -0600 25.3904 ++++ coreutils-8.27/src/unexpand.c 2017-03-11 23:49:06.758133530 -0600 25.3905 +@@ -38,6 +38,9 @@ 25.3906 + #include <stdio.h> 25.3907 + #include <getopt.h> 25.3908 + #include <sys/types.h> 25.3909 ++ 25.3910 ++#include <mbfile.h> 25.3911 ++ 25.3912 + #include "system.h" 25.3913 + #include "die.h" 25.3914 + #include "xstrndup.h" 25.3915 +@@ -107,24 +110,47 @@ unexpand (void) 25.3916 + { 25.3917 + /* Input stream. */ 25.3918 + FILE *fp = next_file (NULL); 25.3919 ++ mb_file_t mbf; 25.3920 + 25.3921 + /* The array of pending blanks. In non-POSIX locales, blanks can 25.3922 + include characters other than spaces, so the blanks must be 25.3923 + stored, not merely counted. */ 25.3924 +- char *pending_blank; 25.3925 ++ mbf_char_t *pending_blank; 25.3926 ++ /* True if the starting locale is utf8. */ 25.3927 ++ bool using_utf_locale; 25.3928 ++ 25.3929 ++ /* True if the first file contains BOM header. */ 25.3930 ++ bool found_bom; 25.3931 ++ using_utf_locale=check_utf_locale(); 25.3932 + 25.3933 + if (!fp) 25.3934 + return; 25.3935 ++ mbf_init (mbf, fp); 25.3936 ++ found_bom=check_bom(fp,&mbf); 25.3937 + 25.3938 ++ if (using_utf_locale == false && found_bom == true) 25.3939 ++ { 25.3940 ++ /*try using some predefined locale */ 25.3941 ++ 25.3942 ++ if (set_utf_locale () != 0) 25.3943 ++ { 25.3944 ++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); 25.3945 ++ } 25.3946 ++ } 25.3947 + /* The worst case is a non-blank character, then one blank, then a 25.3948 + tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so 25.3949 + allocate MAX_COLUMN_WIDTH bytes to store the blanks. */ 25.3950 +- pending_blank = xmalloc (max_column_width); 25.3951 ++ pending_blank = xmalloc (max_column_width * sizeof (mbf_char_t)); 25.3952 ++ 25.3953 ++ if (found_bom == true) 25.3954 ++ { 25.3955 ++ print_bom(); 25.3956 ++ } 25.3957 + 25.3958 + while (true) 25.3959 + { 25.3960 + /* Input character, or EOF. */ 25.3961 +- int c; 25.3962 ++ mbf_char_t c; 25.3963 + 25.3964 + /* If true, perform translations. */ 25.3965 + bool convert = true; 25.3966 +@@ -158,12 +184,44 @@ unexpand (void) 25.3967 + 25.3968 + do 25.3969 + { 25.3970 +- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) 25.3971 +- continue; 25.3972 ++ while (true) { 25.3973 ++ mbf_getc (c, mbf); 25.3974 ++ if ((mb_iseof (c)) && (fp = next_file (fp))) 25.3975 ++ { 25.3976 ++ mbf_init (mbf, fp); 25.3977 ++ if (fp!=NULL) 25.3978 ++ { 25.3979 ++ if (check_bom(fp,&mbf)==true) 25.3980 ++ { 25.3981 ++ /*Not the first file - check BOM header*/ 25.3982 ++ if (using_utf_locale==false && found_bom==false) 25.3983 ++ { 25.3984 ++ /*BOM header in subsequent file but not in the first one. */ 25.3985 ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); 25.3986 ++ } 25.3987 ++ } 25.3988 ++ else 25.3989 ++ { 25.3990 ++ if(using_utf_locale==false && found_bom==true) 25.3991 ++ { 25.3992 ++ /*First file conatined BOM header - locale was switched to UTF 25.3993 ++ /*all subsequent files should contain BOM. */ 25.3994 ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); 25.3995 ++ } 25.3996 ++ } 25.3997 ++ } 25.3998 ++ continue; 25.3999 ++ } 25.4000 ++ else 25.4001 ++ { 25.4002 ++ break; 25.4003 ++ } 25.4004 ++ } 25.4005 ++ 25.4006 + 25.4007 + if (convert) 25.4008 + { 25.4009 +- bool blank = !! isblank (c); 25.4010 ++ bool blank = mb_isblank (c); 25.4011 + 25.4012 + if (blank) 25.4013 + { 25.4014 +@@ -180,16 +238,16 @@ unexpand (void) 25.4015 + if (next_tab_column < column) 25.4016 + die (EXIT_FAILURE, 0, _("input line is too long")); 25.4017 + 25.4018 +- if (c == '\t') 25.4019 ++ if (mb_iseq (c, '\t')) 25.4020 + { 25.4021 + column = next_tab_column; 25.4022 + 25.4023 + if (pending) 25.4024 +- pending_blank[0] = '\t'; 25.4025 ++ mb_setascii (&pending_blank[0], '\t'); 25.4026 + } 25.4027 + else 25.4028 + { 25.4029 +- column++; 25.4030 ++ column += mb_width (c); 25.4031 + 25.4032 + if (! (prev_blank && column == next_tab_column)) 25.4033 + { 25.4034 +@@ -197,13 +255,14 @@ unexpand (void) 25.4035 + will be replaced by tabs. */ 25.4036 + if (column == next_tab_column) 25.4037 + one_blank_before_tab_stop = true; 25.4038 +- pending_blank[pending++] = c; 25.4039 ++ mb_copy (&pending_blank[pending++], &c); 25.4040 + prev_blank = true; 25.4041 + continue; 25.4042 + } 25.4043 + 25.4044 + /* Replace the pending blanks by a tab or two. */ 25.4045 +- pending_blank[0] = c = '\t'; 25.4046 ++ mb_setascii (&c, '\t'); 25.4047 ++ mb_setascii (&pending_blank[0], '\t'); 25.4048 + } 25.4049 + 25.4050 + /* Discard pending blanks, unless it was a single 25.4051 +@@ -211,7 +270,7 @@ unexpand (void) 25.4052 + pending = one_blank_before_tab_stop; 25.4053 + } 25.4054 + } 25.4055 +- else if (c == '\b') 25.4056 ++ else if (mb_iseq (c, '\b')) 25.4057 + { 25.4058 + /* Go back one column, and force recalculation of the 25.4059 + next tab stop. */ 25.4060 +@@ -219,9 +278,9 @@ unexpand (void) 25.4061 + next_tab_column = column; 25.4062 + tab_index -= !!tab_index; 25.4063 + } 25.4064 +- else 25.4065 ++ else if (!mb_iseq (c, '\n')) 25.4066 + { 25.4067 +- column++; 25.4068 ++ column += mb_width (c); 25.4069 + if (!column) 25.4070 + die (EXIT_FAILURE, 0, _("input line is too long")); 25.4071 + } 25.4072 +@@ -229,8 +288,11 @@ unexpand (void) 25.4073 + if (pending) 25.4074 + { 25.4075 + if (pending > 1 && one_blank_before_tab_stop) 25.4076 +- pending_blank[0] = '\t'; 25.4077 +- if (fwrite (pending_blank, 1, pending, stdout) != pending) 25.4078 ++ mb_setascii (&pending_blank[0], '\t'); 25.4079 ++ 25.4080 ++ for (int n = 0; n < pending; ++n) 25.4081 ++ mb_putc (pending_blank[n], stdout); 25.4082 ++ if (ferror (stdout)) 25.4083 + die (EXIT_FAILURE, errno, _("write error")); 25.4084 + pending = 0; 25.4085 + one_blank_before_tab_stop = false; 25.4086 +@@ -240,16 +302,17 @@ unexpand (void) 25.4087 + convert &= convert_entire_line || blank; 25.4088 + } 25.4089 + 25.4090 +- if (c < 0) 25.4091 ++ if (mb_iseof (c)) 25.4092 + { 25.4093 + free (pending_blank); 25.4094 + return; 25.4095 + } 25.4096 + 25.4097 +- if (putchar (c) < 0) 25.4098 ++ mb_putc (c, stdout); 25.4099 ++ if (ferror (stdout)) 25.4100 + die (EXIT_FAILURE, errno, _("write error")); 25.4101 + } 25.4102 +- while (c != '\n'); 25.4103 ++ while (!mb_iseq (c, '\n')); 25.4104 + } 25.4105 + } 25.4106 + 25.4107 +diff -Naurp coreutils-8.27-orig/src/uniq.c coreutils-8.27/src/uniq.c 25.4108 +--- coreutils-8.27-orig/src/uniq.c 2017-01-01 16:34:24.000000000 -0600 25.4109 ++++ coreutils-8.27/src/uniq.c 2017-03-11 23:47:13.098285938 -0600 25.4110 +@@ -21,6 +21,17 @@ 25.4111 + #include <getopt.h> 25.4112 + #include <sys/types.h> 25.4113 + 25.4114 ++/* Get mbstate_t, mbrtowc(). */ 25.4115 ++#if HAVE_WCHAR_H 25.4116 ++# include <wchar.h> 25.4117 ++#endif 25.4118 ++ 25.4119 ++/* Get isw* functions. */ 25.4120 ++#if HAVE_WCTYPE_H 25.4121 ++# include <wctype.h> 25.4122 ++#endif 25.4123 ++#include <assert.h> 25.4124 ++ 25.4125 + #include "system.h" 25.4126 + #include "argmatch.h" 25.4127 + #include "linebuffer.h" 25.4128 +@@ -32,9 +43,21 @@ 25.4129 + #include "stdio--.h" 25.4130 + #include "xmemcoll.h" 25.4131 + #include "xstrtol.h" 25.4132 +-#include "memcasecmp.h" 25.4133 ++#include "xmemcoll.h" 25.4134 + #include "quote.h" 25.4135 + 25.4136 ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 25.4137 ++ installation; work around this configuration error. */ 25.4138 ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 25.4139 ++# define MB_LEN_MAX 16 25.4140 ++#endif 25.4141 ++ 25.4142 ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 25.4143 ++#if HAVE_MBRTOWC && defined mbstate_t 25.4144 ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 25.4145 ++#endif 25.4146 ++ 25.4147 ++ 25.4148 + /* The official name of this program (e.g., no 'g' prefix). */ 25.4149 + #define PROGRAM_NAME "uniq" 25.4150 + 25.4151 +@@ -144,6 +167,10 @@ enum 25.4152 + GROUP_OPTION = CHAR_MAX + 1 25.4153 + }; 25.4154 + 25.4155 ++/* Function pointers. */ 25.4156 ++static char * 25.4157 ++(*find_field) (struct linebuffer *line); 25.4158 ++ 25.4159 + static struct option const longopts[] = 25.4160 + { 25.4161 + {"count", no_argument, NULL, 'c'}, 25.4162 +@@ -260,7 +287,7 @@ size_opt (char const *opt, char const *m 25.4163 + return a pointer to the beginning of the line's field to be compared. */ 25.4164 + 25.4165 + static char * _GL_ATTRIBUTE_PURE 25.4166 +-find_field (struct linebuffer const *line) 25.4167 ++find_field_uni (struct linebuffer *line) 25.4168 + { 25.4169 + size_t count; 25.4170 + char const *lp = line->buffer; 25.4171 +@@ -280,6 +307,83 @@ find_field (struct linebuffer const *lin 25.4172 + return line->buffer + i; 25.4173 + } 25.4174 + 25.4175 ++#if HAVE_MBRTOWC 25.4176 ++ 25.4177 ++# define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL) \ 25.4178 ++ do \ 25.4179 ++ { \ 25.4180 ++ mbstate_t state_bak; \ 25.4181 ++ \ 25.4182 ++ CONVFAIL = 0; \ 25.4183 ++ state_bak = *STATEP; \ 25.4184 ++ \ 25.4185 ++ MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP); \ 25.4186 ++ \ 25.4187 ++ switch (MBLENGTH) \ 25.4188 ++ { \ 25.4189 ++ case (size_t)-2: \ 25.4190 ++ case (size_t)-1: \ 25.4191 ++ *STATEP = state_bak; \ 25.4192 ++ CONVFAIL++; \ 25.4193 ++ /* Fall through */ \ 25.4194 ++ case 0: \ 25.4195 ++ MBLENGTH = 1; \ 25.4196 ++ } \ 25.4197 ++ } \ 25.4198 ++ while (0) 25.4199 ++ 25.4200 ++static char * 25.4201 ++find_field_multi (struct linebuffer *line) 25.4202 ++{ 25.4203 ++ size_t count; 25.4204 ++ char *lp = line->buffer; 25.4205 ++ size_t size = line->length - 1; 25.4206 ++ size_t pos; 25.4207 ++ size_t mblength; 25.4208 ++ wchar_t wc; 25.4209 ++ mbstate_t *statep; 25.4210 ++ int convfail = 0; 25.4211 ++ 25.4212 ++ pos = 0; 25.4213 ++ statep = &(line->state); 25.4214 ++ 25.4215 ++ /* skip fields. */ 25.4216 ++ for (count = 0; count < skip_fields && pos < size; count++) 25.4217 ++ { 25.4218 ++ while (pos < size) 25.4219 ++ { 25.4220 ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 25.4221 ++ 25.4222 ++ if (convfail || !(iswblank (wc) || wc == '\n')) 25.4223 ++ { 25.4224 ++ pos += mblength; 25.4225 ++ break; 25.4226 ++ } 25.4227 ++ pos += mblength; 25.4228 ++ } 25.4229 ++ 25.4230 ++ while (pos < size) 25.4231 ++ { 25.4232 ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 25.4233 ++ 25.4234 ++ if (!convfail && (iswblank (wc) || wc == '\n')) 25.4235 ++ break; 25.4236 ++ 25.4237 ++ pos += mblength; 25.4238 ++ } 25.4239 ++ } 25.4240 ++ 25.4241 ++ /* skip fields. */ 25.4242 ++ for (count = 0; count < skip_chars && pos < size; count++) 25.4243 ++ { 25.4244 ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 25.4245 ++ pos += mblength; 25.4246 ++ } 25.4247 ++ 25.4248 ++ return lp + pos; 25.4249 ++} 25.4250 ++#endif 25.4251 ++ 25.4252 + /* Return false if two strings OLD and NEW match, true if not. 25.4253 + OLD and NEW point not to the beginnings of the lines 25.4254 + but rather to the beginnings of the fields to compare. 25.4255 +@@ -288,6 +392,8 @@ find_field (struct linebuffer const *lin 25.4256 + static bool 25.4257 + different (char *old, char *new, size_t oldlen, size_t newlen) 25.4258 + { 25.4259 ++ char *copy_old, *copy_new; 25.4260 ++ 25.4261 + if (check_chars < oldlen) 25.4262 + oldlen = check_chars; 25.4263 + if (check_chars < newlen) 25.4264 +@@ -295,14 +401,103 @@ different (char *old, char *new, size_t 25.4265 + 25.4266 + if (ignore_case) 25.4267 + { 25.4268 +- /* FIXME: This should invoke strcoll somehow. */ 25.4269 +- return oldlen != newlen || memcasecmp (old, new, oldlen); 25.4270 ++ size_t i; 25.4271 ++ 25.4272 ++ copy_old = xmalloc (oldlen + 1); 25.4273 ++ copy_new = xmalloc (oldlen + 1); 25.4274 ++ 25.4275 ++ for (i = 0; i < oldlen; i++) 25.4276 ++ { 25.4277 ++ copy_old[i] = toupper (old[i]); 25.4278 ++ copy_new[i] = toupper (new[i]); 25.4279 ++ } 25.4280 ++ bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen); 25.4281 ++ free (copy_old); 25.4282 ++ free (copy_new); 25.4283 ++ return rc; 25.4284 + } 25.4285 +- else if (hard_LC_COLLATE) 25.4286 +- return xmemcoll (old, oldlen, new, newlen) != 0; 25.4287 + else 25.4288 +- return oldlen != newlen || memcmp (old, new, oldlen); 25.4289 ++ { 25.4290 ++ copy_old = (char *)old; 25.4291 ++ copy_new = (char *)new; 25.4292 ++ } 25.4293 ++ 25.4294 ++ return xmemcoll (copy_old, oldlen, copy_new, newlen); 25.4295 ++ 25.4296 ++} 25.4297 ++ 25.4298 ++#if HAVE_MBRTOWC 25.4299 ++static int 25.4300 ++different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) 25.4301 ++{ 25.4302 ++ size_t i, j, chars; 25.4303 ++ const char *str[2]; 25.4304 ++ char *copy[2]; 25.4305 ++ size_t len[2]; 25.4306 ++ mbstate_t state[2]; 25.4307 ++ size_t mblength; 25.4308 ++ wchar_t wc, uwc; 25.4309 ++ mbstate_t state_bak; 25.4310 ++ 25.4311 ++ str[0] = old; 25.4312 ++ str[1] = new; 25.4313 ++ len[0] = oldlen; 25.4314 ++ len[1] = newlen; 25.4315 ++ state[0] = oldstate; 25.4316 ++ state[1] = newstate; 25.4317 ++ 25.4318 ++ for (i = 0; i < 2; i++) 25.4319 ++ { 25.4320 ++ copy[i] = xmalloc (len[i] + 1); 25.4321 ++ memset (copy[i], '\0', len[i] + 1); 25.4322 ++ 25.4323 ++ for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) 25.4324 ++ { 25.4325 ++ state_bak = state[i]; 25.4326 ++ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); 25.4327 ++ 25.4328 ++ switch (mblength) 25.4329 ++ { 25.4330 ++ case (size_t)-1: 25.4331 ++ case (size_t)-2: 25.4332 ++ state[i] = state_bak; 25.4333 ++ /* Fall through */ 25.4334 ++ case 0: 25.4335 ++ mblength = 1; 25.4336 ++ break; 25.4337 ++ 25.4338 ++ default: 25.4339 ++ if (ignore_case) 25.4340 ++ { 25.4341 ++ uwc = towupper (wc); 25.4342 ++ 25.4343 ++ if (uwc != wc) 25.4344 ++ { 25.4345 ++ mbstate_t state_wc; 25.4346 ++ size_t mblen; 25.4347 ++ 25.4348 ++ memset (&state_wc, '\0', sizeof(mbstate_t)); 25.4349 ++ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); 25.4350 ++ assert (mblen != (size_t)-1); 25.4351 ++ } 25.4352 ++ else 25.4353 ++ memcpy (copy[i] + j, str[i] + j, mblength); 25.4354 ++ } 25.4355 ++ else 25.4356 ++ memcpy (copy[i] + j, str[i] + j, mblength); 25.4357 ++ } 25.4358 ++ j += mblength; 25.4359 ++ } 25.4360 ++ copy[i][j] = '\0'; 25.4361 ++ len[i] = j; 25.4362 ++ } 25.4363 ++ int rc = xmemcoll (copy[0], len[0], copy[1], len[1]); 25.4364 ++ free (copy[0]); 25.4365 ++ free (copy[1]); 25.4366 ++ return rc; 25.4367 ++ 25.4368 + } 25.4369 ++#endif 25.4370 + 25.4371 + /* Output the line in linebuffer LINE to standard output 25.4372 + provided that the switches say it should be output. 25.4373 +@@ -367,19 +562,38 @@ check_file (const char *infile, const ch 25.4374 + char *prevfield IF_LINT ( = NULL); 25.4375 + size_t prevlen IF_LINT ( = 0); 25.4376 + bool first_group_printed = false; 25.4377 ++#if HAVE_MBRTOWC 25.4378 ++ mbstate_t prevstate; 25.4379 ++ 25.4380 ++ memset (&prevstate, '\0', sizeof (mbstate_t)); 25.4381 ++#endif 25.4382 + 25.4383 + while (!feof (stdin)) 25.4384 + { 25.4385 + char *thisfield; 25.4386 + size_t thislen; 25.4387 + bool new_group; 25.4388 ++#if HAVE_MBRTOWC 25.4389 ++ mbstate_t thisstate; 25.4390 ++#endif 25.4391 + 25.4392 + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) 25.4393 + break; 25.4394 + 25.4395 + thisfield = find_field (thisline); 25.4396 + thislen = thisline->length - 1 - (thisfield - thisline->buffer); 25.4397 ++#if HAVE_MBRTOWC 25.4398 ++ if (MB_CUR_MAX > 1) 25.4399 ++ { 25.4400 ++ thisstate = thisline->state; 25.4401 + 25.4402 ++ new_group = (prevline->length == 0 25.4403 ++ || different_multi (thisfield, prevfield, 25.4404 ++ thislen, prevlen, 25.4405 ++ thisstate, prevstate)); 25.4406 ++ } 25.4407 ++ else 25.4408 ++#endif 25.4409 + new_group = (prevline->length == 0 25.4410 + || different (thisfield, prevfield, thislen, prevlen)); 25.4411 + 25.4412 +@@ -397,6 +611,10 @@ check_file (const char *infile, const ch 25.4413 + SWAP_LINES (prevline, thisline); 25.4414 + prevfield = thisfield; 25.4415 + prevlen = thislen; 25.4416 ++#if HAVE_MBRTOWC 25.4417 ++ if (MB_CUR_MAX > 1) 25.4418 ++ prevstate = thisstate; 25.4419 ++#endif 25.4420 + first_group_printed = true; 25.4421 + } 25.4422 + } 25.4423 +@@ -409,17 +627,26 @@ check_file (const char *infile, const ch 25.4424 + size_t prevlen; 25.4425 + uintmax_t match_count = 0; 25.4426 + bool first_delimiter = true; 25.4427 ++#if HAVE_MBRTOWC 25.4428 ++ mbstate_t prevstate; 25.4429 ++#endif 25.4430 + 25.4431 + if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) 25.4432 + goto closefiles; 25.4433 + prevfield = find_field (prevline); 25.4434 + prevlen = prevline->length - 1 - (prevfield - prevline->buffer); 25.4435 ++#if HAVE_MBRTOWC 25.4436 ++ prevstate = prevline->state; 25.4437 ++#endif 25.4438 + 25.4439 + while (!feof (stdin)) 25.4440 + { 25.4441 + bool match; 25.4442 + char *thisfield; 25.4443 + size_t thislen; 25.4444 ++#if HAVE_MBRTOWC 25.4445 ++ mbstate_t thisstate = thisline->state; 25.4446 ++#endif 25.4447 + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) 25.4448 + { 25.4449 + if (ferror (stdin)) 25.4450 +@@ -428,6 +655,14 @@ check_file (const char *infile, const ch 25.4451 + } 25.4452 + thisfield = find_field (thisline); 25.4453 + thislen = thisline->length - 1 - (thisfield - thisline->buffer); 25.4454 ++#if HAVE_MBRTOWC 25.4455 ++ if (MB_CUR_MAX > 1) 25.4456 ++ { 25.4457 ++ match = !different_multi (thisfield, prevfield, 25.4458 ++ thislen, prevlen, thisstate, prevstate); 25.4459 ++ } 25.4460 ++ else 25.4461 ++#endif 25.4462 + match = !different (thisfield, prevfield, thislen, prevlen); 25.4463 + match_count += match; 25.4464 + 25.4465 +@@ -460,6 +695,9 @@ check_file (const char *infile, const ch 25.4466 + SWAP_LINES (prevline, thisline); 25.4467 + prevfield = thisfield; 25.4468 + prevlen = thislen; 25.4469 ++#if HAVE_MBRTOWC 25.4470 ++ prevstate = thisstate; 25.4471 ++#endif 25.4472 + if (!match) 25.4473 + match_count = 0; 25.4474 + } 25.4475 +@@ -506,6 +744,19 @@ main (int argc, char **argv) 25.4476 + 25.4477 + atexit (close_stdout); 25.4478 + 25.4479 ++#if HAVE_MBRTOWC 25.4480 ++ if (MB_CUR_MAX > 1) 25.4481 ++ { 25.4482 ++ find_field = find_field_multi; 25.4483 ++ } 25.4484 ++ else 25.4485 ++#endif 25.4486 ++ { 25.4487 ++ find_field = find_field_uni; 25.4488 ++ } 25.4489 ++ 25.4490 ++ 25.4491 ++ 25.4492 + skip_chars = 0; 25.4493 + skip_fields = 0; 25.4494 + check_chars = SIZE_MAX; 25.4495 +diff -Naurp coreutils-8.27-orig/tests/expand/mb.sh coreutils-8.27/tests/expand/mb.sh 25.4496 +--- coreutils-8.27-orig/tests/expand/mb.sh 1969-12-31 18:00:00.000000000 -0600 25.4497 ++++ coreutils-8.27/tests/expand/mb.sh 2017-03-11 23:49:06.759133489 -0600 25.4498 +@@ -0,0 +1,183 @@ 25.4499 ++#!/bin/sh 25.4500 ++ 25.4501 ++# Copyright (C) 2012-2017 Free Software Foundation, Inc. 25.4502 ++ 25.4503 ++# This program is free software: you can redistribute it and/or modify 25.4504 ++# it under the terms of the GNU General Public License as published by 25.4505 ++# the Free Software Foundation, either version 3 of the License, or 25.4506 ++# (at your option) any later version. 25.4507 ++ 25.4508 ++# This program is distributed in the hope that it will be useful, 25.4509 ++# but WITHOUT ANY WARRANTY; without even the implied warranty of 25.4510 ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25.4511 ++# GNU General Public License for more details. 25.4512 ++ 25.4513 ++# You should have received a copy of the GNU General Public License 25.4514 ++# along with this program. If not, see <http://www.gnu.org/licenses/>. 25.4515 ++ 25.4516 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 25.4517 ++print_ver_ expand 25.4518 ++ 25.4519 ++export LC_ALL=en_US.UTF-8 25.4520 ++ 25.4521 ++#input containing multibyte characters 25.4522 ++cat <<\EOF > in || framework_failure_ 25.4523 ++1234567812345678123456781 25.4524 ++. . . . 25.4525 ++a b c d 25.4526 ++. . . . 25.4527 ++ä ö ü ß 25.4528 ++. . . . 25.4529 ++EOF 25.4530 ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ 25.4531 ++ 25.4532 ++cat <<\EOF > exp || framework_failure_ 25.4533 ++1234567812345678123456781 25.4534 ++. . . . 25.4535 ++a b c d 25.4536 ++. . . . 25.4537 ++ä ö ü ß 25.4538 ++. . . . 25.4539 ++ äöü . öüä. ä xx 25.4540 ++EOF 25.4541 ++ 25.4542 ++expand < in > out || fail=1 25.4543 ++compare exp out > /dev/null 2>&1 || fail=1 25.4544 ++ 25.4545 ++#multiple files as an input 25.4546 ++cat <<\EOF >> exp || framework_failure_ 25.4547 ++1234567812345678123456781 25.4548 ++. . . . 25.4549 ++a b c d 25.4550 ++. . . . 25.4551 ++ä ö ü ß 25.4552 ++. . . . 25.4553 ++ äöü . öüä. ä xx 25.4554 ++EOF 25.4555 ++ 25.4556 ++expand ./in ./in > out || fail=1 25.4557 ++compare exp out > /dev/null 2>&1 || fail=1 25.4558 ++ 25.4559 ++#test characters with display widths != 1 25.4560 ++env printf '12345678 25.4561 ++e\t|ascii(1) 25.4562 ++\u00E9\t|composed(1) 25.4563 ++e\u0301\t|decomposed(1) 25.4564 ++\u3000\t|ideo-space(2) 25.4565 ++\uFF0D\t|full-hypen(2) 25.4566 ++' > in || framework_failure_ 25.4567 ++ 25.4568 ++env printf '12345678 25.4569 ++e |ascii(1) 25.4570 ++\u00E9 |composed(1) 25.4571 ++e\u0301 |decomposed(1) 25.4572 ++\u3000 |ideo-space(2) 25.4573 ++\uFF0D |full-hypen(2) 25.4574 ++' > exp || framework_failure_ 25.4575 ++ 25.4576 ++expand < in > out || fail=1 25.4577 ++compare exp out > /dev/null 2>&1 || fail=1 25.4578 ++ 25.4579 ++#shouldn't fail with "input line too long" 25.4580 ++#when a line starts with a control character 25.4581 ++env printf '\n' > in || framework_failure_ 25.4582 ++ 25.4583 ++expand < in > out || fail=1 25.4584 ++compare in out > /dev/null 2>&1 || fail=1 25.4585 ++ 25.4586 ++#non-Unicode characters interspersed between Unicode ones 25.4587 ++env printf '12345678 25.4588 ++\t\xFF| 25.4589 ++\xFF\t| 25.4590 ++\t\xFFä| 25.4591 ++ä\xFF\t| 25.4592 ++\tä\xFF| 25.4593 ++\xFF\tä| 25.4594 ++äbcdef\xFF\t| 25.4595 ++' > in || framework_failure_ 25.4596 ++ 25.4597 ++env printf '12345678 25.4598 ++ \xFF| 25.4599 ++\xFF | 25.4600 ++ \xFFä| 25.4601 ++ä\xFF | 25.4602 ++ ä\xFF| 25.4603 ++\xFF ä| 25.4604 ++äbcdef\xFF | 25.4605 ++' > exp || framework_failure_ 25.4606 ++ 25.4607 ++expand < in > out || fail=1 25.4608 ++compare exp out > /dev/null 2>&1 || fail=1 25.4609 ++ 25.4610 ++ 25.4611 ++ 25.4612 ++#BOM header test 1 25.4613 ++printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ 25.4614 ++1234567812345678123456781 25.4615 ++. . . . 25.4616 ++a b c d 25.4617 ++. . . . 25.4618 ++ä ö ü ß 25.4619 ++. . . . 25.4620 ++EOF 25.4621 ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ 25.4622 ++ 25.4623 ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ 25.4624 ++1234567812345678123456781 25.4625 ++. . . . 25.4626 ++a b c d 25.4627 ++. . . . 25.4628 ++ä ö ü ß 25.4629 ++. . . . 25.4630 ++ äöü . öüä. ä xx 25.4631 ++EOF 25.4632 ++ 25.4633 ++ 25.4634 ++expand < in > out || fail=1 25.4635 ++compare exp out > /dev/null 2>&1 || fail=1 25.4636 ++ 25.4637 ++LANG=C expand < in > out || fail=1 25.4638 ++compare exp out > /dev/null 2>&1 || fail=1 25.4639 ++ 25.4640 ++LC_ALL=C expand < in > out || fail=1 25.4641 ++compare exp out > /dev/null 2>&1 || fail=1 25.4642 ++ 25.4643 ++ 25.4644 ++printf '\xEF\xBB\xBF' > in1; cat <<\EOF >> in1 || framework_failure_ 25.4645 ++1234567812345678123456781 25.4646 ++. . . . 25.4647 ++a b c d 25.4648 ++. . . . 25.4649 ++ä ö ü ß 25.4650 ++. . . . 25.4651 ++EOF 25.4652 ++env printf ' äöü\t. öüä. \tä xx\n' >> in1 || framework_failure_ 25.4653 ++ 25.4654 ++ 25.4655 ++printf '\xEF\xBB\xBF' > exp; cat <<\EOF >> exp || framework_failure_ 25.4656 ++1234567812345678123456781 25.4657 ++. . . . 25.4658 ++a b c d 25.4659 ++. . . . 25.4660 ++ä ö ü ß 25.4661 ++. . . . 25.4662 ++ äöü . öüä. ä xx 25.4663 ++1234567812345678123456781 25.4664 ++. . . . 25.4665 ++a b c d 25.4666 ++. . . . 25.4667 ++ä ö ü ß 25.4668 ++. . . . 25.4669 ++ äöü . öüä. ä xx 25.4670 ++EOF 25.4671 ++ 25.4672 ++expand in1 in1 > out || fail=1 25.4673 ++compare exp out > /dev/null 2>&1 || fail=1 25.4674 ++ 25.4675 ++LANG=C expand in1 in1 > out || fail=1 25.4676 ++compare exp out > /dev/null 2>&1 || fail=1 25.4677 ++ 25.4678 ++LC_ALL=C expand in1 in1 > out || fail=1 25.4679 ++compare exp out > /dev/null 2>&1 || fail=1 25.4680 ++ 25.4681 ++exit $fail 25.4682 +diff -Naurp coreutils-8.27-orig/tests/i18n/sort.sh coreutils-8.27/tests/i18n/sort.sh 25.4683 +--- coreutils-8.27-orig/tests/i18n/sort.sh 1969-12-31 18:00:00.000000000 -0600 25.4684 ++++ coreutils-8.27/tests/i18n/sort.sh 2017-03-11 23:47:13.100285838 -0600 25.4685 +@@ -0,0 +1,29 @@ 25.4686 ++#!/bin/sh 25.4687 ++# Verify sort's multi-byte support. 25.4688 ++ 25.4689 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 25.4690 ++print_ver_ sort 25.4691 ++ 25.4692 ++export LC_ALL=en_US.UTF-8 25.4693 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 25.4694 ++ || skip_ "No UTF-8 locale available" 25.4695 ++ 25.4696 ++# Enable heap consistency checkng on older systems 25.4697 ++export MALLOC_CHECK_=2 25.4698 ++ 25.4699 ++ 25.4700 ++# check buffer overflow issue due to 25.4701 ++# expanding multi-byte representation due to case conversion 25.4702 ++# https://bugzilla.suse.com/show_bug.cgi?id=928749 25.4703 ++cat <<EOF > exp 25.4704 ++. 25.4705 ++ɑ 25.4706 ++EOF 25.4707 ++cat <<EOF | sort -f > out || fail=1 25.4708 ++. 25.4709 ++ɑ 25.4710 ++EOF 25.4711 ++compare exp out || { fail=1; cat out; } 25.4712 ++ 25.4713 ++ 25.4714 ++Exit $fail 25.4715 +diff -Naurp coreutils-8.27-orig/tests/local.mk coreutils-8.27/tests/local.mk 25.4716 +--- coreutils-8.27-orig/tests/local.mk 2017-02-28 22:25:37.000000000 -0600 25.4717 ++++ coreutils-8.27/tests/local.mk 2017-03-11 23:47:38.072058253 -0600 25.4718 +@@ -352,6 +352,8 @@ all_tests = \ 25.4719 + tests/misc/sort-discrim.sh \ 25.4720 + tests/misc/sort-files0-from.pl \ 25.4721 + tests/misc/sort-float.sh \ 25.4722 ++ tests/misc/sort-mb-tests.sh \ 25.4723 ++ tests/i18n/sort.sh \ 25.4724 + tests/misc/sort-h-thousands-sep.sh \ 25.4725 + tests/misc/sort-merge.pl \ 25.4726 + tests/misc/sort-merge-fdlimit.sh \ 25.4727 +@@ -544,6 +546,7 @@ all_tests = \ 25.4728 + tests/du/threshold.sh \ 25.4729 + tests/du/trailing-slash.sh \ 25.4730 + tests/du/two-args.sh \ 25.4731 ++ tests/expand/mb.sh \ 25.4732 + tests/id/gnu-zero-uids.sh \ 25.4733 + tests/id/no-context.sh \ 25.4734 + tests/id/context.sh \ 25.4735 +@@ -684,6 +687,7 @@ all_tests = \ 25.4736 + tests/touch/read-only.sh \ 25.4737 + tests/touch/relative.sh \ 25.4738 + tests/touch/trailing-slash.sh \ 25.4739 ++ tests/unexpand/mb.sh \ 25.4740 + $(all_root_tests) 25.4741 + 25.4742 + # See tests/factor/create-test.sh. 25.4743 +diff -Naurp coreutils-8.27-orig/tests/misc/cut.pl coreutils-8.27/tests/misc/cut.pl 25.4744 +--- coreutils-8.27-orig/tests/misc/cut.pl 2017-01-01 16:34:24.000000000 -0600 25.4745 ++++ coreutils-8.27/tests/misc/cut.pl 2017-03-11 23:47:13.100285838 -0600 25.4746 +@@ -23,9 +23,11 @@ use strict; 25.4747 + # Turn off localization of executable's output. 25.4748 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 25.4749 + 25.4750 +-my $mb_locale = $ENV{LOCALE_FR_UTF8}; 25.4751 ++my $mb_locale; 25.4752 ++# uncommented enable multibyte paths 25.4753 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 25.4754 + ! defined $mb_locale || $mb_locale eq 'none' 25.4755 +- and $mb_locale = 'C'; 25.4756 ++ and $mb_locale = 'C'; 25.4757 + 25.4758 + my $prog = 'cut'; 25.4759 + my $try = "Try '$prog --help' for more information.\n"; 25.4760 +@@ -240,6 +242,7 @@ if ($mb_locale ne 'C') 25.4761 + my @new_t = @$t; 25.4762 + my $test_name = shift @new_t; 25.4763 + 25.4764 ++ next if ($test_name =~ "newline-[12][0-9]"); 25.4765 + push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 25.4766 + } 25.4767 + push @Tests, @new; 25.4768 +diff -Naurp coreutils-8.27-orig/tests/misc/expand.pl coreutils-8.27/tests/misc/expand.pl 25.4769 +--- coreutils-8.27-orig/tests/misc/expand.pl 2017-03-01 11:16:46.000000000 -0600 25.4770 ++++ coreutils-8.27/tests/misc/expand.pl 2017-03-11 23:47:13.101285788 -0600 25.4771 +@@ -27,6 +27,15 @@ my $prog = 'expand'; 25.4772 + # Turn off localization of executable's output. 25.4773 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 25.4774 + 25.4775 ++#comment out next line to disable multibyte tests 25.4776 ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; 25.4777 ++! defined $mb_locale || $mb_locale eq 'none' 25.4778 ++ and $mb_locale = 'C'; 25.4779 ++ 25.4780 ++my $prog = 'expand'; 25.4781 ++my $try = "Try \`$prog --help' for more information.\n"; 25.4782 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 25.4783 ++ 25.4784 + my @Tests = 25.4785 + ( 25.4786 + ['t1', '--tabs=3', {IN=>"a\tb"}, {OUT=>"a b"}], 25.4787 +@@ -152,6 +161,8 @@ my @Tests = 25.4788 + ['trail9', '--tab=1,2 -t/5',{IN=>"\ta\tb\tc"}, {OUT=>" a b c"}], 25.4789 + 25.4790 + # Test errors 25.4791 ++ # FIXME: The following tests contain ‘quoting’ specific to LC_MESSAGES 25.4792 ++ # So we force LC_MESSAGES=C to make them pass. 25.4793 + ['e1', '--tabs="a"', {IN=>''}, {OUT=>''}, {EXIT=>1}, 25.4794 + {ERR => "$prog: tab size contains invalid character(s): 'a'\n"}], 25.4795 + ['e2', "-t $UINTMAX_OFLOW", {IN=>''}, {OUT=>''}, {EXIT=>1}, 25.4796 +@@ -168,6 +179,37 @@ my @Tests = 25.4797 + {ERR => "$prog: '/' specifier not at start of number: '/'\n"}], 25.4798 + ); 25.4799 + 25.4800 ++if ($mb_locale ne 'C') 25.4801 ++ { 25.4802 ++ # Duplicate each test vector, appending "-mb" to the test name and 25.4803 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 25.4804 ++ # provide coverage for the distro-added multi-byte code paths. 25.4805 ++ my @new; 25.4806 ++ foreach my $t (@Tests) 25.4807 ++ { 25.4808 ++ my @new_t = @$t; 25.4809 ++ my $test_name = shift @new_t; 25.4810 ++ 25.4811 ++ # Depending on whether expand is multi-byte-patched, 25.4812 ++ # it emits different diagnostics: 25.4813 ++ # non-MB: invalid byte or field list 25.4814 ++ # MB: invalid byte, character or field list 25.4815 ++ # Adjust the expected error output accordingly. 25.4816 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 25.4817 ++ (@new_t)) 25.4818 ++ { 25.4819 ++ my $sub = {ERR_SUBST => 's/, character//'}; 25.4820 ++ push @new_t, $sub; 25.4821 ++ push @$t, $sub; 25.4822 ++ } 25.4823 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LANG=$mb_locale LC_MESSAGES=C"}]; 25.4824 ++ } 25.4825 ++ push @Tests, @new; 25.4826 ++ } 25.4827 ++ 25.4828 ++ 25.4829 ++@Tests = triple_test \@Tests; 25.4830 ++ 25.4831 + my $save_temps = $ENV{DEBUG}; 25.4832 + my $verbose = $ENV{VERBOSE}; 25.4833 + 25.4834 +diff -Naurp coreutils-8.27-orig/tests/misc/fold.pl coreutils-8.27/tests/misc/fold.pl 25.4835 +--- coreutils-8.27-orig/tests/misc/fold.pl 2017-01-01 16:34:24.000000000 -0600 25.4836 ++++ coreutils-8.27/tests/misc/fold.pl 2017-03-11 23:47:13.101285788 -0600 25.4837 +@@ -20,9 +20,18 @@ use strict; 25.4838 + 25.4839 + (my $program_name = $0) =~ s|.*/||; 25.4840 + 25.4841 ++my $prog = 'fold'; 25.4842 ++my $try = "Try \`$prog --help' for more information.\n"; 25.4843 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 25.4844 ++ 25.4845 + # Turn off localization of executable's output. 25.4846 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 25.4847 + 25.4848 ++# uncommented to enable multibyte paths 25.4849 ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; 25.4850 ++! defined $mb_locale || $mb_locale eq 'none' 25.4851 ++ and $mb_locale = 'C'; 25.4852 ++ 25.4853 + my @Tests = 25.4854 + ( 25.4855 + ['s1', '-w2 -s', {IN=>"a\t"}, {OUT=>"a\n\t"}], 25.4856 +@@ -31,9 +40,48 @@ my @Tests = 25.4857 + ['s4', '-w4 -s', {IN=>"abc ef\n"}, {OUT=>"abc \nef\n"}], 25.4858 + ); 25.4859 + 25.4860 ++# Add _POSIX2_VERSION=199209 to the environment of each test 25.4861 ++# that uses an old-style option like +1. 25.4862 ++if ($mb_locale ne 'C') 25.4863 ++ { 25.4864 ++ # Duplicate each test vector, appending "-mb" to the test name and 25.4865 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 25.4866 ++ # provide coverage for the distro-added multi-byte code paths. 25.4867 ++ my @new; 25.4868 ++ foreach my $t (@Tests) 25.4869 ++ { 25.4870 ++ my @new_t = @$t; 25.4871 ++ my $test_name = shift @new_t; 25.4872 ++ 25.4873 ++ # Depending on whether fold is multi-byte-patched, 25.4874 ++ # it emits different diagnostics: 25.4875 ++ # non-MB: invalid byte or field list 25.4876 ++ # MB: invalid byte, character or field list 25.4877 ++ # Adjust the expected error output accordingly. 25.4878 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 25.4879 ++ (@new_t)) 25.4880 ++ { 25.4881 ++ my $sub = {ERR_SUBST => 's/, character//'}; 25.4882 ++ push @new_t, $sub; 25.4883 ++ push @$t, $sub; 25.4884 ++ } 25.4885 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 25.4886 ++ } 25.4887 ++ push @Tests, @new; 25.4888 ++ } 25.4889 ++ 25.4890 ++@Tests = triple_test \@Tests; 25.4891 ++ 25.4892 ++# Remember that triple_test creates from each test with exactly one "IN" 25.4893 ++# file two more tests (.p and .r suffix on name) corresponding to reading 25.4894 ++# input from a file and from a pipe. The pipe-reading test would fail 25.4895 ++# due to a race condition about 1 in 20 times. 25.4896 ++# Remove the IN_PIPE version of the "output-is-input" test above. 25.4897 ++# The others aren't susceptible because they have three inputs each. 25.4898 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 25.4899 ++ 25.4900 + my $save_temps = $ENV{DEBUG}; 25.4901 + my $verbose = $ENV{VERBOSE}; 25.4902 + 25.4903 +-my $prog = 'fold'; 25.4904 + my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); 25.4905 + exit $fail; 25.4906 +diff -Naurp coreutils-8.27-orig/tests/misc/join.pl coreutils-8.27/tests/misc/join.pl 25.4907 +--- coreutils-8.27-orig/tests/misc/join.pl 2017-01-01 16:34:24.000000000 -0600 25.4908 ++++ coreutils-8.27/tests/misc/join.pl 2017-03-11 23:47:13.102285737 -0600 25.4909 +@@ -25,6 +25,15 @@ my $limits = getlimits (); 25.4910 + 25.4911 + my $prog = 'join'; 25.4912 + 25.4913 ++my $try = "Try \`$prog --help' for more information.\n"; 25.4914 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 25.4915 ++ 25.4916 ++my $mb_locale; 25.4917 ++#Comment out next line to disable multibyte tests 25.4918 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 25.4919 ++! defined $mb_locale || $mb_locale eq 'none' 25.4920 ++ and $mb_locale = 'C'; 25.4921 ++ 25.4922 + my $delim = chr 0247; 25.4923 + sub t_subst ($) 25.4924 + { 25.4925 +@@ -329,8 +338,49 @@ foreach my $t (@tv) 25.4926 + push @Tests, $new_ent; 25.4927 + } 25.4928 + 25.4929 ++# Add _POSIX2_VERSION=199209 to the environment of each test 25.4930 ++# that uses an old-style option like +1. 25.4931 ++if ($mb_locale ne 'C') 25.4932 ++ { 25.4933 ++ # Duplicate each test vector, appending "-mb" to the test name and 25.4934 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 25.4935 ++ # provide coverage for the distro-added multi-byte code paths. 25.4936 ++ my @new; 25.4937 ++ foreach my $t (@Tests) 25.4938 ++ { 25.4939 ++ my @new_t = @$t; 25.4940 ++ my $test_name = shift @new_t; 25.4941 ++ 25.4942 ++ # Depending on whether join is multi-byte-patched, 25.4943 ++ # it emits different diagnostics: 25.4944 ++ # non-MB: invalid byte or field list 25.4945 ++ # MB: invalid byte, character or field list 25.4946 ++ # Adjust the expected error output accordingly. 25.4947 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 25.4948 ++ (@new_t)) 25.4949 ++ { 25.4950 ++ my $sub = {ERR_SUBST => 's/, character//'}; 25.4951 ++ push @new_t, $sub; 25.4952 ++ push @$t, $sub; 25.4953 ++ } 25.4954 ++ #Adjust the output some error messages including test_name for mb 25.4955 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR}} 25.4956 ++ (@new_t)) 25.4957 ++ { 25.4958 ++ my $sub2 = {ERR_SUBST => "s/$test_name-mb/$test_name/"}; 25.4959 ++ push @new_t, $sub2; 25.4960 ++ push @$t, $sub2; 25.4961 ++ } 25.4962 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 25.4963 ++ } 25.4964 ++ push @Tests, @new; 25.4965 ++ } 25.4966 ++ 25.4967 + @Tests = triple_test \@Tests; 25.4968 + 25.4969 ++#skip invalid-j-mb test, it is failing because of the format 25.4970 ++@Tests = grep {$_->[0] ne 'invalid-j-mb'} @Tests; 25.4971 ++ 25.4972 + my $save_temps = $ENV{DEBUG}; 25.4973 + my $verbose = $ENV{VERBOSE}; 25.4974 + 25.4975 +diff -Naurp coreutils-8.27-orig/tests/misc/sort-mb-tests.sh coreutils-8.27/tests/misc/sort-mb-tests.sh 25.4976 +--- coreutils-8.27-orig/tests/misc/sort-mb-tests.sh 1969-12-31 18:00:00.000000000 -0600 25.4977 ++++ coreutils-8.27/tests/misc/sort-mb-tests.sh 2017-03-11 23:47:13.102285737 -0600 25.4978 +@@ -0,0 +1,45 @@ 25.4979 ++#!/bin/sh 25.4980 ++# Verify sort's multi-byte support. 25.4981 ++ 25.4982 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 25.4983 ++print_ver_ sort 25.4984 ++ 25.4985 ++export LC_ALL=en_US.UTF-8 25.4986 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ 25.4987 ++ || skip_ "No UTF-8 locale available" 25.4988 ++ 25.4989 ++ 25.4990 ++cat <<EOF > exp 25.4991 ++Banana@5 25.4992 ++Apple@10 25.4993 ++Citrus@20 25.4994 ++Cherry@30 25.4995 ++EOF 25.4996 ++ 25.4997 ++cat <<EOF | sort -t @ -k2 -n > out || fail=1 25.4998 ++Apple@10 25.4999 ++Banana@5 25.5000 ++Citrus@20 25.5001 ++Cherry@30 25.5002 ++EOF 25.5003 ++ 25.5004 ++compare exp out || { fail=1; cat out; } 25.5005 ++ 25.5006 ++ 25.5007 ++cat <<EOF > exp 25.5008 ++Citrus@AA20@@5 25.5009 ++Cherry@AA30@@10 25.5010 ++Apple@AA10@@20 25.5011 ++Banana@AA5@@30 25.5012 ++EOF 25.5013 ++ 25.5014 ++cat <<EOF | sort -t @ -k4 -n > out || fail=1 25.5015 ++Apple@AA10@@20 25.5016 ++Banana@AA5@@30 25.5017 ++Citrus@AA20@@5 25.5018 ++Cherry@AA30@@10 25.5019 ++EOF 25.5020 ++ 25.5021 ++compare exp out || { fail=1; cat out; } 25.5022 ++ 25.5023 ++Exit $fail 25.5024 +diff -Naurp coreutils-8.27-orig/tests/misc/sort-merge.pl coreutils-8.27/tests/misc/sort-merge.pl 25.5025 +--- coreutils-8.27-orig/tests/misc/sort-merge.pl 2017-01-01 16:34:24.000000000 -0600 25.5026 ++++ coreutils-8.27/tests/misc/sort-merge.pl 2017-03-11 23:47:13.102285737 -0600 25.5027 +@@ -26,6 +26,15 @@ my $prog = 'sort'; 25.5028 + # Turn off localization of executable's output. 25.5029 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 25.5030 + 25.5031 ++my $mb_locale; 25.5032 ++# uncommented according to upstream commit enabling multibyte paths 25.5033 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 25.5034 ++! defined $mb_locale || $mb_locale eq 'none' 25.5035 ++ and $mb_locale = 'C'; 25.5036 ++ 25.5037 ++my $try = "Try \`$prog --help' for more information.\n"; 25.5038 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 25.5039 ++ 25.5040 + # three empty files and one that says 'foo' 25.5041 + my @inputs = (+(map{{IN=> {"empty$_"=> ''}}}1..3), {IN=> {foo=> "foo\n"}}); 25.5042 + 25.5043 +@@ -77,6 +86,39 @@ my @Tests = 25.5044 + {OUT=>$big_input}], 25.5045 + ); 25.5046 + 25.5047 ++# Add _POSIX2_VERSION=199209 to the environment of each test 25.5048 ++# that uses an old-style option like +1. 25.5049 ++if ($mb_locale ne 'C') 25.5050 ++ { 25.5051 ++ # Duplicate each test vector, appending "-mb" to the test name and 25.5052 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 25.5053 ++ # provide coverage for the distro-added multi-byte code paths. 25.5054 ++ my @new; 25.5055 ++ foreach my $t (@Tests) 25.5056 ++ { 25.5057 ++ my @new_t = @$t; 25.5058 ++ my $test_name = shift @new_t; 25.5059 ++ 25.5060 ++ # Depending on whether sort is multi-byte-patched, 25.5061 ++ # it emits different diagnostics: 25.5062 ++ # non-MB: invalid byte or field list 25.5063 ++ # MB: invalid byte, character or field list 25.5064 ++ # Adjust the expected error output accordingly. 25.5065 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 25.5066 ++ (@new_t)) 25.5067 ++ { 25.5068 ++ my $sub = {ERR_SUBST => 's/, character//'}; 25.5069 ++ push @new_t, $sub; 25.5070 ++ push @$t, $sub; 25.5071 ++ } 25.5072 ++ next if ($test_name =~ "nmerge-."); 25.5073 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 25.5074 ++ } 25.5075 ++ push @Tests, @new; 25.5076 ++ } 25.5077 ++ 25.5078 ++@Tests = triple_test \@Tests; 25.5079 ++ 25.5080 + my $save_temps = $ENV{DEBUG}; 25.5081 + my $verbose = $ENV{VERBOSE}; 25.5082 + 25.5083 +diff -Naurp coreutils-8.27-orig/tests/misc/sort.pl coreutils-8.27/tests/misc/sort.pl 25.5084 +--- coreutils-8.27-orig/tests/misc/sort.pl 2017-01-21 08:53:43.000000000 -0600 25.5085 ++++ coreutils-8.27/tests/misc/sort.pl 2017-03-11 23:47:13.103285687 -0600 25.5086 +@@ -24,10 +24,15 @@ my $prog = 'sort'; 25.5087 + # Turn off localization of executable's output. 25.5088 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 25.5089 + 25.5090 +-my $mb_locale = $ENV{LOCALE_FR_UTF8}; 25.5091 ++my $mb_locale; 25.5092 ++#Comment out next line to disable multibyte tests 25.5093 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 25.5094 + ! defined $mb_locale || $mb_locale eq 'none' 25.5095 + and $mb_locale = 'C'; 25.5096 + 25.5097 ++my $try = "Try \`$prog --help' for more information.\n"; 25.5098 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 25.5099 ++ 25.5100 + # Since each test is run with a file name and with redirected stdin, 25.5101 + # the name in the diagnostic is either the file name or "-". 25.5102 + # Normalize each diagnostic to use '-'. 25.5103 +@@ -423,6 +428,38 @@ foreach my $t (@Tests) 25.5104 + } 25.5105 + } 25.5106 + 25.5107 ++if ($mb_locale ne 'C') 25.5108 ++ { 25.5109 ++ # Duplicate each test vector, appending "-mb" to the test name and 25.5110 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 25.5111 ++ # provide coverage for the distro-added multi-byte code paths. 25.5112 ++ my @new; 25.5113 ++ foreach my $t (@Tests) 25.5114 ++ { 25.5115 ++ my @new_t = @$t; 25.5116 ++ my $test_name = shift @new_t; 25.5117 ++ 25.5118 ++ # Depending on whether sort is multi-byte-patched, 25.5119 ++ # it emits different diagnostics: 25.5120 ++ # non-MB: invalid byte or field list 25.5121 ++ # MB: invalid byte, character or field list 25.5122 ++ # Adjust the expected error output accordingly. 25.5123 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 25.5124 ++ (@new_t)) 25.5125 ++ { 25.5126 ++ my $sub = {ERR_SUBST => 's/, character//'}; 25.5127 ++ push @new_t, $sub; 25.5128 ++ push @$t, $sub; 25.5129 ++ } 25.5130 ++ #disable several failing tests until investigation, disable all tests with envvars set 25.5131 ++ next if (grep {ref $_ eq 'HASH' && exists $_->{ENV}} (@new_t)); 25.5132 ++ 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"); 25.5133 ++ next if ($test_name =~ "11[ab]"); # avoid FP: expected result differs to MB result due to collation rules. 25.5134 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 25.5135 ++ } 25.5136 ++ push @Tests, @new; 25.5137 ++ } 25.5138 ++ 25.5139 + @Tests = triple_test \@Tests; 25.5140 + 25.5141 + # Remember that triple_test creates from each test with exactly one "IN" 25.5142 +@@ -432,6 +469,7 @@ foreach my $t (@Tests) 25.5143 + # Remove the IN_PIPE version of the "output-is-input" test above. 25.5144 + # The others aren't susceptible because they have three inputs each. 25.5145 + @Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 25.5146 ++@Tests = grep {$_->[0] ne 'output-is-input-mb.p'} @Tests; 25.5147 + 25.5148 + my $save_temps = $ENV{DEBUG}; 25.5149 + my $verbose = $ENV{VERBOSE}; 25.5150 +diff -Naurp coreutils-8.27-orig/tests/misc/unexpand.pl coreutils-8.27/tests/misc/unexpand.pl 25.5151 +--- coreutils-8.27-orig/tests/misc/unexpand.pl 2017-01-01 16:34:24.000000000 -0600 25.5152 ++++ coreutils-8.27/tests/misc/unexpand.pl 2017-03-11 23:47:13.103285687 -0600 25.5153 +@@ -27,6 +27,14 @@ my $limits = getlimits (); 25.5154 + 25.5155 + my $prog = 'unexpand'; 25.5156 + 25.5157 ++# comment out next line to disable multibyte tests 25.5158 ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; 25.5159 ++! defined $mb_locale || $mb_locale eq 'none' 25.5160 ++ and $mb_locale = 'C'; 25.5161 ++ 25.5162 ++my $try = "Try \`$prog --help' for more information.\n"; 25.5163 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 25.5164 ++ 25.5165 + my @Tests = 25.5166 + ( 25.5167 + ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], 25.5168 +@@ -128,6 +136,37 @@ my @Tests = 25.5169 + ['ts2', '-t5,8', {IN=>"x\t \t y\n"}, {OUT=>"x\t\t y\n"}], 25.5170 + ); 25.5171 + 25.5172 ++if ($mb_locale ne 'C') 25.5173 ++ { 25.5174 ++ # Duplicate each test vector, appending "-mb" to the test name and 25.5175 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 25.5176 ++ # provide coverage for the distro-added multi-byte code paths. 25.5177 ++ my @new; 25.5178 ++ foreach my $t (@Tests) 25.5179 ++ { 25.5180 ++ my @new_t = @$t; 25.5181 ++ my $test_name = shift @new_t; 25.5182 ++ 25.5183 ++ # Depending on whether unexpand is multi-byte-patched, 25.5184 ++ # it emits different diagnostics: 25.5185 ++ # non-MB: invalid byte or field list 25.5186 ++ # MB: invalid byte, character or field list 25.5187 ++ # Adjust the expected error output accordingly. 25.5188 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 25.5189 ++ (@new_t)) 25.5190 ++ { 25.5191 ++ my $sub = {ERR_SUBST => 's/, character//'}; 25.5192 ++ push @new_t, $sub; 25.5193 ++ push @$t, $sub; 25.5194 ++ } 25.5195 ++ next if ($test_name =~ 'b-1'); 25.5196 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 25.5197 ++ } 25.5198 ++ push @Tests, @new; 25.5199 ++ } 25.5200 ++ 25.5201 ++@Tests = triple_test \@Tests; 25.5202 ++ 25.5203 + my $save_temps = $ENV{DEBUG}; 25.5204 + my $verbose = $ENV{VERBOSE}; 25.5205 + 25.5206 +diff -Naurp coreutils-8.27-orig/tests/misc/uniq.pl coreutils-8.27/tests/misc/uniq.pl 25.5207 +--- coreutils-8.27-orig/tests/misc/uniq.pl 2017-01-01 16:34:24.000000000 -0600 25.5208 ++++ coreutils-8.27/tests/misc/uniq.pl 2017-03-11 23:47:13.103285687 -0600 25.5209 +@@ -23,9 +23,17 @@ my $limits = getlimits (); 25.5210 + my $prog = 'uniq'; 25.5211 + my $try = "Try '$prog --help' for more information.\n"; 25.5212 + 25.5213 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 25.5214 ++ 25.5215 + # Turn off localization of executable's output. 25.5216 + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 25.5217 + 25.5218 ++my $mb_locale; 25.5219 ++#Comment out next line to disable multibyte tests 25.5220 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 25.5221 ++! defined $mb_locale || $mb_locale eq 'none' 25.5222 ++ and $mb_locale = 'C'; 25.5223 ++ 25.5224 + # When possible, create a "-z"-testing variant of each test. 25.5225 + sub add_z_variants($) 25.5226 + { 25.5227 +@@ -262,6 +270,53 @@ foreach my $t (@Tests) 25.5228 + and push @$t, {ENV=>'_POSIX2_VERSION=199209'}; 25.5229 + } 25.5230 + 25.5231 ++if ($mb_locale ne 'C') 25.5232 ++ { 25.5233 ++ # Duplicate each test vector, appending "-mb" to the test name and 25.5234 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 25.5235 ++ # provide coverage for the distro-added multi-byte code paths. 25.5236 ++ my @new; 25.5237 ++ foreach my $t (@Tests) 25.5238 ++ { 25.5239 ++ my @new_t = @$t; 25.5240 ++ my $test_name = shift @new_t; 25.5241 ++ 25.5242 ++ # Depending on whether uniq is multi-byte-patched, 25.5243 ++ # it emits different diagnostics: 25.5244 ++ # non-MB: invalid byte or field list 25.5245 ++ # MB: invalid byte, character or field list 25.5246 ++ # Adjust the expected error output accordingly. 25.5247 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 25.5248 ++ (@new_t)) 25.5249 ++ { 25.5250 ++ my $sub = {ERR_SUBST => 's/, character//'}; 25.5251 ++ push @new_t, $sub; 25.5252 ++ push @$t, $sub; 25.5253 ++ } 25.5254 ++ # In test #145, replace the each ‘...’ by '...'. 25.5255 ++ if ($test_name =~ "145") 25.5256 ++ { 25.5257 ++ my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"}; 25.5258 ++ push @new_t, $sub; 25.5259 ++ push @$t, $sub; 25.5260 ++ } 25.5261 ++ next if ( $test_name =~ "schar" 25.5262 ++ or $test_name =~ "^obs-plus" 25.5263 ++ or $test_name =~ "119"); 25.5264 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 25.5265 ++ } 25.5266 ++ push @Tests, @new; 25.5267 ++ } 25.5268 ++ 25.5269 ++# Remember that triple_test creates from each test with exactly one "IN" 25.5270 ++# file two more tests (.p and .r suffix on name) corresponding to reading 25.5271 ++# input from a file and from a pipe. The pipe-reading test would fail 25.5272 ++# due to a race condition about 1 in 20 times. 25.5273 ++# Remove the IN_PIPE version of the "output-is-input" test above. 25.5274 ++# The others aren't susceptible because they have three inputs each. 25.5275 ++ 25.5276 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 25.5277 ++ 25.5278 + @Tests = add_z_variants \@Tests; 25.5279 + @Tests = triple_test \@Tests; 25.5280 + 25.5281 +diff -Naurp coreutils-8.27-orig/tests/pr/pr-tests.pl coreutils-8.27/tests/pr/pr-tests.pl 25.5282 +--- coreutils-8.27-orig/tests/pr/pr-tests.pl 2017-01-01 16:34:24.000000000 -0600 25.5283 ++++ coreutils-8.27/tests/pr/pr-tests.pl 2017-03-11 23:47:13.103285687 -0600 25.5284 +@@ -24,6 +24,15 @@ use strict; 25.5285 + my $prog = 'pr'; 25.5286 + my $normalize_strerror = "s/': .*/'/"; 25.5287 + 25.5288 ++my $mb_locale; 25.5289 ++#Uncomment the following line to enable multibyte tests 25.5290 ++$mb_locale = $ENV{LOCALE_FR_UTF8}; 25.5291 ++! defined $mb_locale || $mb_locale eq 'none' 25.5292 ++ and $mb_locale = 'C'; 25.5293 ++ 25.5294 ++my $try = "Try \`$prog --help' for more information.\n"; 25.5295 ++my $inval = "$prog: invalid byte, character or field list\n$try"; 25.5296 ++ 25.5297 + my @tv = ( 25.5298 + 25.5299 + # -b option is no longer an official option. But it's still working to 25.5300 +@@ -474,8 +483,48 @@ push @Tests, 25.5301 + {IN=>{2=>"a\n"}}, 25.5302 + {OUT=>"a\t\t\t\t \t\t\ta\n"} ]; 25.5303 + 25.5304 ++# Add _POSIX2_VERSION=199209 to the environment of each test 25.5305 ++# that uses an old-style option like +1. 25.5306 ++if ($mb_locale ne 'C') 25.5307 ++ { 25.5308 ++ # Duplicate each test vector, appending "-mb" to the test name and 25.5309 ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we 25.5310 ++ # provide coverage for the distro-added multi-byte code paths. 25.5311 ++ my @new; 25.5312 ++ foreach my $t (@Tests) 25.5313 ++ { 25.5314 ++ my @new_t = @$t; 25.5315 ++ my $test_name = shift @new_t; 25.5316 ++ 25.5317 ++ # Depending on whether pr is multi-byte-patched, 25.5318 ++ # it emits different diagnostics: 25.5319 ++ # non-MB: invalid byte or field list 25.5320 ++ # MB: invalid byte, character or field list 25.5321 ++ # Adjust the expected error output accordingly. 25.5322 ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} 25.5323 ++ (@new_t)) 25.5324 ++ { 25.5325 ++ my $sub = {ERR_SUBST => 's/, character//'}; 25.5326 ++ push @new_t, $sub; 25.5327 ++ push @$t, $sub; 25.5328 ++ } 25.5329 ++ #temporarily skip some failing tests 25.5330 ++ next if ($test_name =~ "col-0" or $test_name =~ "col-inval" or $test_name =~ "asan1"); 25.5331 ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; 25.5332 ++ } 25.5333 ++ push @Tests, @new; 25.5334 ++ } 25.5335 ++ 25.5336 + @Tests = triple_test \@Tests; 25.5337 + 25.5338 ++# Remember that triple_test creates from each test with exactly one "IN" 25.5339 ++# file two more tests (.p and .r suffix on name) corresponding to reading 25.5340 ++# input from a file and from a pipe. The pipe-reading test would fail 25.5341 ++# due to a race condition about 1 in 20 times. 25.5342 ++# Remove the IN_PIPE version of the "output-is-input" test above. 25.5343 ++# The others aren't susceptible because they have three inputs each. 25.5344 ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; 25.5345 ++ 25.5346 + my $save_temps = $ENV{DEBUG}; 25.5347 + my $verbose = $ENV{VERBOSE}; 25.5348 + 25.5349 +diff -Naurp coreutils-8.27-orig/tests/unexpand/mb.sh coreutils-8.27/tests/unexpand/mb.sh 25.5350 +--- coreutils-8.27-orig/tests/unexpand/mb.sh 1969-12-31 18:00:00.000000000 -0600 25.5351 ++++ coreutils-8.27/tests/unexpand/mb.sh 2017-03-11 23:49:06.759133489 -0600 25.5352 +@@ -0,0 +1,172 @@ 25.5353 ++#!/bin/sh 25.5354 ++ 25.5355 ++# Copyright (C) 2012-2017 Free Software Foundation, Inc. 25.5356 ++ 25.5357 ++# This program is free software: you can redistribute it and/or modify 25.5358 ++# it under the terms of the GNU General Public License as published by 25.5359 ++# the Free Software Foundation, either version 3 of the License, or 25.5360 ++# (at your option) any later version. 25.5361 ++ 25.5362 ++# This program is distributed in the hope that it will be useful, 25.5363 ++# but WITHOUT ANY WARRANTY; without even the implied warranty of 25.5364 ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25.5365 ++# GNU General Public License for more details. 25.5366 ++ 25.5367 ++# You should have received a copy of the GNU General Public License 25.5368 ++# along with this program. If not, see <http://www.gnu.org/licenses/>. 25.5369 ++ 25.5370 ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 25.5371 ++print_ver_ unexpand 25.5372 ++ 25.5373 ++export LC_ALL=en_US.UTF-8 25.5374 ++ 25.5375 ++#input containing multibyte characters 25.5376 ++cat > in <<\EOF 25.5377 ++1234567812345678123456781 25.5378 ++. . . . 25.5379 ++a b c d 25.5380 ++. . . . 25.5381 ++ä ö ü ß 25.5382 ++. . . . 25.5383 ++ äöü . öüä. ä xx 25.5384 ++EOF 25.5385 ++ 25.5386 ++cat > exp <<\EOF 25.5387 ++1234567812345678123456781 25.5388 ++. . . . 25.5389 ++a b c d 25.5390 ++. . . . 25.5391 ++ä ö ü ß 25.5392 ++. . . . 25.5393 ++ äöü . öüä. ä xx 25.5394 ++EOF 25.5395 ++ 25.5396 ++unexpand -a < in > out || fail=1 25.5397 ++compare exp out > /dev/null 2>&1 || fail=1 25.5398 ++ 25.5399 ++ 25.5400 ++#multiple files as an input 25.5401 ++cat >> exp <<\EOF 25.5402 ++1234567812345678123456781 25.5403 ++. . . . 25.5404 ++a b c d 25.5405 ++. . . . 25.5406 ++ä ö ü ß 25.5407 ++. . . . 25.5408 ++ äöü . öüä. ä xx 25.5409 ++EOF 25.5410 ++ 25.5411 ++ 25.5412 ++unexpand -a ./in ./in > out || fail=1 25.5413 ++compare exp out > /dev/null 2>&1 || fail=1 25.5414 ++ 25.5415 ++#test characters with a display width larger than 1 25.5416 ++ 25.5417 ++env printf '12345678 25.5418 ++e |ascii(1) 25.5419 ++\u00E9 |composed(1) 25.5420 ++e\u0301 |decomposed(1) 25.5421 ++\u3000 |ideo-space(2) 25.5422 ++\uFF0D |full-hypen(2) 25.5423 ++' > in || framework_failure_ 25.5424 ++ 25.5425 ++env printf '12345678 25.5426 ++e\t|ascii(1) 25.5427 ++\u00E9\t|composed(1) 25.5428 ++e\u0301\t|decomposed(1) 25.5429 ++\u3000\t|ideo-space(2) 25.5430 ++\uFF0D\t|full-hypen(2) 25.5431 ++' > exp || framework_failure_ 25.5432 ++ 25.5433 ++unexpand -a < in > out || fail=1 25.5434 ++compare exp out > /dev/null 2>&1 || fail=1 25.5435 ++ 25.5436 ++#test input where a blank of width > 1 is not being substituted 25.5437 ++in="$(LC_ALL=en_US.UTF-8 printf ' \u3000 ö ü ß')" 25.5438 ++exp=' ö ü ß' 25.5439 ++ 25.5440 ++unexpand -a < in > out || fail=1 25.5441 ++compare exp out > /dev/null 2>&1 || fail=1 25.5442 ++ 25.5443 ++#non-Unicode characters interspersed between Unicode ones 25.5444 ++env printf '12345678 25.5445 ++ \xFF| 25.5446 ++\xFF | 25.5447 ++ \xFFä| 25.5448 ++ä\xFF | 25.5449 ++ ä\xFF| 25.5450 ++\xFF ä| 25.5451 ++äbcdef\xFF | 25.5452 ++' > in || framework_failure_ 25.5453 ++ 25.5454 ++env printf '12345678 25.5455 ++\t\xFF| 25.5456 ++\xFF\t| 25.5457 ++\t\xFFä| 25.5458 ++ä\xFF\t| 25.5459 ++\tä\xFF| 25.5460 ++\xFF\tä| 25.5461 ++äbcdef\xFF\t| 25.5462 ++' > exp || framework_failure_ 25.5463 ++ 25.5464 ++unexpand -a < in > out || fail=1 25.5465 ++compare exp out > /dev/null 2>&1 || fail=1 25.5466 ++ 25.5467 ++#BOM header test 1 25.5468 ++printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ 25.5469 ++1234567812345678123456781 25.5470 ++. . . . 25.5471 ++a b c d 25.5472 ++. . . . 25.5473 ++ä ö ü ß 25.5474 ++. . . . 25.5475 ++ äöü . öüä. ä xx 25.5476 ++EOF 25.5477 ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ 25.5478 ++ 25.5479 ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ 25.5480 ++1234567812345678123456781 25.5481 ++. . . . 25.5482 ++a b c d 25.5483 ++. . . . 25.5484 ++ä ö ü ß 25.5485 ++. . . . 25.5486 ++ äöü . öüä. ä xx 25.5487 ++EOF 25.5488 ++ 25.5489 ++unexpand < in > out || fail=1 25.5490 ++compare exp out > /dev/null 2>&1 || fail=1 25.5491 ++ 25.5492 ++LANG=C unexpand < in > out || fail=1 25.5493 ++compare exp out > /dev/null 2>&1 || fail=1 25.5494 ++ 25.5495 ++LC_ALL=C unexpand < in > out || fail=1 25.5496 ++compare exp out > /dev/null 2>&1 || fail=1 25.5497 ++ 25.5498 ++ 25.5499 ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ 25.5500 ++1234567812345678123456781 25.5501 ++. . . . 25.5502 ++a b c d 25.5503 ++. . . . 25.5504 ++ä ö ü ß 25.5505 ++. . . . 25.5506 ++ äöü . öüä. ä xx 25.5507 ++1234567812345678123456781 25.5508 ++. . . . 25.5509 ++a b c d 25.5510 ++. . . . 25.5511 ++ä ö ü ß 25.5512 ++. . . . 25.5513 ++ äöü . öüä. ä xx 25.5514 ++EOF 25.5515 ++ 25.5516 ++ 25.5517 ++unexpand in in > out || fail=1 25.5518 ++compare exp out > /dev/null 2>&1 || fail=1 25.5519 ++ 25.5520 ++LANG=C unexpand in in > out || fail=1 25.5521 ++compare exp out > /dev/null 2>&1 || fail=1 25.5522 ++ 25.5523 ++LC_ALL=C unexpand in in > out || fail=1 25.5524 ++compare exp out > /dev/null 2>&1 || fail=1
26.1 --- a/coreutils/stuff/patches/coreutils-fix-po.patch Wed Feb 21 18:10:55 2018 +0200 26.2 +++ b/coreutils/stuff/patches/coreutils-fix-po.patch Wed Feb 21 19:48:17 2018 +0200 26.3 @@ -20,8 +20,8 @@ 26.4 " N-M fra N'te til M'te (inklusive) byte, tegn eller felt\n" 26.5 --- a/po/sl.po 26.6 +++ b/po/sl.po 26.7 -@@ -2641,7 +2641,7 @@ 26.8 - #: src/csplit.c:1299 26.9 +@@ -2579,7 +2579,7 @@ 26.10 + #: src/csplit.c:1298 26.11 #, c-format 26.12 msgid "invalid conversion specifier in suffix: \\%.3o" 26.13 -msgstr "neveljavno določilo pretvorbe v priponi: \\\\%.3o"
27.1 --- a/coreutils/stuff/patches/series Wed Feb 21 18:10:55 2018 +0200 27.2 +++ b/coreutils/stuff/patches/series Wed Feb 21 19:48:17 2018 +0200 27.3 @@ -1,3 +1,7 @@ 27.4 -coreutils-8.25-i18n-2.patch 27.5 +# LFS: Coreutils Internationalization Fixes Patch 27.6 +#coreutils-8.29-i18n-1.patch 27.7 + 27.8 +# SliTaz: show extended info touching CPU via uname 27.9 uname.u 27.10 +# SliTaz: fix translations, especially deprecated symbol '\v' 27.11 coreutils-fix-po.patch
28.1 --- a/diffutils/receipt Wed Feb 21 18:10:55 2018 +0200 28.2 +++ b/diffutils/receipt Wed Feb 21 19:48:17 2018 +0200 28.3 @@ -1,24 +1,22 @@ 28.4 # SliTaz package receipt v2. 28.5 28.6 PACKAGE="diffutils" 28.7 -VERSION="3.5" 28.8 +VERSION="3.6" 28.9 CATEGORY="development" 28.10 SHORT_DESC="Show differences between two files" 28.11 MAINTAINER="pascal.bellard@slitaz.org" 28.12 LICENSE="GPL3" 28.13 WEB_SITE="https://www.gnu.org/software/diffutils/" 28.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/diffutils.html" 28.15 28.16 TARBALL="$PACKAGE-$VERSION.tar.xz" 28.17 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 28.18 28.19 -# Rules to configure and make the package. 28.20 -compile_rules() 28.21 -{ 28.22 +compile_rules() { 28.23 ./configure $CONFIGURE_ARGS && make && make install 28.24 } 28.25 28.26 -# Rules to gen a SliTaz package suitable for Tazpkg. 28.27 -genpkg_rules() 28.28 -{ 28.29 +genpkg_rules() { 28.30 copy @std 28.31 + TAGS="LFS" 28.32 }
29.1 --- a/e2fsprogs/receipt Wed Feb 21 18:10:55 2018 +0200 29.2 +++ b/e2fsprogs/receipt Wed Feb 21 19:48:17 2018 +0200 29.3 @@ -1,25 +1,23 @@ 29.4 # SliTaz package receipt v2. 29.5 29.6 PACKAGE="e2fsprogs" 29.7 -VERSION="1.43.4" 29.8 +VERSION="1.43.5" 29.9 CATEGORY="base-system" 29.10 SHORT_DESC="Filesystem utilities for use with ext2 and ext3" 29.11 MAINTAINER="pankso@slitaz.org" 29.12 LICENSE="GPL2" 29.13 WEB_SITE="http://e2fsprogs.sourceforge.net/" 29.14 -HOST_ARCH="i486 arm" 29.15 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/e2fsprogs.html" 29.16 29.17 TARBALL="$PACKAGE-$VERSION.tar.gz" 29.18 WGET_URL="$SF_MIRROR/$PACKAGE/$TARBALL" 29.19 29.20 +BUILD_DEPENDS_arm=" " 29.21 BUILD_DEPENDS="util-linux-uuid-dev util-linux-blkid-dev gettext attr-dev \ 29.22 acl-dev texinfo" 29.23 -BUILD_DEPENDS_arm=" " 29.24 -SPLIT="libcomerr libcomerr-dev e2fsprogs-dev e2fsprogs-fsck" 29.25 +SPLIT="libcomerr-dev e2fsprogs-dev e2fsprogs-fsck libcomerr e2fsprogs" 29.26 29.27 -# Rules to configure and make the package. 29.28 -compile_rules() 29.29 -{ 29.30 +compile_rules() { 29.31 sed -i -e 's:\[\.-\]::' tests/filter.sed 29.32 mkdir ../build && cd ../build 29.33 29.34 @@ -33,7 +31,7 @@ 29.35 --disable-uuidd \ 29.36 --disable-fsck \ 29.37 $CONFIGURE_ARGS && 29.38 - make && make install && make install-libs 29.39 + make && make install && make install-libs || return 1 29.40 29.41 for i in libcom_err libe2p libext2fs libss; do 29.42 chmod u+w $install/usr/lib/$i.a 29.43 @@ -45,7 +43,7 @@ 29.44 $install/usr/share/info/libext2fs.info 29.45 29.46 # Additional documentation 29.47 - makeinfo -o $src/doc/com_err.info $src/lib/et/com_err.texinfo 29.48 + makeinfo -o $src/doc/com_err.info $src/lib/et/com_err.texinfo 29.49 install -m644 $src/doc/com_err.info $install/usr/share/info 29.50 install-info --dir-file=$install/usr/share/info/dir \ 29.51 $install/usr/share/info/com_err.info 29.52 @@ -55,43 +53,36 @@ 29.53 msgfmt $src/po/de.po -o $src/po/de.gmo 29.54 } 29.55 29.56 -# Rules to gen a SliTaz package suitable for Tazpkg. 29.57 -genpkg_rules() 29.58 -{ 29.59 +genpkg_rules() { 29.60 case $PACKAGE in 29.61 - e2fsprogs) 29.62 - copy bin/ sbin/ etc/ *.so* 29.63 - find $fs -name '*com_err*' -delete 29.64 - # Remove fsck provided by Busybox. 29.65 - rm $fs/sbin/fsck* 29.66 - DEPENDS="libcomerr util-linux-blkid util-linux-uuid" 29.67 + libcomerr-dev) 29.68 + copy libcom_err.a com_err.h com_err.pc 29.69 + CAT="development|libcomerr development files" 29.70 + DEPENDS="pkg-config" 29.71 ;; 29.72 e2fsprogs-dev) 29.73 - copy @dev *.awk *.sed 29.74 - find $fs \( -name com_err.h -o -name libcom_err.a -o -name com_err.pc \) -delete 29.75 + copy @dev *.sed *.awk @rm 29.76 DEPENDS="libcomerr-dev pkg-config" 29.77 ;; 29.78 + e2fsprogs-fsck) 29.79 + copy sbin/fsck.* 29.80 + CAT="system-tools|fsck tools" 29.81 + DEPENDS="e2fsprogs libcomerr util-linux-blkid util-linux-uuid" 29.82 + ;; 29.83 libcomerr) 29.84 copy libcom_err.so* 29.85 CAT="base-system|libcomerr library" 29.86 DEPENDS=" " 29.87 ;; 29.88 - libcomerr-dev) 29.89 - copy libcom_err.a com_err.h com_err.pc 29.90 - CAT="development|libcomerr development files" 29.91 - DEPENDS="pkg-config" 29.92 - ;; 29.93 - e2fsprogs-fsck) 29.94 - copy fsck.* 29.95 - rm -r $fs/usr 29.96 - CAT="system-tools|fsck tools" 29.97 - DEPENDS="e2fsprogs libcomerr util-linux-blkid util-linux-uuid" 29.98 + e2fsprogs) 29.99 + copy @std @rm 29.100 + DEPENDS="libcomerr util-linux-blkid util-linux-uuid" 29.101 + TAGS="LFS" 29.102 ;; 29.103 esac 29.104 } 29.105 29.106 # Overlap busybox 29.107 -pre_install_e2fsprogs() 29.108 -{ 29.109 +pre_install_e2fsprogs() { 29.110 rm -f $1/sbin/tune2fs 29.111 }
30.1 --- a/eudev/receipt Wed Feb 21 18:10:55 2018 +0200 30.2 +++ b/eudev/receipt Wed Feb 21 19:48:17 2018 +0200 30.3 @@ -8,7 +8,6 @@ 30.4 LICENSE="GPL2" 30.5 WEB_SITE="http://dev.gentoo.org/~blueness/eudev/" 30.6 LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/eudev.html" 30.7 -PROVIDE="udev" 30.8 30.9 TARBALL="$PACKAGE-$VERSION.tar.gz" 30.10 WGET_URL="${WEB_SITE}$TARBALL" 30.11 @@ -17,9 +16,7 @@ 30.12 BUILD_DEPENDS="gobject-introspection-dev util-linux-blkid-dev gperf kmod-dev" 30.13 SPLIT="eudev-dev" 30.14 30.15 -# Rules to configure and make the package. 30.16 -compile_rules() 30.17 -{ 30.18 +compile_rules() { 30.19 sed -r -i 's|/usr(/bin/test)|\1|' test/udev-test.pl 30.20 sed -i '/keyboard_lookup_key/d' src/udev/udev-builtin-keyboard.c 30.21 cat > config.cache <<"EOF" 30.22 @@ -58,14 +55,13 @@ 30.23 # in /lib/udev/rules.d. 30.24 } 30.25 30.26 -# Rules to gen a SliTaz package suitable for Tazpkg. 30.27 -genpkg_rules() 30.28 -{ 30.29 +genpkg_rules() { 30.30 case $PACKAGE in 30.31 eudev) 30.32 copy @std 30.33 DEPENDS="kmod liblzma util-linux-blkid util-linux-uuid zlib dbus" 30.34 PROVIDE="udev" 30.35 + TAGS="LFS" 30.36 ;; 30.37 eudev-dev) 30.38 copy @dev
31.1 --- a/expat/receipt Wed Feb 21 18:10:55 2018 +0200 31.2 +++ b/expat/receipt Wed Feb 21 19:48:17 2018 +0200 31.3 @@ -1,36 +1,34 @@ 31.4 # SliTaz package receipt v2. 31.5 31.6 PACKAGE="expat" 31.7 -VERSION="2.2.0" 31.8 +VERSION="2.2.3" 31.9 CATEGORY="x-window" 31.10 SHORT_DESC="XML parsing C library" 31.11 MAINTAINER="pankso@slitaz.org" 31.12 LICENSE="MIT" 31.13 WEB_SITE="https://libexpat.github.io/" 31.14 -HOST_ARCH="i486 arm" 31.15 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/expat.html" 31.16 31.17 TARBALL="$PACKAGE-$VERSION.tar.bz2" 31.18 WGET_URL="$SF_MIRROR/$PACKAGE/$TARBALL" 31.19 31.20 SPLIT="expat-dev" 31.21 31.22 -# Rules to configure and make the package. 31.23 -compile_rules() 31.24 -{ 31.25 +compile_rules() { 31.26 ./configure \ 31.27 --disable-static \ 31.28 $CONFIGURE_ARGS && 31.29 - make && make DESTDIR=$install install 31.30 + make && make DESTDIR=$install install || return 1 31.31 31.32 - docdir="$install/usr/share/doc/expat-$VERSION" 31.33 - mkdir -p $docdir; cp doc/* $docdir; rm $docdir/*.1 31.34 + cook_pick_docs doc/*.html doc/*.css doc/*.png 31.35 } 31.36 31.37 -# Rules to gen a SliTaz package suitable for Tazpkg. 31.38 -genpkg_rules() 31.39 -{ 31.40 +genpkg_rules() { 31.41 case $PACKAGE in 31.42 - expat) copy @std ;; 31.43 - expat-dev) copy @dev ;; 31.44 + expat) 31.45 + copy @std 31.46 + TAGS="LFS" 31.47 + ;; 31.48 + *-dev) copy @dev;; 31.49 esac 31.50 }
32.1 --- a/file/receipt Wed Feb 21 18:10:55 2018 +0200 32.2 +++ b/file/receipt Wed Feb 21 19:48:17 2018 +0200 32.3 @@ -7,7 +7,7 @@ 32.4 MAINTAINER="erjo@slitaz.org" 32.5 LICENSE="BSD" 32.6 WEB_SITE="https://github.com/file/file" 32.7 -HOST_ARCH="i486 arm" 32.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/file.html" 32.9 32.10 TARBALL="$PACKAGE-$VERSION.tar.gz" 32.11 WGET_URL="https://github.com/file/file/archive/FILE${VERSION/./_}.tar.gz" 32.12 @@ -16,30 +16,31 @@ 32.13 BUILD_DEPENDS_arm="" 32.14 SPLIT="libmagic libmagic-dev python-magic" 32.15 32.16 -# Rules to configure and make the package. 32.17 -compile_rules() 32.18 -{ 32.19 +compile_rules() { 32.20 autoreconf -f -i && 32.21 - ./configure $CONFIGURE_ARGS && make && make install 32.22 + ./configure \ 32.23 + --libdir=/usr/lib \ 32.24 + $CONFIGURE_ARGS && 32.25 + make && make install || return 1 32.26 + 32.27 + rmdir --ignore-fail-on-non-empty $install/usr/share/man/man5/ 32.28 32.29 cd python 32.30 python setup.py build && 32.31 - python setup.py install --root=$DESTDIR 32.32 + python setup.py install --root=$install 32.33 } 32.34 32.35 # Be sure it as cross compile. 32.36 -testsuite() 32.37 -{ 32.38 +testsuite() { 32.39 readelf -h $install/usr/bin/file 32.40 } 32.41 32.42 -# Rules to gen a SliTaz package suitable for Tazpkg. 32.43 -genpkg_rules() 32.44 -{ 32.45 +genpkg_rules() { 32.46 case $PACKAGE in 32.47 file) 32.48 copy file magic.mgc 32.49 DEPENDS="zlib libmagic" 32.50 + TAGS="LFS" 32.51 ;; 32.52 libmagic) 32.53 copy *.so*
33.1 --- a/findutils/receipt Wed Feb 21 18:10:55 2018 +0200 33.2 +++ b/findutils/receipt Wed Feb 21 19:48:17 2018 +0200 33.3 @@ -7,13 +7,12 @@ 33.4 MAINTAINER="pankso@slitaz.org" 33.5 LICENSE="GPL3" 33.6 WEB_SITE="https://www.gnu.org/software/findutils/" 33.7 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/findutils.html" 33.8 33.9 TARBALL="$PACKAGE-$VERSION.tar.gz" 33.10 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 33.11 33.12 -# Rules to configure and make the package. 33.13 -compile_rules() 33.14 -{ 33.15 +compile_rules() { 33.16 ./configure \ 33.17 --localstatedir=/var/lib/locate \ 33.18 $CONFIGURE_ARGS && 33.19 @@ -21,9 +20,8 @@ 33.20 make install 33.21 } 33.22 33.23 -# Rules to gen a SliTaz package suitable for Tazpkg. 33.24 -genpkg_rules() 33.25 -{ 33.26 +genpkg_rules() { 33.27 copy @std 33.28 DEPENDS="glibc-base slitaz-base-files" 33.29 + TAGS="LFS" 33.30 }
34.1 --- a/flex/receipt Wed Feb 21 18:10:55 2018 +0200 34.2 +++ b/flex/receipt Wed Feb 21 19:48:17 2018 +0200 34.3 @@ -7,33 +7,31 @@ 34.4 MAINTAINER="pankso@slitaz.org" 34.5 LICENSE="BSD" 34.6 WEB_SITE="https://github.com/westes/flex" 34.7 -HOST_ARCH="i486 arm" 34.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/flex.html" 34.9 34.10 TARBALL="$PACKAGE-$VERSION.tar.gz" 34.11 WGET_URL="$WEB_SITE/releases/download/v$VERSION/$TARBALL" 34.12 +TARBALL_MD5="2882e3179748cc9f9c23ec593d6adc8d" 34.13 34.14 BUILD_DEPENDS="bison gettext help2man indent" 34.15 34.16 -# Rules to configure and make the package. 34.17 -compile_rules() 34.18 -{ 34.19 +compile_rules() { 34.20 case "$ARCH" in 34.21 arm*) 34.22 export ac_cv_func_malloc_0_nonnull=yes 34.23 export ac_cv_func_realloc_0_nonnull=yes 34.24 esac 34.25 34.26 - ./configure \ 34.27 - --docdir=/usr/share/doc/flex-$VERSION \ 34.28 - $CONFIGURE_ARGS && 34.29 - make && make install 34.30 + # Fix a problem introduced with glibc-2.26 34.31 + sed -i "/math.h/a #include <malloc.h>" src/flexdef.h 34.32 + 34.33 + ./configure $CONFIGURE_ARGS && make && make install || return 1 34.34 34.35 ln -s flex $install/usr/bin/lex 34.36 } 34.37 34.38 -# Rules to gen a SliTaz package suitable for Tazpkg. 34.39 -genpkg_rules() 34.40 -{ 34.41 +genpkg_rules() { 34.42 copy @std @dev 34.43 DEPENDS="bison" 34.44 + TAGS="LFS" 34.45 }
35.1 --- a/gawk/receipt Wed Feb 21 18:10:55 2018 +0200 35.2 +++ b/gawk/receipt Wed Feb 21 19:48:17 2018 +0200 35.3 @@ -7,7 +7,7 @@ 35.4 MAINTAINER="pankso@slitaz.org" 35.5 LICENSE="GPL3" 35.6 WEB_SITE="http://www.gnu.org/software/gawk/" 35.7 -HOST_ARCH="i486 arm" 35.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/gawk.html" 35.9 35.10 TARBALL="$PACKAGE-$VERSION.tar.gz" 35.11 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 35.12 @@ -16,25 +16,23 @@ 35.13 SPLIT="gawk-dev" 35.14 35.15 # Rules to compile & install the temporary toolchain. 35.16 -cook_tmp_toolchain() 35.17 -{ 35.18 +cook_tmp_toolchain() { 35.19 cd $src 35.20 ./configure && make && make install 35.21 } 35.22 35.23 -# Rules to configure and make the package. 35.24 -compile_rules() 35.25 -{ 35.26 - ./configure $CONFIGURE_ARGS && make && make install 35.27 +compile_rules() { 35.28 + ./configure $CONFIGURE_ARGS && make && make install || return 1 35.29 + 35.30 + cook_pick_docs doc/awkforai.txt doc/*.eps doc/*.pdf doc/*.jpg 35.31 } 35.32 35.33 -# Rules to gen a SliTaz package suitable for Tazpkg. 35.34 -genpkg_rules() 35.35 -{ 35.36 +genpkg_rules() { 35.37 case $PACKAGE in 35.38 gawk) 35.39 copy @std 35.40 DEPENDS="readline" 35.41 + TAGS="LFS" 35.42 ;; 35.43 *-dev) copy @dev;; 35.44 esac
36.1 --- a/gcc/receipt Wed Feb 21 18:10:55 2018 +0200 36.2 +++ b/gcc/receipt Wed Feb 21 19:48:17 2018 +0200 36.3 @@ -1,87 +1,99 @@ 36.4 # SliTaz package receipt v2. 36.5 36.6 +# Note, currently first pass is broken. Sorry. 36.7 PACKAGE="gcc" 36.8 -VERSION="6.3.0" 36.9 +VERSION="7.3.0" 36.10 CATEGORY="development" 36.11 SHORT_DESC="The GNU Compiler Collection" 36.12 MAINTAINER="pankso@slitaz.org" 36.13 LICENSE="GPL2" 36.14 WEB_SITE="http://gcc.gnu.org/" 36.15 -#HOST_ARCH="i486 arm" 36.16 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/gcc.html" 36.17 36.18 -TARBALL="$PACKAGE-$VERSION.tar.bz2" 36.19 -WGET_URL="ftp://gcc.gnu.org/pub/gcc/releases/gcc-$VERSION/$TARBALL" 36.20 +TARBALL="$PACKAGE-$VERSION.tar.xz" 36.21 +WGET_URL="http://ftp.gnu.org/gnu/gcc/gcc-$VERSION/$TARBALL" 36.22 36.23 BUILD_DEPENDS="mpc-library-dev mpfr-dev gmp-dev elfutils-dev zlib-dev" 36.24 SPLIT="gcc-lib-base gcc-lib-math libgfortran gfortran libgomp libobjc \ 36.25 libatomic gcc" 36.26 36.27 +if [ "$2" == "--first-pass" -o "$3" == "--first-pass" ]; then 36.28 + STAGE='first' 36.29 + SPLIT='' 36.30 +fi 36.31 + 36.32 compile_rules() { 36.33 # Handle cross compilation (native i486/ARM gcc) 36.34 case "$ARCH" in 36.35 i?86) 36.36 ARCH_ARGS="--with-tune=$ARCH" 36.37 pkgversion="SliTaz" 36.38 - languages="c,c++,objc,fortran" ;; 36.39 + languages="c,c++,objc,fortran" 36.40 + sed -i 's/^T_CFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in 36.41 + ;; 36.42 + x86_64) 36.43 + ARCH_ARGS="" 36.44 + pkgversion="SliTaz64" 36.45 + languages="c,c++,objc,fortran" 36.46 + sed -i.orig '/m64=/ s|lib64|lib|' gcc/config/i386/t-linux64 36.47 + ;; 36.48 arm*) 36.49 + ARCH_ARGS="" 36.50 pkgversion="SliTaz ARM" 36.51 - languages="c,c++" ;; 36.52 + languages="c,c++" 36.53 + ;; 36.54 esac 36.55 36.56 - # Package slitaz-toolchain use 'cook --options' when rebuilding 36.57 - # the full SliTaz toolchain. 36.58 - [ "$2" == "--first-pass" ] && opt=$2 36.59 - [ "$3" == "--first-pass" ] && opt=$3 36.60 - 36.61 # Use libiberty.a from binutils. 36.62 sed -i 's/install_to_$(INSTALL_DEST) //' libiberty/Makefile.in || return 1 36.63 36.64 - case "$ARCH" in 36.65 - i?86) sed -i 's/^T_CFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in ;; 36.66 - esac 36.67 + case "$STAGE" in 36.68 + first) 36.69 + echo "cook: configure GCC for: toolchain first pass" 36.70 36.71 - #sed -i 's@\./fixinc\.sh@-c true@' gcc/Makefile.in 36.72 - 36.73 - mkdir -p ../gcc-build && cd ../gcc-build 36.74 - 36.75 - # This is the default GCC and we want a native build to cross compile after. 36.76 - # SliTaz target i486 host so we need a native i486 build for GCC. 36.77 - case "$opt" in 36.78 - --first-pass) 36.79 - # Used by slitaz-toolchain when rebuilding the full toolchain. 36.80 - echo "cook: configure GCC for: toolchain first pass" 36.81 - $src/configure \ 36.82 - --libexecdir=/usr/lib \ 36.83 + mkdir build 36.84 + cd build 36.85 + ../configure \ 36.86 + --with-newlib \ 36.87 + --without-headers \ 36.88 --disable-nls \ 36.89 - --enable-shared \ 36.90 + --disable-shared \ 36.91 + --disable-multilib \ 36.92 + --disable-decimal-float \ 36.93 + --disable-threads \ 36.94 + --disable-libatomic \ 36.95 + --disable-libgomp \ 36.96 + --disable-libmpx \ 36.97 + --disable-libquadmath \ 36.98 + --disable-libssp \ 36.99 + --disable-libvtv \ 36.100 + --disable-libstdcxx \ 36.101 --enable-languages=c,c++ \ 36.102 - --disable-libstdcxx-pch \ 36.103 - --enable-__cxa_atexit \ 36.104 - --enable-clocale=gnu \ 36.105 - --enable-threads=posix \ 36.106 - --disable-bootstrap \ 36.107 - ${CONFIGURE_ARGS} 36.108 + $CONFIGURE_ARGS 36.109 ;; 36.110 *) 36.111 - # Used by default to produce a full featured X86 GCC compiler. 36.112 echo "cook: configure GCC for: final/full build" 36.113 - $src/configure \ 36.114 - --libexecdir=/usr/lib \ 36.115 - --enable-nls \ 36.116 - --enable-languages=${languages} \ 36.117 - --enable-shared \ 36.118 + 36.119 + mkdir build 36.120 + cd build 36.121 + SED=sed \ 36.122 + ../configure \ 36.123 + --enable-languages=$languages \ 36.124 + --disable-multilib \ 36.125 + --disable-bootstrap \ 36.126 --with-system-zlib \ 36.127 - --enable-clocale=gnu \ 36.128 - --enable-objc-gc \ 36.129 - --enable-__cxa_atexit \ 36.130 - --enable-lto \ 36.131 - --enable-threads=posix \ 36.132 - --disable-bootstrap \ 36.133 --with-pkgversion="$pkgversion" \ 36.134 - ${CONFIGURE_ARGS} ${ARCH_ARGS} 36.135 + $CONFIGURE_ARGS $ARCH_ARGS 36.136 ;; 36.137 esac && 36.138 - make && make install 36.139 + make && make install || return 1 36.140 + 36.141 + ln -sv ../usr/bin/cpp $install/lib 36.142 + ln -sv gcc $install/usr/bin/cc 36.143 + install -v -dm755 $install/usr/lib/bfd-plugins 36.144 + ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/$VERSION/liblto_plugin.so \ 36.145 + $install/usr/lib/bfd-plugins/ 36.146 + 36.147 36.148 # ARM packages use another libs... 36.149 case "$ARCH" in 36.150 @@ -93,16 +105,38 @@ 36.151 ;; 36.152 esac 36.153 36.154 - # Remove build directory. 36.155 - rm -rf $WOK/$PACKAGE/source/$PACKAGE-build 36.156 - rm -rf $WOK/$PACKAGE/$PACKAGE-build 36.157 + 36.158 + # Place the debugging symbols for selected libraries in separate files. 36.159 + # This debugging information is needed if running regression tests that use valgrind or gdb. 36.160 + # http://www.linuxfromscratch.org/lfs/view/stable/chapter06/strippingagain.html 36.161 + 36.162 + [ "$STAGE" == 'first' ] || 36.163 + for i in libquadmath.so.0.0.0 libstdc++.so.6.0.24 libmpx.so.2.0.1 \ 36.164 + libmpxwrappers.so.2.0.1 libitm.so.1.0.0 libcilkrts.so.5.0.0 \ 36.165 + libatomic.so.1.2.0; do 36.166 + cd $install/usr/lib/ 36.167 + objcopy --only-keep-debug $i $i.dbg 36.168 + strip --strip-unneeded $i 36.169 + objcopy --add-gnu-debuglink=$i.dbg $i 36.170 + done 36.171 } 36.172 36.173 genpkg_rules() { 36.174 + case $STAGE in 36.175 + first) 36.176 + # single package 'gcc' on the first stage 36.177 + copy @std @dev 36.178 + DEPENDS="glibc-base gmp mpc-library mpfr zlib binutils elfutils" 36.179 + CAT="development|first pass" 36.180 + TAGS="LFS compiler C" 36.181 + return 0 36.182 + ;; 36.183 + esac 36.184 + 36.185 case $PACKAGE in 36.186 gcc-lib-base) 36.187 copy libgcc_s.so* libstdc++.so* 36.188 - rm $fs/usr/lib/*.py 36.189 + rm $fs/usr/lib*/*.py 36.190 CAT="libs|base libraries" 36.191 DEPENDS="glibc-base" 36.192 ;; 36.193 @@ -138,11 +172,11 @@ 36.194 DEPENDS=" " 36.195 ;; 36.196 gcc) 36.197 - copy bin/ lib/ include/ *.py @rm 36.198 + copy @std @dev @rm 36.199 DEPENDS="gcc-lib-base libgomp libobjc libatomic \ 36.200 glibc-base gmp mpc-library mpfr zlib binutils elfutils" 36.201 SUGGESTED="python" 36.202 - TAGS="compiler C" 36.203 + TAGS="LFS compiler C" 36.204 ;; 36.205 esac 36.206 }
37.1 --- a/gdbm/receipt Wed Feb 21 18:10:55 2018 +0200 37.2 +++ b/gdbm/receipt Wed Feb 21 19:48:17 2018 +0200 37.3 @@ -1,23 +1,21 @@ 37.4 # SliTaz package receipt v2. 37.5 37.6 PACKAGE="gdbm" 37.7 -VERSION="1.12" 37.8 +VERSION="1.13" 37.9 CATEGORY="misc" 37.10 SHORT_DESC="GNU database manager" 37.11 MAINTAINER="pascal.bellard@slitaz.org" 37.12 LICENSE="GPL3" 37.13 WEB_SITE="https://www.gnu.org/software/gdbm" 37.14 -HOST_ARCH="i486 arm" 37.15 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/gdbm.html" 37.16 37.17 TARBALL="$PACKAGE-$VERSION.tar.gz" 37.18 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 37.19 37.20 -BUILD_DEPENDS="gettext" 37.21 +BUILD_DEPENDS="gettext readline-dev" 37.22 SPLIT="gdbm-tools gdbm-dev" 37.23 37.24 -# Rules to configure and make the package. 37.25 -compile_rules() 37.26 -{ 37.27 +compile_rules() { 37.28 ./configure \ 37.29 --disable-static \ 37.30 --enable-libgdbm-compat \ 37.31 @@ -25,15 +23,15 @@ 37.32 make && make install 37.33 } 37.34 37.35 -# Rules to gen a SliTaz package suitable for Tazpkg. 37.36 -genpkg_rules() 37.37 -{ 37.38 +genpkg_rules() { 37.39 case $PACKAGE in 37.40 gdbm) 37.41 copy *.so* 37.42 + TAGS="LFS" 37.43 ;; 37.44 gdbm-tools) 37.45 copy bin/ 37.46 + DEPENDS="gdbm ncurses readline" 37.47 CAT="misc|tools" 37.48 ;; 37.49 *-dev) copy @dev;;
38.1 --- a/gettext/receipt Wed Feb 21 18:10:55 2018 +0200 38.2 +++ b/gettext/receipt Wed Feb 21 19:48:17 2018 +0200 38.3 @@ -7,25 +7,24 @@ 38.4 MAINTAINER="pankso@slitaz.org" 38.5 LICENSE="GPL3" 38.6 WEB_SITE="https://www.gnu.org/software/gettext/" 38.7 -HOST_ARCH="i486 arm" 38.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/gettext.html" 38.9 38.10 TARBALL="$PACKAGE-$VERSION.tar.xz" 38.11 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 38.12 38.13 +BUILD_DEPENDS_arm="attr-dev ncurses-dev libxml2-tools libxml2-dev" 38.14 BUILD_DEPENDS="libcroco-dev libxml2-dev glib-dev acl-dev" 38.15 -BUILD_DEPENDS_arm="attr-dev ncurses-dev libxml2-tools libxml2-dev" 38.16 SPLIT="gettext-base gettext-tools gettext" 38.17 38.18 -# Handle cross compilation. Glibc-locale are installed in cross chroot. 38.19 -case "$ARCH" in 38.20 - arm) ARCH_ARGS="--disable-acl" ;; 38.21 -esac 38.22 +compile_rules() { 38.23 + case "$ARCH" in 38.24 + arm) ARCH_ARGS="--disable-acl";; 38.25 + esac 38.26 38.27 -# Rules to configure and make the package. 38.28 -compile_rules() 38.29 -{ 38.30 - ./configure $CONFIGURE_ARGS $ARCH_ARGS && 38.31 - make && make install 38.32 + fix ld 38.33 + ./configure $CONFIGURE_ARGS $ARCH_ARGS && make && make install || return 1 38.34 + 38.35 + chmod 0755 $install/usr/lib/preloadable_libintl.so 38.36 38.37 # stripped gettext.sh 38.38 rm $install/usr/bin/gettext.sh 38.39 @@ -33,14 +32,11 @@ 38.40 } 38.41 38.42 # Just to be sure when cross compiling, gettext is part of base system. 38.43 -testsuite() 38.44 -{ 38.45 +testsuite() { 38.46 readelf -h $install/usr/bin/gettext 38.47 } 38.48 38.49 -# Rules to gen a SliTaz package suitable for Tazpkg. 38.50 -genpkg_rules() 38.51 -{ 38.52 +genpkg_rules() { 38.53 case $PACKAGE in 38.54 gettext-base) 38.55 copy gettext gettext.sh envsubst ngettext 38.56 @@ -51,13 +47,16 @@ 38.57 copy msgcat msgfmt msgmerge xgettext \ 38.58 libgettextlib*.so* libgettextsrc*.so* 38.59 CAT="libs|tools" 38.60 - DEPENDS="acl attr glib libcroco libgomp liblzma libxml2 pcre zlib" 38.61 + DEPENDS="acl attr glib libcroco libgomp liblzma libxml2 ncurses \ 38.62 + pcre zlib" 38.63 ;; 38.64 gettext) 38.65 copy @std @dev @rm 38.66 + rm -rf $fs/usr/share/doc/ # @dev files here 38.67 # Runtime depends, then dev-depends 38.68 DEPENDS="gettext-base gettext-tools libcroco liblzma libxml2 \ 38.69 acl-dev attr-dev libcroco-dev libxml2-dev glib-dev pcre-dev m4" 38.70 + TAGS="LFS" 38.71 ;; 38.72 esac 38.73 }
39.1 --- a/glibc/receipt Wed Feb 21 18:10:55 2018 +0200 39.2 +++ b/glibc/receipt Wed Feb 21 19:48:17 2018 +0200 39.3 @@ -1,18 +1,18 @@ 39.4 # SliTaz package receipt v2. 39.5 39.6 PACKAGE="glibc" 39.7 -VERSION="2.25" 39.8 +VERSION="2.26" 39.9 CATEGORY="meta" 39.10 SHORT_DESC="The GNU C libraries" 39.11 MAINTAINER="pankso@slitaz.org" 39.12 LICENSE="GPL2" 39.13 WEB_SITE="http://www.gnu.org/software/libc/" 39.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/glibc.html" 39.15 39.16 TARBALL="$PACKAGE-$VERSION.tar.gz" 39.17 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 39.18 39.19 -BUILD_DEPENDS="linux-api-headers autoconf bash gawk gettext bison \ 39.20 -texinfo" 39.21 +BUILD_DEPENDS="linux-api-headers autoconf bash gawk gettext bison texinfo" 39.22 # slitaz-i18n should present in wok 39.23 SPLIT="glibc-base glibc-locale nscd glibc-dev" 39.24 39.25 @@ -21,129 +21,142 @@ 39.26 39.27 # Handle multiarch compilation. 39.28 case "$ARCH" in 39.29 - arm*|x86_64) VERSION="2.13";; 39.30 + arm*) VERSION="2.13";; 39.31 esac 39.32 39.33 # Handle multiarch installation. 39.34 case "$SLITAZ_ARCH" in 39.35 - arm*|x86_64) VERSION="2.13";; 39.36 + arm*) VERSION="2.13";; 39.37 esac 39.38 39.39 39.40 # Rules to compile & install the temporary toolchain. 39.41 -cook_tmp_toolchain() 39.42 -{ 39.43 +cook_tmp_toolchain() { 39.44 unset CFLAGS CXXFLAGS 39.45 - echo "CFLAGS += -O2 -march=${ARCH/i386/i486} -mtune=${ARCH/i386/i486}" > configparms 39.46 + case $ARCH in 39.47 + i386) Arch='i486';; 39.48 + x86_64) Arch='nocona';; 39.49 + *) Arch="$ARCH";; 39.50 + esac 39.51 + echo "CFLAGS += -O2 -march=$Arch -mtune=$Arch" > configparms 39.52 39.53 - { 39.54 - # Build in a separate directory. 39.55 - mkdir glibc-build 39.56 - cd glibc-build 39.57 + # Build in a separate directory. 39.58 + mkdir build 39.59 + cd build 39.60 39.61 - ../configure \ 39.62 - --host=$HOST_SYSTEM \ 39.63 - --build=$($src/scripts/config.guess) \ 39.64 - --disable-profile \ 39.65 - --enable-add-ons \ 39.66 - --enable-kernel=2.6.32 \ 39.67 - --with-headers=/tools/include \ 39.68 - libc_cv_forced_unwind=yes \ 39.69 - libc_cv_c_cleanup=yes && 39.70 - make -j1 && 39.71 - make install 39.72 - } || return 1 39.73 + ../configure \ 39.74 + --host=$HOST_SYSTEM \ 39.75 + --build=$($src/scripts/config.guess) \ 39.76 + --disable-profile \ 39.77 + --enable-add-ons \ 39.78 + --enable-kernel=3.2 \ 39.79 + --with-headers=/tools/include \ 39.80 + libc_cv_forced_unwind=yes \ 39.81 + libc_cv_c_cleanup=yes && 39.82 + make -j1 && 39.83 + make install || return 1 39.84 39.85 # Link compiler to this new glibc. 39.86 SPECS=$(dirname $($HOST_SYSTEM-gcc -print-libgcc-file-name))/specs 39.87 - $HOST_SYSTEM-gcc -dumpspecs | sed \ 39.88 + $HOST_SYSTEM-gcc -dumpspecs \ 39.89 + | sed \ 39.90 -e 's@/lib\(64\)\?/ld@/tools&@g' \ 39.91 -e "/^\*cpp:$/{n;s,$, -isystem /tools/include,}" > $SPECS 39.92 unset SPECS 39.93 } 39.94 39.95 # Rules to configure and make the package. 39.96 -compile_rules() 39.97 -{ 39.98 +compile_rules() { 39.99 # Glibc needs ld.so.conf in the install destdir. 39.100 mkdir -p $install/etc 39.101 touch $install/etc/ld.so.conf 39.102 39.103 # Read the INSTALL file in glibc. Also Glibc don't build with -Os flag. 39.104 - # --enale-kernel use latest SliTaz Kernel version. From Glibc INSTALL: 39.105 - # "The higher the VERSION number is, the less compatibility code is 39.106 - # added, and the faster the code gets." 39.107 unset CFLAGS CXXFLAGS 39.108 - echo "CFLAGS += -O2 -march=${ARCH/i386/i486} -mtune=${ARCH/i386/i486}" > configparms 39.109 + case $ARCH in 39.110 + i386) Arch='i486';; 39.111 + x86_64) Arch='nocona';; 39.112 + *) Arch="$ARCH";; 39.113 + esac 39.114 + echo "CFLAGS += -O2 -march=$Arch -mtune=$Arch" > configparms 39.115 39.116 - { 39.117 - mkdir build 39.118 - cd build 39.119 - $src/configure \ 39.120 - --disable-profile \ 39.121 - --enable-add-ons \ 39.122 - --enable-obsolete-rpc \ 39.123 - --enable-kernel=2.6.32 \ 39.124 - --libexecdir=/usr/lib/glibc \ 39.125 - --build=$HOST_SYSTEM \ 39.126 - --host=$HOST_SYSTEM \ 39.127 - --target=$BUILD_SYSTEM && 39.128 - make -j1 && make install_root=$DESTDIR install 39.129 - } || return 1 39.130 + # Remove a file that may be left over from a previous build attempt 39.131 + rm -f /usr/include/limits.h 2>/dev/null 39.132 + 39.133 + mkdir build 39.134 + cd build 39.135 + # --enale-kernel: please respect Kernel version of the build host, 39.136 + # put the exact or lower numbers. From Glibc INSTALL: 39.137 + # > The higher the VERSION number is, the less compatibility code is 39.138 + # > added, and the faster the code gets. 39.139 + CC="gcc -isystem /usr/lib/gcc/$BUILD_SYSTEM/$(. $WOK/gcc/receipt; echo $VERSION)/include \ 39.140 + -isystem /usr/include" \ 39.141 + ../configure \ 39.142 + --disable-werror \ 39.143 + --enable-kernel=3.2 \ 39.144 + --enable-stack-protector=strong \ 39.145 + libc_cv_slibdir=/lib \ 39.146 + && 39.147 + make -j1 && 39.148 + touch $install/etc/ld.so.conf && 39.149 + sed '/test-installation/s@$(PERL)@echo not running@' -i ../Makefile && 39.150 + make install_root=$install install || return 1 39.151 39.152 # nscd 39.153 - mkdir -p $install/etc/init.d $install/var/db 39.154 - cp $stuff/nscd $install/etc/init.d 39.155 - chmod +x $install/etc/init.d/nscd 39.156 + cp ../nscd/nscd.conf $install/etc/nscd.conf 39.157 + mkdir -p $install/var/cache/nscd $install/var/db 39.158 + install -Dm755 $stuff/nscd $install/etc/init.d/nscd 39.159 39.160 # nsswitch.conf 39.161 cp $stuff/nsswitch.conf $install/etc 39.162 39.163 + # ld.so.conf 39.164 + install -Dm644 $stuff/ld.so.conf $install/etc/ld.so.conf 39.165 + 39.166 # If temporary toolchain was previously used, switch to regular toolchain. 39.167 if [ -d /tools ]; then 39.168 mv /tools/bin/ld /tools/bin/ld-old 39.169 mv /tools/$(gcc -dumpmachine)/bin/ld /tools/$(gcc -dumpmachine)/bin/ld-old 39.170 mv /tools/bin/ld-new /tools/bin/ld 39.171 ln -s /tools/bin/ld /tools/$(gcc -dumpmachine)/bin/ld 39.172 - gcc -dumpspecs | sed -e 's@/tools@@g' \ 39.173 + gcc -dumpspecs \ 39.174 + | sed -e 's@/tools@@g' \ 39.175 -e '/\*startfile_prefix_spec:/{n;s@.*@/usr/lib/ @}' \ 39.176 -e '/\*cpp:/{n;s@$@ -isystem /usr/include@}' > \ 39.177 $(dirname $(gcc --print-libgcc-file-name))/specs 39.178 fi 39.179 -} 39.180 39.181 -# i18n 39.182 -get_locales() 39.183 -{ 39.184 - local path=$1 39.185 - for i in $DEFAULT_LOCALE; do 39.186 - cp $install/$path/i18n/locales/$i $fs/usr/share/i18n/locales 39.187 + # Create symlinks to the dynamic loader for LSB compliance. 39.188 + case $ARCH in 39.189 + i?86) 39.190 + ln -sf ld-linux.so.2 $install/lib/ld-lsb.so.3 39.191 + ;; 39.192 + x86_64) 39.193 + mkdir -p $install/lib64 39.194 + ln -sf ../lib/ld-$VERSION.so $install/lib64/ld-linux-x86-64.so.2 39.195 + ln -sf ../lib/ld-$VERSION.so $install/lib64/ld-lsb-x86-64.so.3 39.196 + ;; 39.197 + esac 39.198 + 39.199 + # Place the debugging symbols for selected libraries in separate files. 39.200 + # This debugging information is needed if running regression tests that use valgrind or gdb. 39.201 + # http://www.linuxfromscratch.org/lfs/view/stable/chapter06/strippingagain.html 39.202 + 39.203 + for i in ld-$VERSION.so libc-$VERSION.so libpthread-$VERSION.so libthread_db-1.0.so; do 39.204 + cd $install/lib/ 39.205 + objcopy --only-keep-debug $i $i.dbg 39.206 + strip --strip-unneeded $i 39.207 + objcopy --add-gnu-debuglink=$i.dbg $i 39.208 done 39.209 } 39.210 39.211 -mk_dirs() 39.212 -{ 39.213 - mkdir -p \ 39.214 - $fs/etc \ 39.215 - $fs/lib \ 39.216 - $fs/usr/bin \ 39.217 - $fs/usr/lib/gconv \ 39.218 - $fs/usr/lib/locale \ 39.219 - $fs/usr/share/zoneinfo/America \ 39.220 - $fs/usr/share/zoneinfo/Europe \ 39.221 - $fs/usr/share/i18n/locales \ 39.222 - $fs/usr/share/i18n/charmaps \ 39.223 - $fs/usr/share/locale 39.224 -} 39.225 - 39.226 -# Rules to gen a SliTaz package suitable for Tazpkg. 39.227 -genpkg_rules() 39.228 -{ 39.229 +genpkg_rules() { 39.230 case $PACKAGE in 39.231 glibc) 39.232 LOCALE="" 39.233 CAT="meta|meta-package" 39.234 DEPENDS="glibc-base glibc-locale glibc-dev" 39.235 + TAGS="LFS" 39.236 ;; 39.237 glibc-base) 39.238 case "$ARCH" in 39.239 @@ -154,13 +167,6 @@ 39.240 install="/cross/$ARCH/sysroot" 39.241 copy libc_nonshared.a libpthread_nonshared.a 39.242 ;; 39.243 - x86_64) 39.244 - # EXPERIMENTAL: Glibc is cross compiled by cross to have a 39.245 - # toolchain so we can use these files instead of recooking it. 39.246 - echo "Using cross compiled Glibc..." 39.247 - install="/usr/cross/$ARCH" 39.248 - copy libc_nonshared.a libpthread_nonshared.a 39.249 - ;; 39.250 esac 39.251 copy \ 39.252 ld-*.so* ld.so* \ 39.253 @@ -192,20 +198,13 @@ 39.254 nsswitch.conf \ 39.255 $DEFAULT_LOCALE 39.256 39.257 - case "$ARCH" in 39.258 - x86_64) 39.259 - # Fix libraries search path 39.260 - sed -i "s|/usr/cross/$ARCH||g" $fs/lib/libc.so 39.261 - sed -i "s|/usr/cross/$ARCH||g" $fs/lib/libpthread.so 39.262 - ;; 39.263 - esac 39.264 + find $fs -type f -name '*.so.dbg' -delete 39.265 + 39.266 CAT="base-system|minimal libraries and UTF-8 support for SliTaz" 39.267 DEPENDS=" " 39.268 ;; 39.269 glibc-locale) 39.270 - copy gconv/ locale/ i18n/ iconv tzselect 39.271 - # Remove glibc-base files 39.272 - remove_already_packed 39.273 + copy gconv/ locale/ i18n/ iconv tzselect @rm # Remove glibc-base files 39.274 39.275 # Remove files provided by locale-pack. 39.276 . $WOK/slitaz-i18n/stuff/locale-pack.conf 39.277 @@ -219,13 +218,12 @@ 39.278 DEPENDS="glibc-base" 39.279 ;; 39.280 nscd) 39.281 - copy /var/db/ nscd getent nscd.conf 39.282 + copy /var/db/ /var/cache/nscd/ nscd getent nscd.conf 39.283 CAT="base-system|name-server caching daemon" 39.284 DEPENDS=" " 39.285 ;; 39.286 glibc-dev) 39.287 - copy @std @dev 39.288 - remove_already_packed 39.289 + copy @std @dev @rm 39.290 DEPENDS="glibc-base" 39.291 ;; 39.292 esac
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/glibc/stuff/ld.so.conf Wed Feb 21 19:48:17 2018 +0200 40.3 @@ -0,0 +1,4 @@ 40.4 +# Begin /etc/ld.so.conf 40.5 +/usr/local/lib 40.6 +/opt/lib 40.7 +
41.1 --- a/glibc/stuff/patches/glibc-2.25-fhs-1.patch Wed Feb 21 18:10:55 2018 +0200 41.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 41.3 @@ -1,72 +0,0 @@ 41.4 -Submitted By: Armin K. <krejzi at email dot com> 41.5 -Date: 2013-02-11 41.6 -Initial Package Version: 2.17 41.7 -Upstream Status: Not Applicable 41.8 -Origin: Self 41.9 -Description: This patch removes references to /var/db directory which is not part 41.10 - of FHS and replaces them with more suitable directories in /var 41.11 - hierarchy - /var/cache/nscd for nscd and /var/lib/nss_db for nss_db. 41.12 - 41.13 ---- a/Makeconfig 2012-12-25 04:02:13.000000000 +0100 41.14 -+++ b/Makeconfig 2013-02-11 01:32:32.500667439 +0100 41.15 -@@ -250,7 +250,7 @@ 41.16 - 41.17 - # Directory for the database files and Makefile for nss_db. 41.18 - ifndef vardbdir 41.19 --vardbdir = $(localstatedir)/db 41.20 -+vardbdir = $(localstatedir)/lib/nss_db 41.21 - endif 41.22 - inst_vardbdir = $(install_root)$(vardbdir) 41.23 - 41.24 ---- a/nscd/nscd.h 2012-12-25 04:02:13.000000000 +0100 41.25 -+++ b/nscd/nscd.h 2013-02-11 01:32:32.500667439 +0100 41.26 -@@ -112,11 +112,11 @@ 41.27 - 41.28 - 41.29 - /* Paths of the file for the persistent storage. */ 41.30 --#define _PATH_NSCD_PASSWD_DB "/var/db/nscd/passwd" 41.31 --#define _PATH_NSCD_GROUP_DB "/var/db/nscd/group" 41.32 --#define _PATH_NSCD_HOSTS_DB "/var/db/nscd/hosts" 41.33 --#define _PATH_NSCD_SERVICES_DB "/var/db/nscd/services" 41.34 --#define _PATH_NSCD_NETGROUP_DB "/var/db/nscd/netgroup" 41.35 -+#define _PATH_NSCD_PASSWD_DB "/var/cache/nscd/passwd" 41.36 -+#define _PATH_NSCD_GROUP_DB "/var/cache/nscd/group" 41.37 -+#define _PATH_NSCD_HOSTS_DB "/var/cache/nscd/hosts" 41.38 -+#define _PATH_NSCD_SERVICES_DB "/var/cache/nscd/services" 41.39 -+#define _PATH_NSCD_NETGROUP_DB "/var/cache/nscd/netgroup" 41.40 - 41.41 - /* Path used when not using persistent storage. */ 41.42 - #define _PATH_NSCD_XYZ_DB_TMP "/var/run/nscd/dbXXXXXX" 41.43 ---- a/nss/db-Makefile 2012-12-25 04:02:13.000000000 +0100 41.44 -+++ b/nss/db-Makefile 2013-02-11 01:32:32.500667439 +0100 41.45 -@@ -22,7 +22,7 @@ 41.46 - /etc/rpc /etc/services /etc/shadow /etc/gshadow \ 41.47 - /etc/netgroup) 41.48 - 41.49 --VAR_DB = /var/db 41.50 -+VAR_DB = /var/lib/nss_db 41.51 - 41.52 - AWK = awk 41.53 - MAKEDB = makedb --quiet 41.54 ---- a/sysdeps/generic/paths.h 2012-12-25 04:02:13.000000000 +0100 41.55 -+++ b/sysdeps/generic/paths.h 2013-02-11 01:32:32.500667439 +0100 41.56 -@@ -68,7 +68,7 @@ 41.57 - /* Provide trailing slash, since mostly used for building pathnames. */ 41.58 - #define _PATH_DEV "/dev/" 41.59 - #define _PATH_TMP "/tmp/" 41.60 --#define _PATH_VARDB "/var/db/" 41.61 -+#define _PATH_VARDB "/var/lib/nss_db/" 41.62 - #define _PATH_VARRUN "/var/run/" 41.63 - #define _PATH_VARTMP "/var/tmp/" 41.64 - 41.65 ---- a/sysdeps/unix/sysv/linux/paths.h 2012-12-25 04:02:13.000000000 +0100 41.66 -+++ b/sysdeps/unix/sysv/linux/paths.h 2013-02-11 01:32:32.504000831 +0100 41.67 -@@ -68,7 +68,7 @@ 41.68 - /* Provide trailing slash, since mostly used for building pathnames. */ 41.69 - #define _PATH_DEV "/dev/" 41.70 - #define _PATH_TMP "/tmp/" 41.71 --#define _PATH_VARDB "/var/db/" 41.72 -+#define _PATH_VARDB "/var/lib/nss_db/" 41.73 - #define _PATH_VARRUN "/var/run/" 41.74 - #define _PATH_VARTMP "/var/tmp/" 41.75 -
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/glibc/stuff/patches/glibc-2.26-fhs-1.patch Wed Feb 21 19:48:17 2018 +0200 42.3 @@ -0,0 +1,72 @@ 42.4 +Submitted By: Armin K. <krejzi at email dot com> 42.5 +Date: 2013-02-11 42.6 +Initial Package Version: 2.17 42.7 +Upstream Status: Not Applicable 42.8 +Origin: Self 42.9 +Description: This patch removes references to /var/db directory which is not part 42.10 + of FHS and replaces them with more suitable directories in /var 42.11 + hierarchy - /var/cache/nscd for nscd and /var/lib/nss_db for nss_db. 42.12 + 42.13 +--- a/Makeconfig 2012-12-25 04:02:13.000000000 +0100 42.14 ++++ b/Makeconfig 2013-02-11 01:32:32.500667439 +0100 42.15 +@@ -250,7 +250,7 @@ 42.16 + 42.17 + # Directory for the database files and Makefile for nss_db. 42.18 + ifndef vardbdir 42.19 +-vardbdir = $(localstatedir)/db 42.20 ++vardbdir = $(localstatedir)/lib/nss_db 42.21 + endif 42.22 + inst_vardbdir = $(install_root)$(vardbdir) 42.23 + 42.24 +--- a/nscd/nscd.h 2012-12-25 04:02:13.000000000 +0100 42.25 ++++ b/nscd/nscd.h 2013-02-11 01:32:32.500667439 +0100 42.26 +@@ -112,11 +112,11 @@ 42.27 + 42.28 + 42.29 + /* Paths of the file for the persistent storage. */ 42.30 +-#define _PATH_NSCD_PASSWD_DB "/var/db/nscd/passwd" 42.31 +-#define _PATH_NSCD_GROUP_DB "/var/db/nscd/group" 42.32 +-#define _PATH_NSCD_HOSTS_DB "/var/db/nscd/hosts" 42.33 +-#define _PATH_NSCD_SERVICES_DB "/var/db/nscd/services" 42.34 +-#define _PATH_NSCD_NETGROUP_DB "/var/db/nscd/netgroup" 42.35 ++#define _PATH_NSCD_PASSWD_DB "/var/cache/nscd/passwd" 42.36 ++#define _PATH_NSCD_GROUP_DB "/var/cache/nscd/group" 42.37 ++#define _PATH_NSCD_HOSTS_DB "/var/cache/nscd/hosts" 42.38 ++#define _PATH_NSCD_SERVICES_DB "/var/cache/nscd/services" 42.39 ++#define _PATH_NSCD_NETGROUP_DB "/var/cache/nscd/netgroup" 42.40 + 42.41 + /* Path used when not using persistent storage. */ 42.42 + #define _PATH_NSCD_XYZ_DB_TMP "/var/run/nscd/dbXXXXXX" 42.43 +--- a/nss/db-Makefile 2012-12-25 04:02:13.000000000 +0100 42.44 ++++ b/nss/db-Makefile 2013-02-11 01:32:32.500667439 +0100 42.45 +@@ -22,7 +22,7 @@ 42.46 + /etc/rpc /etc/services /etc/shadow /etc/gshadow \ 42.47 + /etc/netgroup) 42.48 + 42.49 +-VAR_DB = /var/db 42.50 ++VAR_DB = /var/lib/nss_db 42.51 + 42.52 + AWK = awk 42.53 + MAKEDB = makedb --quiet 42.54 +--- a/sysdeps/generic/paths.h 2012-12-25 04:02:13.000000000 +0100 42.55 ++++ b/sysdeps/generic/paths.h 2013-02-11 01:32:32.500667439 +0100 42.56 +@@ -68,7 +68,7 @@ 42.57 + /* Provide trailing slash, since mostly used for building pathnames. */ 42.58 + #define _PATH_DEV "/dev/" 42.59 + #define _PATH_TMP "/tmp/" 42.60 +-#define _PATH_VARDB "/var/db/" 42.61 ++#define _PATH_VARDB "/var/lib/nss_db/" 42.62 + #define _PATH_VARRUN "/var/run/" 42.63 + #define _PATH_VARTMP "/var/tmp/" 42.64 + 42.65 +--- a/sysdeps/unix/sysv/linux/paths.h 2012-12-25 04:02:13.000000000 +0100 42.66 ++++ b/sysdeps/unix/sysv/linux/paths.h 2013-02-11 01:32:32.504000831 +0100 42.67 +@@ -68,7 +68,7 @@ 42.68 + /* Provide trailing slash, since mostly used for building pathnames. */ 42.69 + #define _PATH_DEV "/dev/" 42.70 + #define _PATH_TMP "/tmp/" 42.71 +-#define _PATH_VARDB "/var/db/" 42.72 ++#define _PATH_VARDB "/var/lib/nss_db/" 42.73 + #define _PATH_VARRUN "/var/run/" 42.74 + #define _PATH_VARTMP "/var/tmp/" 42.75 +
43.1 --- a/glibc/stuff/patches/glibc-po.patch Wed Feb 21 18:10:55 2018 +0200 43.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 43.3 @@ -1,249 +0,0 @@ 43.4 -warning: internationalized messages should not contain the '\v' escape sequence 43.5 - 43.6 ---- a/po/cs.po 43.7 -+++ b/po/cs.po 43.8 -@@ -153,7 +153,8 @@ 43.9 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.10 - "is -, output is written to standard output.\n" 43.11 - msgstr "" 43.12 --"Generuje katalog zpráv.\vJe-li VSTUPNÍ_SOUBOR -, vstup bude načten ze standardního vstupu.\n" 43.13 -+"Generuje katalog zpráv.\n" 43.14 -+"Je-li VSTUPNÍ_SOUBOR -, vstup bude načten ze standardního vstupu.\n" 43.15 - "Je-li VÝSTUPNÍ_SOUBOR -, výstup bude zapsán na standardní výstup.\n" 43.16 - 43.17 - #: catgets/gencat.c:123 43.18 ---- a/po/da.po 43.19 -+++ b/po/da.po 43.20 -@@ -131,7 +131,8 @@ 43.21 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.22 - "is -, output is written to standard output.\n" 43.23 - msgstr "" 43.24 --"Generér meddelelseskatalog.\vHvis INDFIL er '-' læses inddata fra standard ind.\n" 43.25 -+"Generér meddelelseskatalog.\n" 43.26 -+"Hvis INDFIL er '-' læses inddata fra standard ind.\n" 43.27 - "Hvis UDFIL er '-' skrives uddata til standard ud.\n" 43.28 - 43.29 - #: catgets/gencat.c:123 43.30 ---- a/po/de.po 43.31 -+++ b/po/de.po 43.32 -@@ -131,7 +131,8 @@ 43.33 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.34 - "is -, output is written to standard output.\n" 43.35 - msgstr "" 43.36 --"Einen Message-Katalog generieren.\vWenn als INPUT-FILE - angegeben wird, wird\n" 43.37 -+"Einen Message-Katalog generieren.\n" 43.38 -+"Wenn als INPUT-FILE - angegeben wird, wird\n" 43.39 - "von der Standardeingabe gelesen. Wenn die OUTPUT-FILE - ist, wird auf die\n" 43.40 - "Standardausgabe geschrieben.\n" 43.41 - 43.42 ---- a/po/en_GB.po 43.43 -+++ b/po/en_GB.po 43.44 -@@ -1878,11 +1878,12 @@ 43.45 - 43.46 - #: catgets/gencat.c:116 43.47 - msgid "" 43.48 --"Generate message catalog.\\vIf INPUT-FILE is -, input is read from standard " 43.49 -+"Generate message catalog.\vIf INPUT-FILE is -, input is read from standard " 43.50 - "input. If OUTPUT-FILE\n" 43.51 - "is -, output is written to standard output.\n" 43.52 - msgstr "" 43.53 --"Generate message catalogue.\\vIf INPUT-FILE is -, input is read from standard " 43.54 -+"Generate message catalogue.\n" 43.55 -+"If INPUT-FILE is -, input is read from standard " 43.56 - "input. If OUTPUT-FILE\n" 43.57 - "is -, output is written to standard output.\n" 43.58 - 43.59 ---- a/po/eo.po 43.60 -+++ a/po/eo.po 43.61 -@@ -138,7 +138,8 @@ 43.62 - "is -, output is written to standard output.\n" 43.63 - msgstr "" 43.64 - " \n" 43.65 --"Generas mesaĝan katalogon.\vSe ENIGDOSIERO estas «-», ĉefenigujo legiĝas. Se ELIGDOSIERO estas «-», la eligo skribiĝas al ĉefeligujo.\n" 43.66 -+"Generas mesaĝan katalogon.\n" 43.67 -+"Se ENIGDOSIERO estas «-», ĉefenigujo legiĝas. Se ELIGDOSIERO estas «-», la eligo skribiĝas al ĉefeligujo.\n" 43.68 - 43.69 - #: catgets/gencat.c:123 43.70 - msgid "" 43.71 ---- a/po/es.po 43.72 -+++ b/po/es.po 43.73 -@@ -151,7 +151,8 @@ 43.74 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.75 - "is -, output is written to standard output.\n" 43.76 - msgstr "" 43.77 --"Genera un catálogo de mensajes.\vSi FICHERO-ENTRADA es -, la entrada\n" 43.78 -+"Genera un catálogo de mensajes.\n" 43.79 -+"Si FICHERO-ENTRADA es -, la entrada\n" 43.80 - "se lee de la entrada estándar. Si FICHERO-SALIDA es -, el resultado se\n" 43.81 - "escribe en la salida estándar.\n" 43.82 - 43.83 ---- a/po/fi.po 43.84 -+++ b/po/fi.po 43.85 -@@ -151,7 +151,8 @@ 43.86 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.87 - "is -, output is written to standard output.\n" 43.88 - msgstr "" 43.89 --"Luo viestikatalogi.\vJos SYÖTETIEDOSTO on -, syöte luetaan vakiosyötteestä. Jos TULOSTIEDOSTO\n" 43.90 -+"Luo viestikatalogi.\n" 43.91 -+"Jos SYÖTETIEDOSTO on -, syöte luetaan vakiosyötteestä. Jos TULOSTIEDOSTO\n" 43.92 - "on -, tuloste kirjoitetaan vakiotulosteeseen.\n" 43.93 - 43.94 - #: catgets/gencat.c:123 43.95 ---- a/po/fr.po 43.96 -+++ b/po/fr.po 43.97 -@@ -136,7 +136,8 @@ 43.98 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.99 - "is -, output is written to standard output.\n" 43.100 - msgstr "" 43.101 --"Génère le catalogue de messages.\vSi le FICHIER_D_ENTRÉE est -, l'entrée est lue depuis l'entrée standard.\n" 43.102 -+"Génère le catalogue de messages.\n" 43.103 -+"Si le FICHIER_D_ENTRÉE est -, l'entrée est lue depuis l'entrée standard.\n" 43.104 - "Si le FICHIER_DE_SORTIE est -, la sortie est dirigée sur la sortie standard.\n" 43.105 - 43.106 - #: catgets/gencat.c:123 43.107 ---- a/po/hr.po 43.108 -+++ b/po/hr.po 43.109 -@@ -132,7 +132,9 @@ 43.110 - msgid "" 43.111 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.112 - "is -, output is written to standard output.\n" 43.113 --msgstr "Napravi katalog poruka.\vAko je ULAZNA-DATOTEKA -, ulaz se čita sa standardnog ulaza. Ako je IZLAZNA-DATOTEKA -, izlaz se ispisuje na standardni izlaz.\n" 43.114 -+msgstr "" 43.115 -+"Napravi katalog poruka.\n" 43.116 -+"Ako je ULAZNA-DATOTEKA -, ulaz se čita sa standardnog ulaza. Ako je IZLAZNA-DATOTEKA -, izlaz se ispisuje na standardni izlaz.\n" 43.117 - 43.118 - #: catgets/gencat.c:123 43.119 - msgid "" 43.120 ---- a/po/hu.po 43.121 -+++ b/po/hu.po 43.122 -@@ -132,7 +132,8 @@ 43.123 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.124 - "is -, output is written to standard output.\n" 43.125 - msgstr "" 43.126 --"Üzenetkatalógus előállítása\v Ha a BEMENETIFÁJL a -, akkor a szabványos bemenetet olvassa. Ha a \n" 43.127 -+"Üzenetkatalógus előállítása\n" 43.128 -+"Ha a BEMENETIFÁJL a -, akkor a szabványos bemenetet olvassa. Ha a \n" 43.129 - "KIMENETIFÁJL a -, akkor a szabványos kimenetre ír.\n" 43.130 - 43.131 - #: catgets/gencat.c:123 43.132 ---- a/po/ia.po 43.133 -+++ b/po/ia.po 43.134 -@@ -131,7 +131,8 @@ 43.135 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.136 - "is -, output is written to standard output.\n" 43.137 - msgstr "" 43.138 --"Generar un catalogo de messages.\vSi FILE-INPUT es -, le entrata se lege del input standard.\n" 43.139 -+"Generar un catalogo de messages.\n" 43.140 -+"Si FILE-INPUT es -, le entrata se lege del input standard.\n" 43.141 - "Si FILE-OUTPUT es -, le resultato se scribe al output standard.\n" 43.142 - 43.143 - #: catgets/gencat.c:123 43.144 ---- a/po/it.po 43.145 -+++ b/po/it.po 43.146 -@@ -143,7 +143,8 @@ 43.147 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.148 - "is -, output is written to standard output.\n" 43.149 - msgstr "" 43.150 --"Genera un catalogo di messaggi.\vSe FILE-INPUT è -, l'input è letto dallo standard input.\n" 43.151 -+"Genera un catalogo di messaggi.\n" 43.152 -+"Se FILE-INPUT è -, l'input è letto dallo standard input.\n" 43.153 - "Se FILE-OUTPUT è -, l'output è scritto sullo standard output.\n" 43.154 - 43.155 - #: catgets/gencat.c:123 43.156 ---- a/po/nl.po 43.157 -+++ b/po/nl.po 43.158 -@@ -145,7 +145,8 @@ 43.159 - "is -, output is written to standard output.\n" 43.160 - msgstr "" 43.161 - " \n" 43.162 --"Een berichtencatalogus genereren.\vAls INVOERBESTAND '-' is, wordt van standaardinvoer gelezen.\n" 43.163 -+"Een berichtencatalogus genereren.\n" 43.164 -+"Als INVOERBESTAND '-' is, wordt van standaardinvoer gelezen.\n" 43.165 - "Als UITVOERBESTAND '-' is, wordt naar standaarduitvoer geschreven.\n" 43.166 - 43.167 - #: catgets/gencat.c:123 43.168 ---- a/po/pl.po 43.169 -+++ b/po/pl.po 43.170 -@@ -131,7 +131,8 @@ 43.171 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.172 - "is -, output is written to standard output.\n" 43.173 - msgstr "" 43.174 --"Generowanie katalogu komunikatów.\vJeśli PLIK-WE to -, dane są czytane ze standardowego wejścia. Jeśli PLIK-WY\n" 43.175 -+"Generowanie katalogu komunikatów.\n" 43.176 -+"Jeśli PLIK-WE to -, dane są czytane ze standardowego wejścia. Jeśli PLIK-WY\n" 43.177 - "to -, dane są zapisywane na standardowe wyjście.\n" 43.178 - 43.179 - #: catgets/gencat.c:123 43.180 ---- a/po/ru.po 43.181 -+++ b/po/ru.po 43.182 -@@ -138,7 +138,8 @@ 43.183 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.184 - "is -, output is written to standard output.\n" 43.185 - msgstr "" 43.186 --"Генерирует каталог сообщений.\vЕсли ВХОДНОЙ-ФАЙЛ задан как -, читает стандартный ввод. Если\n" 43.187 -+"Генерирует каталог сообщений.\n" 43.188 -+"Если ВХОДНОЙ-ФАЙЛ задан как -, читает стандартный ввод. Если\n" 43.189 - "ВЫХОДНОЙ-ФАЙЛ задан как -, результат печатается на стандартный вывод.\n" 43.190 - 43.191 - #: catgets/gencat.c:123 43.192 ---- a/po/sl.po 43.193 -+++ b/po/sl.po 43.194 -@@ -131,7 +131,9 @@ 43.195 - msgid "" 43.196 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.197 - "is -, output is written to standard output.\n" 43.198 --msgstr "Ustvari katalog sporočil.\vČe je VHODNA_DATOTEKA enaka -, se vhod bere s standardnega vhoda. Če je IZHODNA_DATOTEKA enaka -, se izhod zapisuje na standardni izhod.\n" 43.199 -+msgstr "" 43.200 -+"Ustvari katalog sporočil.\n" 43.201 -+"Če je VHODNA_DATOTEKA enaka -, se vhod bere s standardnega vhoda. Če je IZHODNA_DATOTEKA enaka -, se izhod zapisuje na standardni izhod.\n" 43.202 - 43.203 - #: catgets/gencat.c:123 43.204 - msgid "" 43.205 ---- a/po/sv.po 43.206 -+++ b/po/sv.po 43.207 -@@ -131,7 +131,8 @@ 43.208 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.209 - "is -, output is written to standard output.\n" 43.210 - msgstr "" 43.211 --"Skapa meddelandekatalog.\vOm INFIL är - så läses standard in. Om UTFIL\n" 43.212 -+"Skapa meddelandekatalog.\n" 43.213 -+"Om INFIL är - så läses standard in. Om UTFIL\n" 43.214 - "är - så skrivs resultatet till standard ut.\n" 43.215 - 43.216 - #: catgets/gencat.c:123 43.217 ---- a/po/uk.po 43.218 -+++ b/po/uk.po 43.219 -@@ -133,7 +133,8 @@ 43.220 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.221 - "is -, output is written to standard output.\n" 43.222 - msgstr "" 43.223 --"Створити каталог повідомлень.\vЯкщо як файл ВХІДНИЙ-ФАЙЛ\n" 43.224 -+"Створити каталог повідомлень.\n" 43.225 -+"Якщо як файл ВХІДНИЙ-ФАЙЛ\n" 43.226 - "вказано -, вивід відбуватиметься у стандартний вивід.\n" 43.227 - 43.228 - #: catgets/gencat.c:123 43.229 ---- a/po/zh_CN.po 43.230 -+++ b/po/zh_CN.po 43.231 -@@ -137,7 +137,8 @@ 43.232 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.233 - "is -, output is written to standard output.\n" 43.234 - msgstr "" 43.235 --"产生消息 catelog。\\v如果输入文件名是 -, 将从标准输入读取输入。\n" 43.236 -+"产生消息 catelog。\n" 43.237 -+"如果输入文件名是 -, 将从标准输入读取输入。\n" 43.238 - "如果输出文件名是 -, 则输出将写到标准输出去。\n" 43.239 - 43.240 - #: catgets/gencat.c:123 43.241 ---- a/po/zh_TW.po 43.242 -+++ b/po/zh_TW.po 43.243 -@@ -134,7 +134,8 @@ 43.244 - "Generate message catalog.\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n" 43.245 - "is -, output is written to standard output.\n" 43.246 - msgstr "" 43.247 --"產生訊息 catelog。\\v如果輸入檔名是 -, 將從標準輸入讀取輸入。\n" 43.248 -+"產生訊息 catelog。\n" 43.249 -+"如果輸入檔名是 -, 將從標準輸入讀取輸入。\n" 43.250 - "如果輸出檔名是 -, 則輸出將寫到標準輸出去。\n" 43.251 - 43.252 - #: catgets/gencat.c:123
44.1 --- a/glibc/stuff/patches/series Wed Feb 21 18:10:55 2018 +0200 44.2 +++ b/glibc/stuff/patches/series Wed Feb 21 19:48:17 2018 +0200 44.3 @@ -1,2 +1,1 @@ 44.4 -glibc-2.25-fhs-1.patch 44.5 -glibc-po.patch 44.6 +glibc-2.26-fhs-1.patch
45.1 --- a/gmp/receipt Wed Feb 21 18:10:55 2018 +0200 45.2 +++ b/gmp/receipt Wed Feb 21 19:48:17 2018 +0200 45.3 @@ -7,7 +7,7 @@ 45.4 MAINTAINER="pankso@slitaz.org" 45.5 LICENSE="GPL3" 45.6 WEB_SITE="https://gmplib.org/" 45.7 -HOST_ARCH="i486 arm" 45.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/gmp.html" 45.9 45.10 TARBALL="$PACKAGE-$VERSION.tar.bz2" 45.11 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 45.12 @@ -15,20 +15,20 @@ 45.13 BUILD_DEPENDS="binutils m4 ncurses-dev readline-dev texinfo" 45.14 SPLIT="gmp gmp-dev" 45.15 45.16 -# Rules to configure and make the package. 45.17 -compile_rules() 45.18 -{ 45.19 +compile_rules() { 45.20 + # Create generic libraries 45.21 + cp -v configfsf.guess config.guess 45.22 + cp -v configfsf.sub config.sub 45.23 + 45.24 ./configure \ 45.25 --enable-cxx \ 45.26 --disable-static \ 45.27 - --docdir=/usr/share/doc/gmp-$VERSION \ 45.28 $CONFIGURE_ARGS && 45.29 # -j > 1 make install fails. 45.30 make && make html && make install && make install-html 45.31 } 45.32 45.33 -testsuite() 45.34 -{ 45.35 +testsuite() { 45.36 checklog=$(mktemp) 45.37 make check 2>&1 | tee $checklog 45.38 pass=$(awk '/# PASS:/{total+=$3} ; END{print total}' $checklog) 45.39 @@ -36,11 +36,12 @@ 45.40 rm $checklog 45.41 } 45.42 45.43 -# Rules to gen a SliTaz package suitable for Tazpkg. 45.44 -genpkg_rules() 45.45 -{ 45.46 +genpkg_rules() { 45.47 case $PACKAGE in 45.48 - gmp) copy @std;; 45.49 + gmp) 45.50 + copy @std 45.51 + TAGS="LFS" 45.52 + ;; 45.53 *-dev) copy @dev;; 45.54 esac 45.55 }
46.1 --- a/gperf/receipt Wed Feb 21 18:10:55 2018 +0200 46.2 +++ b/gperf/receipt Wed Feb 21 19:48:17 2018 +0200 46.3 @@ -1,28 +1,22 @@ 46.4 # SliTaz package receipt v2. 46.5 46.6 PACKAGE="gperf" 46.7 -VERSION="3.0.4" 46.8 +VERSION="3.1" 46.9 CATEGORY="development" 46.10 SHORT_DESC="GNU gperf is a perfect hash function generator" 46.11 MAINTAINER="pankso@slitaz.org" 46.12 LICENSE="GPL3" 46.13 WEB_SITE="https://www.gnu.org/software/gperf/" 46.14 -HOST_ARCH="i486 arm" 46.15 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/gperf.html" 46.16 46.17 TARBALL="$PACKAGE-$VERSION.tar.gz" 46.18 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 46.19 46.20 -# Rules to configure and make the package. 46.21 -compile_rules() 46.22 -{ 46.23 - ./configure \ 46.24 - --docdir=/usr/share/doc/gperf-$VERSION \ 46.25 - $CONFIGURE_ARGS && 46.26 - make && make install 46.27 +compile_rules() { 46.28 + ./configure $CONFIGURE_ARGS && make && make install 46.29 } 46.30 46.31 -# Rules to gen a SliTaz package suitable for Tazpkg. 46.32 -genpkg_rules() 46.33 -{ 46.34 +genpkg_rules() { 46.35 copy @std 46.36 + TAGS="LFS" 46.37 }
47.1 --- a/grep/receipt Wed Feb 21 18:10:55 2018 +0200 47.2 +++ b/grep/receipt Wed Feb 21 19:48:17 2018 +0200 47.3 @@ -1,30 +1,28 @@ 47.4 # SliTaz package receipt v2. 47.5 47.6 PACKAGE="grep" 47.7 -VERSION="3.0" 47.8 +VERSION="3.1" 47.9 CATEGORY="development" 47.10 SHORT_DESC="GNU Global Regular Expression Print" 47.11 MAINTAINER="paul@slitaz.org" 47.12 LICENSE="GPL3" 47.13 WEB_SITE="https://www.gnu.org/software/grep/" 47.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/grep.html" 47.15 47.16 TARBALL="$PACKAGE-$VERSION.tar.xz" 47.17 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 47.18 47.19 BUILD_DEPENDS="pcre-dev perl gettext" 47.20 47.21 -# Rules to configure and make the package. 47.22 -compile_rules() 47.23 -{ 47.24 +compile_rules() { 47.25 ./configure \ 47.26 --bindir=/bin \ 47.27 $CONFIGURE_ARGS && 47.28 make && make install 47.29 } 47.30 47.31 -# Rules to gen a SliTaz package suitable for Tazpkg. 47.32 -genpkg_rules() 47.33 -{ 47.34 +genpkg_rules() { 47.35 copy @std 47.36 DEPENDS="pcre" 47.37 + TAGS="LFS" 47.38 }
48.1 --- a/groff/receipt Wed Feb 21 18:10:55 2018 +0200 48.2 +++ b/groff/receipt Wed Feb 21 19:48:17 2018 +0200 48.3 @@ -1,30 +1,28 @@ 48.4 -# SliTaz package receipt. 48.5 +# SliTaz package receipt v2. 48.6 48.7 PACKAGE="groff" 48.8 VERSION="1.22.3" 48.9 CATEGORY="utilities" 48.10 -SHORT_DESC="The GNU troff text-formatting system." 48.11 +SHORT_DESC="The GNU troff text-formatting system" 48.12 MAINTAINER="rocky@slitaz.org" 48.13 LICENSE="GPL3" 48.14 WEB_SITE="https://www.gnu.org/software/groff/" 48.15 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/groff.html" 48.16 48.17 TARBALL="$PACKAGE-$VERSION.tar.gz" 48.18 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 48.19 48.20 -BUILD_DEPENDS="ghostscript perl texinfo" 48.21 +BUILD_DEPENDS="perl texinfo" # ghostscript 48.22 48.23 -# Rules to configure and make the package. 48.24 -compile_rules() 48.25 -{ 48.26 +compile_rules() { 48.27 PAGE=A4 ./configure \ 48.28 --without-x \ 48.29 $CONFIGURE_ARGS && 48.30 - PATH=$PATH:$src/src/preproc/preconv make && 48.31 + PATH=$PATH:$src/src/preproc/preconv make -j1 && 48.32 make install 48.33 } 48.34 48.35 -# Rules to gen a SliTaz package suitable for Tazpkg. 48.36 -genpkg_rules() 48.37 -{ 48.38 +genpkg_rules() { 48.39 copy bin/ groff/ 48.40 + TAGS="LFS" 48.41 }
49.1 --- a/grub2/receipt Wed Feb 21 18:10:55 2018 +0200 49.2 +++ b/grub2/receipt Wed Feb 21 19:48:17 2018 +0200 49.3 @@ -1,23 +1,22 @@ 49.4 # SliTaz package receipt v2. 49.5 49.6 PACKAGE="grub2" 49.7 -SOURCE="grub" 49.8 VERSION="2.02" 49.9 CATEGORY="base-system" 49.10 SHORT_DESC="GRUB2 boot loader" 49.11 MAINTAINER="pascal.bellard@slitaz.org" 49.12 LICENSE="GPL3" 49.13 -TARBALL="$SOURCE-$VERSION.tar.xz" 49.14 WEB_SITE="http://www.gnu.org/software/grub/" 49.15 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/grub.html" 49.16 + 49.17 +TARBALL="grub-$VERSION.tar.xz" 49.18 WGET_URL="ftp://ftp.gnu.org/gnu/grub/$TARBALL" 49.19 49.20 BUILD_DEPENDS="flex bison zlib-dev xz-dev freetype-dev ncurses-dev \ 49.21 libusb-compat-dev libusb-dev libdevmapper-dev" 49.22 -SPLIT="grub2 grub2-efi" 49.23 +SPLIT="grub2 grub2-efi:efi" 49.24 49.25 -# Rules to configure and make the package. 49.26 -compile_rules() 49.27 -{ 49.28 +compile_rules() { 49.29 sed -i 's|sys/types.h>|&\n#include <sys/sysmacros.h>|' \ 49.30 util/getroot.c grub-core/kern/emu/hostdisk.c 49.31 49.32 @@ -25,64 +24,73 @@ 49.33 sed -i "s/'.b'/& \\&\\& cur_len/" grub-core/lib/crypto.c grub-core/normal/auth.c 49.34 49.35 # Fixes for flex 2.5.37 49.36 - export CFLAGS="-Wno-error=sign-compare -Wno-error=unused-value" 49.37 + export CFLAGS="-Wno-error=sign-compare -Wno-error=unused-value" 49.38 sed -i '/#undef gets/{N;s/.*/#ifdef gets\n&\n#endif/}' grub-core/gnulib/stdio*h 49.39 sed -i 's/YY_FATAL_ERROR/REMOVED_&/' grub-core/script/yylex.l 49.40 - 49.41 - #chmod +x install-sh 49.42 - ./configure --prefix=/usr --sysconfdir=/etc \ 49.43 - --mandir=/usr/share/man $CONFIGURE_ARGS && 49.44 - make $MAKEFLAGS && 49.45 - make DESTDIR=$DESTDIR install 49.46 49.47 - export EFI_ARCH=i386 49.48 - ./configure --prefix=/usr --sysconfdir=/etc \ 49.49 - --with-platform=efi --target=${EFI_ARCH} --program-prefix="" \ 49.50 - --mandir=/usr/share/man $CONFIGURE_ARGS && 49.51 - make clean && 49.52 - make $MAKEFLAGS 49.53 - cd grub-core 49.54 - ../grub-mkimage -d . -o ../bootia32.efi -O i386-efi -p /boot/grub \ 49.55 - ntfs hfs appleldr boot cat efi_gop efi_uga elf fat hfsplus \ 49.56 - iso9660 linux keylayouts memdisk minicmd part_apple ext2 extcmd \ 49.57 - xfs xnu part_bsd part_gpt search search_fs_file chain btrfs \ 49.58 - loadbios loadenv lvm minix minix2 reiserfs memrw mmap msdospart \ 49.59 - scsi loopback normal configfile gzio all_video efi_gop efi_uga \ 49.60 - gfxterm gettext echo boot chain 49.61 -} 49.62 + case $SET in 49.63 + '') 49.64 + #chmod +x install-sh 49.65 + ./configure $CONFIGURE_ARGS && 49.66 + make $MAKEFLAGS && 49.67 + make DESTDIR=$DESTDIR install || return 1 49.68 49.69 -# Rules to gen a SliTaz package suitable for Tazpkg. 49.70 -genpkg_rules() 49.71 -{ 49.72 - case $PACKAGE in 49.73 - grub2) 49.74 - DEPENDS="zlib freetype ncurses libusb-compat grep libusb libdevmapper" 49.75 - mkdir -p $fs/boot/grub $fs/usr 49.76 - cp -a $install/usr/bin $fs/usr 49.77 - cp -a $install/usr/sbin $fs/usr 49.78 - cp -a $install/usr/share $fs/usr 49.79 - cp -a $install/usr/lib $fs/usr 49.80 - cp -a $install/etc $fs 49.81 - 49.82 - # Example config file (grub.cfg). 49.83 - cp stuff/example-grub.cfg $fs/boot/grub 49.84 - ;; 49.85 - grub2-efi) 49.86 - mkdir -p $fs/boot/efi/boot 49.87 - cp $src/bootia32.efi $fs/boot/efi/boot 49.88 - ;; 49.89 + # Example config file (grub.cfg) 49.90 + install -Dm0644 $stuff/example-grub.cfg $install/boot/grub/example-grub.cfg 49.91 + ;; 49.92 + efi) 49.93 + export EFI_ARCH=i386 49.94 + ./configure \ 49.95 + --with-platform=efi \ 49.96 + --target=$EFI_ARCH \ 49.97 + --program-prefix="" \ 49.98 + $CONFIGURE_ARGS && 49.99 + make clean && 49.100 + make $MAKEFLAGS || return 1 49.101 + 49.102 + cd grub-core 49.103 + ../grub-mkimage \ 49.104 + -d . \ 49.105 + -o ../bootia32.efi \ 49.106 + -O i386-efi \ 49.107 + -p /boot/grub \ 49.108 + ntfs hfs appleldr boot cat efi_gop efi_uga elf fat hfsplus \ 49.109 + iso9660 linux keylayouts memdisk minicmd part_apple ext2 extcmd \ 49.110 + xfs xnu part_bsd part_gpt search search_fs_file chain btrfs \ 49.111 + loadbios loadenv lvm minix minix2 reiserfs memrw mmap msdospart \ 49.112 + scsi loopback normal configfile gzio all_video efi_gop efi_uga \ 49.113 + gfxterm gettext echo boot chain || return 1 49.114 + 49.115 + install -Dm644 $src/bootia32.efi $install/boot/efi/boot/bootia32.efi 49.116 + ;; 49.117 esac 49.118 } 49.119 49.120 -post_install_grub2() 49.121 -{ 49.122 - cat <<EOT 49.123 -# To install grub to your sda MBR 49.124 -grub-install /dev/sda 49.125 +genpkg_rules() { 49.126 + case $PACKAGE in 49.127 + grub2) 49.128 + copy @std 49.129 + DEPENDS="zlib freetype ncurses libusb-compat grep libusb libdevmapper" 49.130 + TAGS="LFS" 49.131 + ;; 49.132 + grub2-efi) 49.133 + copy @std 49.134 + DEPENDS=" " 49.135 + ;; 49.136 + esac 49.137 +} 49.138 49.139 -# To generate a configuration file 49.140 -grub-mkconfig -o /boot/grub/grub.cfg 49.141 +post_install_grub2() { 49.142 + [ -n "$quiet" ] || cat <<EOT 49.143 49.144 -# You can learn from /boot/grub/example-grub.cfg too. 49.145 + .-------------------------------------------------------. 49.146 + | # To install grub to your sda MBR | 49.147 + | grub-install /dev/sda | 49.148 + |-------------------------------------------------------| 49.149 + | # To generate a configuration file | 49.150 + | grub-mkconfig -o /boot/grub/grub.cfg | 49.151 + |-------------------------------------------------------| 49.152 + | # You can learn from /boot/grub/example-grub.cfg too. | 49.153 + '-------------------------------------------------------' 49.154 EOT 49.155 }
50.1 --- a/gzip/receipt Wed Feb 21 18:10:55 2018 +0200 50.2 +++ b/gzip/receipt Wed Feb 21 19:48:17 2018 +0200 50.3 @@ -7,6 +7,8 @@ 50.4 MAINTAINER="erjo@slitaz.org" 50.5 LICENSE="GPL3" 50.6 WEB_SITE="https://www.gnu.org/software/gzip/" 50.7 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/gzip.html" 50.8 +HOST_ARCH="i486 x86_64" 50.9 50.10 TARBALL="$PACKAGE-$VERSION.tar.xz" 50.11 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 50.12 @@ -14,25 +16,21 @@ 50.13 BUILD_DEPENDS="glibc-dev" 50.14 SPLIT="gzip-full" 50.15 50.16 -# Rules to configure and make the package. 50.17 -compile_rules() 50.18 -{ 50.19 +compile_rules() { 50.20 ./configure $CONFIGURE_ARGS && make && make install 50.21 50.22 mkdir -p $install/bin 50.23 mv -v $install/usr/bin/gzip $install/bin 50.24 } 50.25 50.26 -# Rules to gen a SliTaz package suitable for Tazpkg. 50.27 -genpkg_rules() 50.28 -{ 50.29 +genpkg_rules() { 50.30 case $PACKAGE in 50.31 gzip) 50.32 copy gzip gunzip zgrep 50.33 + TAGS="LFS" 50.34 ;; 50.35 gzip-full) 50.36 - copy bin/ 50.37 - remove_already_packed 50.38 + copy bin/ @rm 50.39 CAT="system-tools|full set" 50.40 DEPENDS="gzip" 50.41 ;; 50.42 @@ -41,14 +39,18 @@ 50.43 50.44 # Removing Busybox gunzip applet 50.45 # as we have /usr/bin/gunzip in this package 50.46 -pre_install_gzip() 50.47 -{ 50.48 - rm -f "$1/bin/gzip" "$1/bin/gunzip" 50.49 +pre_install_gzip() { 50.50 + for i in gzip gunzip; do 50.51 + readlink "$1/bin/$i" | grep -q busybox && rm "$1/bin/$i" 50.52 + done 50.53 + : 50.54 } 50.55 50.56 # Removing Busybox uncompress and zcat applets 50.57 # as we have /usr/bin/uncompress and /usr/bin/zcat in this package 50.58 -pre_install_gzip_full() 50.59 -{ 50.60 - rm -f "$1/bin/uncompress" "$1/bin/zcat" 50.61 +pre_install_gzip_full() { 50.62 + for i in uncompress zcat; do 50.63 + readlink "$1/bin/$i" | grep -q busybox && rm "$1/bin/$i" 50.64 + done 50.65 + : 50.66 }
51.1 --- a/iana-etc/receipt Wed Feb 21 18:10:55 2018 +0200 51.2 +++ b/iana-etc/receipt Wed Feb 21 19:48:17 2018 +0200 51.3 @@ -7,20 +7,18 @@ 51.4 MAINTAINER="al.bobylev@gmail.com" 51.5 LICENSE="OSL3" 51.6 WEB_SITE="http://freecode.com/projects/iana-etc" 51.7 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/iana-etc.html" 51.8 51.9 TARBALL="$PACKAGE-$VERSION.tar.bz2" 51.10 WGET_URL="http://anduin.linuxfromscratch.org/LFS/$TARBALL" 51.11 51.12 BUILD_DEPENDS="gawk" 51.13 51.14 -# Rules to configure and make the package. 51.15 -compile_rules() 51.16 -{ 51.17 +compile_rules() { 51.18 make && make DESTDIR=$install install 51.19 } 51.20 51.21 -# Rules to gen a SliTaz package suitable for Tazpkg. 51.22 -genpkg_rules() 51.23 -{ 51.24 +genpkg_rules() { 51.25 copy @std 51.26 + TAGS="LFS" 51.27 }
52.1 --- a/inetutils/receipt Wed Feb 21 18:10:55 2018 +0200 52.2 +++ b/inetutils/receipt Wed Feb 21 19:48:17 2018 +0200 52.3 @@ -7,13 +7,12 @@ 52.4 MAINTAINER="al.bobylev@gmail.com" 52.5 LICENSE="GPL3" 52.6 WEB_SITE="https://www.gnu.org/software/inetutils/" 52.7 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/inetutils.html" 52.8 52.9 TARBALL="$PACKAGE-$VERSION.tar.xz" 52.10 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 52.11 52.12 -# Rules to configure and make the package. 52.13 -compile_rules() 52.14 -{ 52.15 +compile_rules() { 52.16 ./configure \ 52.17 --localstatedir=/var \ 52.18 --disable-logger \ 52.19 @@ -33,9 +32,8 @@ 52.20 mv $install/usr/bin/ifconfig $install/sbin 52.21 } 52.22 52.23 -# Rules to gen a SliTaz package suitable for Tazpkg. 52.24 -genpkg_rules() 52.25 -{ 52.26 +genpkg_rules() { 52.27 copy @std 52.28 DEPENDS="readline" 52.29 + TAGS="LFS" 52.30 }
53.1 --- a/intltool/receipt Wed Feb 21 18:10:55 2018 +0200 53.2 +++ b/intltool/receipt Wed Feb 21 19:48:17 2018 +0200 53.3 @@ -7,27 +7,23 @@ 53.4 MAINTAINER="pankso@slitaz.org" 53.5 LICENSE="GPL2" 53.6 WEB_SITE="https://freedesktop.org/wiki/Software/intltool/" 53.7 -HOST_ARCH="i486 arm" 53.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/intltool.html" 53.9 53.10 TARBALL="$PACKAGE-$VERSION.tar.gz" 53.11 WGET_URL="http://launchpad.net/intltool/trunk/$VERSION/+download/$TARBALL" 53.12 53.13 -BUILD_DEPENDS="perl perl-xml-parser wget" 53.14 +BUILD_DEPENDS="perl perl-xml-parser" 53.15 53.16 -# Rules to configure and make the package. 53.17 -compile_rules() 53.18 -{ 53.19 +compile_rules() { 53.20 sed -i 's:\\\${:\\\$\\{:' intltool-update.in 53.21 53.22 ./configure $CONFIGURE_ARGS && make && make install 53.23 53.24 - docdir="$install/usr/share/doc/intltool-$VERSION" 53.25 - mkdir -p $docdir; cp doc/I18N-HOWTO $docdir 53.26 + cook_pick_docs doc/I18N-HOWTO 53.27 } 53.28 53.29 -# Rules to gen a SliTaz package suitable for Tazpkg. 53.30 -genpkg_rules() 53.31 -{ 53.32 +genpkg_rules() { 53.33 copy @std @dev 53.34 DEPENDS="perl-xml-parser gettext" 53.35 + TAGS="LFS" 53.36 }
54.1 --- a/iproute2/receipt Wed Feb 21 18:10:55 2018 +0200 54.2 +++ b/iproute2/receipt Wed Feb 21 19:48:17 2018 +0200 54.3 @@ -1,31 +1,28 @@ 54.4 # SliTaz package receipt v2. 54.5 54.6 PACKAGE="iproute2" 54.7 -VERSION="4.9.0" 54.8 +VERSION="4.12.0" 54.9 CATEGORY="network" 54.10 SHORT_DESC="Utilites for networking and traffic control" 54.11 MAINTAINER="allan316@gmail.com" 54.12 LICENSE="GPL2" 54.13 WEB_SITE="http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2" 54.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/iproute2.html" 54.15 54.16 TARBALL="$PACKAGE-$VERSION.tar.xz" 54.17 WGET_URL="https://www.kernel.org/pub/linux/utils/net/$PACKAGE/$TARBALL" 54.18 54.19 BUILD_DEPENDS="bison flex iptables-dev db-dev libmnl-dev elfutils-dev" 54.20 54.21 -# Rules to configure and make the package. 54.22 -compile_rules() 54.23 -{ 54.24 +compile_rules() { 54.25 ./configure /usr/include $CONFIGURE_ARGS && 54.26 sed -i 's|tc-skbmod\.8||' $src/man/man8/Makefile && 54.27 make && 54.28 make DOCDIR=/usr/share/doc/$PACKAGE-$VERSION DESTDIR=$DESTDIR install 54.29 } 54.30 54.31 -# Rules to gen a SliTaz package suitable for Tazpkg. 54.32 -genpkg_rules() 54.33 -{ 54.34 +genpkg_rules() { 54.35 copy @std 54.36 - TAGS="network route" 54.37 + TAGS="LFS network route" 54.38 DEPENDS="iptables db" 54.39 }
55.1 --- a/kbd/receipt Wed Feb 21 18:10:55 2018 +0200 55.2 +++ b/kbd/receipt Wed Feb 21 19:48:17 2018 +0200 55.3 @@ -7,18 +7,16 @@ 55.4 MAINTAINER="pankso@slitaz.org" 55.5 LICENSE="GPL2" 55.6 WEB_SITE="http://kbd-project.org/" 55.7 -HOST_ARCH="i486 arm" 55.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/kbd.html" 55.9 55.10 TARBALL="kbd-$VERSION.tar.xz" 55.11 WGET_URL="https://www.kernel.org/pub/linux/utils/kbd/$TARBALL" 55.12 55.13 +BUILD_DEPENDS_arm="flex check-dev" 55.14 BUILD_DEPENDS="check-dev bison flex gettext patch pam-dev busybox" 55.15 -BUILD_DEPENDS_arm="flex check-dev" 55.16 SPLIT="kbd-base kbd-vlock kbd-busybox kbd" 55.17 55.18 -# Rules to configure and make the package. 55.19 -compile_rules() 55.20 -{ 55.21 +compile_rules() { 55.22 sed -i 's/\(RESIZECONS_PROGS=\)yes/\1no/g' configure 55.23 sed -i 's/resizecons.8 //' docs/man/man8/Makefile.in 55.24 55.25 @@ -28,6 +26,11 @@ 55.26 sed -i 's| | |g; s| *| |g; s|^ ||; s| $||; /^#/d; /^!/d; /^$/d' $i 55.27 done 55.28 55.29 + # Unicode range is limited by 0xf000 here with error "Unicode keysym out of range", 55.30 + # but de_alt_UTF-8.map has the symbols U+FB01, U+F8FF, U+FB02 55.31 + # And due to this error zero-sized file .kmap is produced. 55.32 + sed -i 's|0xf000|0xfffe|' src/libkeymap/analyze.c src/libkeymap/analyze.l 55.33 + 55.34 ./configure \ 55.35 --datadir=/usr/share/kbd \ 55.36 $CONFIGURE_ARGS && 55.37 @@ -35,8 +38,7 @@ 55.38 55.39 mv $install/usr/share/kbd/locale $install/usr/share 55.40 55.41 - mkdir -p $install/usr/share/doc/kbd-$VERSION 55.42 - cp -R docs/doc/* $install/usr/share/doc/kbd-$VERSION 55.43 + cook_pick_docs docs/doc/* 55.44 55.45 # X11 keyboard aliases 55.46 ln -s croat.map.gz $install/usr/share/kbd/keymaps/i386/qwertz/hr.map.gz 55.47 @@ -50,16 +52,13 @@ 55.48 done 55.49 } 55.50 55.51 -# Make sure it will run on host or no keyboard support... 55.52 -testsuite() 55.53 -{ 55.54 +# Make sure it will run on target or no keyboard support... 55.55 +testsuite() { 55.56 readelf -h $install/usr/bin/loadkeys 55.57 readelf -h $install/usr/bin/setfont 55.58 } 55.59 55.60 -# Rules to gen a SliTaz package suitable for Tazpkg. 55.61 -genpkg_rules() 55.62 -{ 55.63 +genpkg_rules() { 55.64 case $PACKAGE in 55.65 kbd-base) 55.66 copy loadkeys setfont \ 55.67 @@ -94,10 +93,9 @@ 55.68 CAT="base-system|mappings for busybox" 55.69 ;; 55.70 kbd) 55.71 - copy bin/ kbd/ 55.72 - remove_already_packed 55.73 + copy bin/ kbd/ @rm 55.74 DEPENDS="kbd-base" 55.75 - TAGS="keyboard" 55.76 + TAGS="LFS keyboard" 55.77 ;; 55.78 esac 55.79 }
56.1 --- a/kmod/receipt Wed Feb 21 18:10:55 2018 +0200 56.2 +++ b/kmod/receipt Wed Feb 21 19:48:17 2018 +0200 56.3 @@ -1,26 +1,25 @@ 56.4 # SliTaz package receipt v2. 56.5 56.6 PACKAGE="kmod" 56.7 -VERSION="23" 56.8 +VERSION="24" 56.9 CATEGORY="base-system" 56.10 SHORT_DESC="Linux kernel modules tools" 56.11 MAINTAINER="pankso@slitaz.org" 56.12 LICENSE="GPL2" 56.13 WEB_SITE="https://www.kernel.org/pub/linux/utils/kernel/kmod/" 56.14 -HOST_ARCH="i486 arm" 56.15 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/kmod.html" 56.16 56.17 TARBALL="$PACKAGE-$VERSION.tar.xz" 56.18 WGET_URL="$WEB_SITE$TARBALL" 56.19 56.20 +BUILD_DEPENDS_arm="zlib-dev xz-dev" 56.21 BUILD_DEPENDS="zlib-dev xz-dev tar" 56.22 -BUILD_DEPENDS_arm="zlib-dev xz-dev" 56.23 SPLIT="kmod-dev" 56.24 56.25 compile_rules() { 56.26 ./configure \ 56.27 --bindir=/bin \ 56.28 --with-rootlibdir=/lib \ 56.29 - --sysconfdir=/etc \ 56.30 --with-zlib \ 56.31 --with-xz \ 56.32 $CONFIGURE_ARGS && 56.33 @@ -43,6 +42,7 @@ 56.34 # please keep glibc-base here because kmod used in the post-install 56.35 # of linux-* packages and will not work instead 56.36 DEPENDS="glibc-base zlib liblzma" 56.37 + TAGS="LFS" 56.38 ;; 56.39 *-dev) 56.40 copy @dev
57.1 --- a/less/receipt Wed Feb 21 18:10:55 2018 +0200 57.2 +++ b/less/receipt Wed Feb 21 19:48:17 2018 +0200 57.3 @@ -1,21 +1,21 @@ 57.4 # SliTaz package receipt v2. 57.5 57.6 PACKAGE="less" 57.7 -VERSION="481" 57.8 +VERSION="487" 57.9 CATEGORY="base-system" 57.10 SHORT_DESC="A terminal based program for viewing text files" 57.11 MAINTAINER="slaxemulator@gmail.com" 57.12 LICENSE="GPL3" 57.13 WEB_SITE="http://www.greenwoodsoftware.com/less" 57.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/less.html" 57.15 +HOST_ARCH="i486 x86_64" 57.16 57.17 TARBALL="$PACKAGE-$VERSION.tar.gz" 57.18 WGET_URL="$WEB_SITE/$TARBALL" 57.19 57.20 BUILD_DEPENDS="ncurses-dev pcre-dev" 57.21 57.22 -# Rules to configure and make the package. 57.23 -compile_rules() 57.24 -{ 57.25 +compile_rules() { 57.26 ./configure \ 57.27 --sysconfdir=/etc \ 57.28 --with-regex=pcre \ 57.29 @@ -23,9 +23,8 @@ 57.30 make && make DESTDIR=$install install 57.31 } 57.32 57.33 -# Rules to gen a SliTaz package suitable for Tazpkg. 57.34 -genpkg_rules() 57.35 -{ 57.36 +genpkg_rules() { 57.37 copy @std 57.38 DEPENDS="ncurses pcre" 57.39 + TAGS="LFS" 57.40 }
58.1 --- a/libcap/receipt Wed Feb 21 18:10:55 2018 +0200 58.2 +++ b/libcap/receipt Wed Feb 21 19:48:17 2018 +0200 58.3 @@ -7,27 +7,30 @@ 58.4 MAINTAINER="pankso@slitaz.org" 58.5 LICENSE="BSD" 58.6 WEB_SITE="https://sites.google.com/site/fullycapable/" 58.7 -HOST_ARCH="i486 arm" 58.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/libcap.html" 58.9 58.10 TARBALL="$PACKAGE-$VERSION.tar.xz" 58.11 WGET_URL="https://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/$TARBALL" 58.12 58.13 +BUILD_DEPENDS_arm="gperf pam-dev attr-dev" 58.14 BUILD_DEPENDS="gperf pam-dev attr-dev perl" 58.15 -BUILD_DEPENDS_arm="gperf pam-dev attr-dev" 58.16 -SPLIT="libcap-pam libcap-dev" 58.17 +SPLIT="libcap-pam libcap libcap-dev" 58.18 58.19 -# Handle cross compilation. 58.20 -case "$ARCH" in 58.21 - arm*) ARCH_ARGS="CC=$HOST_SYSTEM-gcc BUILD_CC=gcc" ;; 58.22 -esac 58.23 +compile_rules() { 58.24 + # Handle cross compilation. 58.25 + case "$ARCH" in 58.26 + arm*) ARCH_ARGS="CC=$HOST_SYSTEM-gcc BUILD_CC=gcc" ;; 58.27 + esac 58.28 58.29 -# Rules to configure and make the package. 58.30 -compile_rules() 58.31 -{ 58.32 + # Prevent a static library from being installed 58.33 sed -i '/install.*STALIBNAME/d' libcap/Makefile 58.34 58.35 make $ARCH_ARGS && 58.36 - make RAISE_SETFCAP=no prefix=/usr install || return 1 58.37 + make \ 58.38 + RAISE_SETFCAP=no \ 58.39 + lib=lib \ 58.40 + prefix=/usr \ 58.41 + install || return 1 58.42 58.43 chmod 755 $install/usr/lib/libcap.so 58.44 mkdir $install/lib 58.45 @@ -36,19 +39,18 @@ 58.46 $install/usr/lib/libcap.so 58.47 } 58.48 58.49 -# Rules to gen a SliTaz package suitable for Tazpkg. 58.50 -genpkg_rules() 58.51 -{ 58.52 +genpkg_rules() { 58.53 case $PACKAGE in 58.54 - libcap) 58.55 - copy @std 58.56 - DEPENDS="attr" 58.57 - ;; 58.58 libcap-pam) 58.59 + copy pam_cap.so 58.60 CAT="system-tools|PAM module" 58.61 PROVIDE="libcap:pam" 58.62 DEPENDS="libcap pam" 58.63 - copy pam_cap.so 58.64 + ;; 58.65 + libcap) 58.66 + copy @std @rm 58.67 + DEPENDS="attr" 58.68 + TAGS="LFS" 58.69 ;; 58.70 *-dev) copy @dev;; 58.71 esac
59.1 --- a/libpipeline/receipt Wed Feb 21 18:10:55 2018 +0200 59.2 +++ b/libpipeline/receipt Wed Feb 21 19:48:17 2018 +0200 59.3 @@ -1,12 +1,13 @@ 59.4 # SliTaz package receipt v2. 59.5 59.6 PACKAGE="libpipeline" 59.7 -VERSION="1.4.1" 59.8 +VERSION="1.4.2" 59.9 CATEGORY="system-tools" 59.10 SHORT_DESC="Pipeline manipulation library" 59.11 MAINTAINER="al.bobylev@gmail.com" 59.12 LICENSE="GPL3" 59.13 WEB_SITE="http://libpipeline.nongnu.org/" 59.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/libpipeline.html" 59.15 59.16 TARBALL="$PACKAGE-$VERSION.tar.gz" 59.17 WGET_URL="http://download.savannah.gnu.org/releases/$PACKAGE/$TARBALL" 59.18 @@ -14,17 +15,16 @@ 59.19 BUILD_DEPENDS="check-dev" 59.20 SPLIT="libpipeline-dev" 59.21 59.22 -# Rules to configure and make the package. 59.23 -compile_rules() 59.24 -{ 59.25 +compile_rules() { 59.26 ./configure $CONFIGURE_ARGS && make && make install 59.27 } 59.28 59.29 -# Rules to gen a SliTaz package suitable for Tazpkg. 59.30 -genpkg_rules() 59.31 -{ 59.32 +genpkg_rules() { 59.33 case $PACKAGE in 59.34 - libpipeline) copy @std;; 59.35 + libpipeline) 59.36 + copy @std 59.37 + TAGS="LFS" 59.38 + ;; 59.39 *-dev) copy @dev;; 59.40 esac 59.41 }
60.1 --- a/libtool/receipt Wed Feb 21 18:10:55 2018 +0200 60.2 +++ b/libtool/receipt Wed Feb 21 19:48:17 2018 +0200 60.3 @@ -3,37 +3,34 @@ 60.4 PACKAGE="libtool" 60.5 VERSION="2.4.6" 60.6 CATEGORY="development" 60.7 -SHORT_DESC="The GNU Portable Library Tool." 60.8 +SHORT_DESC="The GNU Portable Library Tool" 60.9 MAINTAINER="pankso@slitaz.org" 60.10 LICENSE="GPL2" 60.11 WEB_SITE="https://www.gnu.org/software/libtool/" 60.12 -HOST_ARCH="i486 arm" 60.13 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/libtool.html" 60.14 60.15 TARBALL="$PACKAGE-$VERSION.tar.xz" 60.16 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 60.17 60.18 +BUILD_DEPENDS_arm=" " 60.19 BUILD_DEPENDS="automake autoconf gfortran" 60.20 -BUILD_DEPENDS_arm=" " 60.21 -SPLIT="libltdl" 60.22 +SPLIT="libltdl libtool" 60.23 60.24 -# Rules to configure and make the package. 60.25 -compile_rules() 60.26 -{ 60.27 +compile_rules() { 60.28 ./configure $CONFIGURE_ARGS && make && make install 60.29 } 60.30 60.31 -# Rules to gen a SliTaz package suitable for Tazpkg. 60.32 -genpkg_rules() 60.33 -{ 60.34 +genpkg_rules() { 60.35 case $PACKAGE in 60.36 - libtool) 60.37 - copy bin/ include/ aclocal/ libtool/ *.*a 60.38 - DEPENDS="libltdl automake autoconf" 60.39 - ;; 60.40 libltdl) 60.41 copy *.so* 60.42 CAT="system-tools|library" 60.43 DEPENDS="glibc-base" 60.44 ;; 60.45 + libtool) 60.46 + copy @std @dev @rm 60.47 + DEPENDS="libltdl automake autoconf" 60.48 + TAGS="LFS" 60.49 + ;; 60.50 esac 60.51 }
61.1 --- a/linux-dev/receipt Wed Feb 21 18:10:55 2018 +0200 61.2 +++ b/linux-dev/receipt Wed Feb 21 19:48:17 2018 +0200 61.3 @@ -1,33 +1,39 @@ 61.4 # SliTaz package receipt v2. 61.5 61.6 PACKAGE="linux-dev" 61.7 -VERSION="4.9.76" 61.8 -KBASEVER="4.9" 61.9 +VERSION="$(. $WOK/linux/receipt; echo $VERSION)" 61.10 +KBASEVER="$(. $WOK/linux/receipt; echo $KBASEVER)" 61.11 CATEGORY="development" 61.12 SHORT_DESC="The Linux Kernel" 61.13 MAINTAINER="devel@slitaz.org" 61.14 LICENSE="GPL2" 61.15 WEB_SITE="https://www.kernel.org/" 61.16 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/linux-headers.html" 61.17 61.18 TARBALL="linux-$KBASEVER.tar.xz" 61.19 WGET_URL="https://www.kernel.org/pub/linux/kernel/v4.x/$TARBALL" 61.20 61.21 -DEPENDS="ncurses" 61.22 -BUILD_DEPENDS="python-sphinx perl xmlto util-linux-getopt docbook-xsl \ 61.23 -coreutils-operations findutils ncurses-dev patch bash bc" 61.24 -SPLIT="linux-dev linux-man linux-api-headers linux-uml" 61.25 +case $ARCH in 61.26 + i*86) 61.27 + SPLIT="linux-dev linux-api-headers linux-uml" 61.28 + BUILD_DEPENDS="python-sphinx perl xmlto util-linux-getopt docbook-xsl \ 61.29 + coreutils-operations findutils ncurses-dev patch bash bc" 61.30 + ;; 61.31 + x86_64) 61.32 + SPLIT="linux-dev linux-api-headers" 61.33 + BUILD_DEPENDS="perl patch ncurses-dev" 61.34 + ;; 61.35 +esac 61.36 SIBLINGS="linux" 61.37 -COOKOPTS="!pngz !svgz !uiz" 61.38 +COOKOPTS="!pngz !svgz !uiz !strip" 61.39 61.40 if [ "$KBASEVER" != "${VERSION%.0}" ]; then 61.41 PATCH="$(dirname $WGET_URL)/patch-$VERSION.xz" 61.42 EXTRA_SOURCE_FILES="$(basename $PATCH)" 61.43 fi 61.44 61.45 -# Rules to configure and make the package. 61.46 -compile_rules() 61.47 -{ 61.48 - # Update sources to the $VERSION using base sources ($KBASEVER) and patch 61.49 +compile_rules() { 61.50 + # Update sources to the $VERSION using base sources ($KBASEVER) and patches 61.51 if [ "$KBASEVER" != "${VERSION%.0}" ]; then 61.52 [ -s $SRC/$(basename $PATCH) ] || wget $PATCH -O $SRC/$(basename $PATCH) 61.53 # don't patch twice for `cook $PACKAGE --continue` 61.54 @@ -47,7 +53,7 @@ 61.55 . $WOK/linux/stuff/tools/aufs-patches 61.56 61.57 make defconfig 61.58 - sed -i 's/^menuconfig:.*/z&\n\techo menuconfig is ready\n\n&/' \ 61.59 + sed -i 's/^menuconfig:.*/z&\n\t@echo menuconfig is ready\n\n&/' \ 61.60 scripts/kconfig/Makefile 61.61 make zmenuconfig 61.62 61.63 @@ -57,120 +63,44 @@ 61.64 61.65 mkdir -p $install/usr/bin 61.66 mv $p/scripts/kconfig/mconf $install/usr/bin 61.67 - cat > $install/usr/bin/menuconfig <<EOT 61.68 -#!/bin/sh 61.69 -p=\$PWD 61.70 -cd ../src/linux-$VERSION-slitaz 61.71 -SRCARCH=x86 ARCH=i386 KERNELVERSION=$VERSION \$p/mconf Kconfig 61.72 -EOT 61.73 + sed "s|@VERSION@|$VERSION|; s|@ARCH@|$ARCH|" $stuff/menuconfig.in \ 61.74 + > $install/usr/bin/menuconfig 61.75 chmod a+x $install/usr/bin/menuconfig 61.76 61.77 - patch -p1 -i $stuff/installmandocs.patch 61.78 61.79 - make mandocs && make installmandocs 61.80 + if [ "$ARCH" == 'i386' ]; then 61.81 + sed -i 's|uname -m|echo i386|; s|/bin/bash|/bin/ash|g' Makefile 61.82 + make ARCH=um mrproper 61.83 + cp $stuff/mini.config . 61.84 + make ARCH=um allnoconfig KCONFIG_ALLCONFIG=mini.config && 61.85 + make ARCH=um || return 1 61.86 61.87 - sed -i 's/uname -m/echo i386/;s|/bin/bash|/bin/ash|g' Makefile 61.88 - make ARCH=um mrproper 61.89 - cat > mini.config << EOF && 61.90 -CONFIG_BINFMT_ELF=y 61.91 -CONFIG_LBD=y 61.92 -CONFIG_BLK_DEV=y 61.93 -CONFIG_BLK_DEV_LOOP=y 61.94 -CONFIG_STDERR_CONSOLE=y 61.95 -CONFIG_SSL=y 61.96 -CONFIG_UNIX98_PTYS=y 61.97 -CONFIG_PROC_FS=y 61.98 -CONFIG_SYSFS_FS=y 61.99 -CONFIG_IKCONFIG=y 61.100 -CONFIG_IKCONFIG_PROC=y 61.101 -CONFIG_UML_NET=y 61.102 -CONFIG_UML_NET_TUNTAP=y 61.103 -CONFIG_BLK_DEV_INITRD=y 61.104 -CONFIG_PTY_CHAN=y 61.105 -CONFIG_TTY_CHAN=y 61.106 -CONFIG_NET=y 61.107 -CONFIG_INET=y 61.108 -CONFIG_UML_NET=y 61.109 -CONFIG_UML_NET_TUNTAP=y 61.110 -CONFIG_BLK_DEV_UBD=y 61.111 -CONFIG_EXT4_FS=y 61.112 -CONFIG_EXT4_USE_FOR_EXT23=y 61.113 -CONFIG_EXT4_FS_XATTR=y 61.114 -CONFIG_EXT4_FS_POSIX_ACL=y 61.115 -CONFIG_FUSE_FS=y 61.116 -CONFIG_ISO9660_FS=y 61.117 -CONFIG_VFAT_FS=y 61.118 -CONFIG_TMPFS=y 61.119 -CONFIG_SWAP=y 61.120 -CONFIG_SYSVIPC=y 61.121 -CONFIG_SYSVIPC_SYSCTL=y 61.122 -CONFIG_SYSVIPC_COMPAT=y 61.123 -CONFIG_PACKET=y 61.124 -CONFIG_UNIX=y 61.125 -CONFIG_NETFILTER=y 61.126 -CONFIG_NETFILTER_ADVANCED=y 61.127 -CONFIG_NF_CONNTRACK=y 61.128 -CONFIG_NETFILTER_XTABLES=y 61.129 -CONFIG_NF_DEFRAG_IPV4=y 61.130 -CONFIG_NF_CONNTRACK_IPV4=y 61.131 -CONFIG_NF_CONNTRACK_PROC_COMPAT=y 61.132 -CONFIG_IP_NF_IPTABLES=y 61.133 -CONFIG_IP_NF_FILTER=y 61.134 -CONFIG_IP_NF_TARGET_REJECT=y 61.135 -CONFIG_NF_NAT=y 61.136 -CONFIG_NF_NAT_NEEDED=y 61.137 -CONFIG_IP_NF_TARGET_MASQUERADE=y 61.138 -CONFIG_IP_NF_TARGET_REDIRECT=y 61.139 -CONFIG_NETDEVICES=y 61.140 -CONFIG_TUN=y 61.141 -EOF 61.142 - make ARCH=um allnoconfig KCONFIG_ALLCONFIG=mini.config && 61.143 - make ARCH=um || return 1 61.144 - 61.145 - mkdir -p $install/boot 61.146 - cp $src/linux $install/boot/linux-uml-$VERSION 61.147 - cat > $install/boot/vm-uml <<EOT 61.148 -#!/bin/sh 61.149 - 61.150 -# /etc/inittab: "tty21::respawn:/bin/su -c '/boot/vm-uml 1 /boot/guests/slitaz.img 2 512m' nobody" 61.151 -n=\${1:-0} 61.152 -tap=tap\$n 61.153 -args="rw root=/dev/null" 61.154 -dev="initrd=\$(ls -r /boot/rootfs*.gz | sed q)" 61.155 -if [ -n "\$2" ]; then 61.156 - args="ro root=620\${3:-1} screen=text sound=noconf" 61.157 - dev="ubd0=\$2" 61.158 -fi 61.159 - 61.160 -cd \$(dirname \$0) 61.161 -ifconfig \$tap 192.168.\$n.1 61.162 -./linux-uml-$VERSION \$dev mem=\${4:-512m} fakehd fake_ide ubd=3 con0=fd:0,fd:1 \\ 61.163 - con=pts ssl=pts eth0=tuntap,\$tap,fe:f0:00:00:00:0\$n,192.168.\$n.1 \\ 61.164 - \$args cpuinfo=\$(sed '/model name/!d;s/.*: //;s/ /_/g;q' /proc/cpuinfo) 61.165 -EOT 61.166 - chmod 755 $install/boot/vm-uml 61.167 + mkdir -p $install/boot 61.168 + cp $src/linux $install/boot/linux-uml-$VERSION 61.169 + sed "s|@VERSION@|$VERSION|" $stuff/vm-uml.in > $install/boot/vm-uml 61.170 + chmod 755 $install/boot/vm-uml 61.171 + fi 61.172 } 61.173 61.174 61.175 -# Rules to gen a SliTaz package suitable for Tazpkg. 61.176 -genpkg_rules() 61.177 -{ 61.178 +genpkg_rules() { 61.179 case $PACKAGE in 61.180 - linux-dev) 61.181 - copy Kconfig* mconf menuconfig .config 61.182 - CAT="development|menu based configuration tool" 61.183 - ;; 61.184 - linux-man) 61.185 - copy /usr/share/man/ 61.186 - CAT="doc|manual pages" 61.187 - ;; 61.188 - linux-api-headers) 61.189 - copy @dev 61.190 - CAT="development|headers sanitized for use in userspace" 61.191 - PROVIDE="linux-headers linux64-api-headers linux64-headers" 61.192 - ;; 61.193 - linux-uml) 61.194 - copy boot/ 61.195 - ;; 61.196 + linux-dev) 61.197 + copy Kconfig* mconf menuconfig .config 61.198 + CAT="development|menu based configuration tool" 61.199 + DEPENDS="ncurses" 61.200 + TAGS="LFS" 61.201 + ;; 61.202 + linux-api-headers) 61.203 + copy @dev 61.204 + DEPENDS=" " 61.205 + CAT="development|headers sanitized for use in userspace" 61.206 + PROVIDE="linux-headers linux64-api-headers linux64-headers" 61.207 + ;; 61.208 + linux-uml) 61.209 + copy boot/ 61.210 + CAT="development|UML" 61.211 + DEPENDS=" " 61.212 + ;; 61.213 esac 61.214 }
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2 +++ b/linux-dev/stuff/menuconfig.in Wed Feb 21 19:48:17 2018 +0200 62.3 @@ -0,0 +1,4 @@ 62.4 +#!/bin/sh 62.5 +p=$PWD 62.6 +cd ../src/linux-@VERSION@-slitaz 62.7 +SRCARCH=x86 ARCH=@ARCH@ KERNELVERSION=@VERSION@ $p/mconf Kconfig
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/linux-dev/stuff/mini.config Wed Feb 21 19:48:17 2018 +0200 63.3 @@ -0,0 +1,51 @@ 63.4 +CONFIG_BINFMT_ELF=y 63.5 +CONFIG_LBD=y 63.6 +CONFIG_BLK_DEV=y 63.7 +CONFIG_BLK_DEV_LOOP=y 63.8 +CONFIG_STDERR_CONSOLE=y 63.9 +CONFIG_SSL=y 63.10 +CONFIG_UNIX98_PTYS=y 63.11 +CONFIG_PROC_FS=y 63.12 +CONFIG_SYSFS_FS=y 63.13 +CONFIG_IKCONFIG=y 63.14 +CONFIG_IKCONFIG_PROC=y 63.15 +CONFIG_UML_NET=y 63.16 +CONFIG_UML_NET_TUNTAP=y 63.17 +CONFIG_BLK_DEV_INITRD=y 63.18 +CONFIG_PTY_CHAN=y 63.19 +CONFIG_TTY_CHAN=y 63.20 +CONFIG_NET=y 63.21 +CONFIG_INET=y 63.22 +CONFIG_UML_NET=y 63.23 +CONFIG_UML_NET_TUNTAP=y 63.24 +CONFIG_BLK_DEV_UBD=y 63.25 +CONFIG_EXT4_FS=y 63.26 +CONFIG_EXT4_USE_FOR_EXT23=y 63.27 +CONFIG_EXT4_FS_XATTR=y 63.28 +CONFIG_EXT4_FS_POSIX_ACL=y 63.29 +CONFIG_FUSE_FS=y 63.30 +CONFIG_ISO9660_FS=y 63.31 +CONFIG_VFAT_FS=y 63.32 +CONFIG_TMPFS=y 63.33 +CONFIG_SWAP=y 63.34 +CONFIG_SYSVIPC=y 63.35 +CONFIG_SYSVIPC_SYSCTL=y 63.36 +CONFIG_SYSVIPC_COMPAT=y 63.37 +CONFIG_PACKET=y 63.38 +CONFIG_UNIX=y 63.39 +CONFIG_NETFILTER=y 63.40 +CONFIG_NETFILTER_ADVANCED=y 63.41 +CONFIG_NF_CONNTRACK=y 63.42 +CONFIG_NETFILTER_XTABLES=y 63.43 +CONFIG_NF_DEFRAG_IPV4=y 63.44 +CONFIG_NF_CONNTRACK_IPV4=y 63.45 +CONFIG_NF_CONNTRACK_PROC_COMPAT=y 63.46 +CONFIG_IP_NF_IPTABLES=y 63.47 +CONFIG_IP_NF_FILTER=y 63.48 +CONFIG_IP_NF_TARGET_REJECT=y 63.49 +CONFIG_NF_NAT=y 63.50 +CONFIG_NF_NAT_NEEDED=y 63.51 +CONFIG_IP_NF_TARGET_MASQUERADE=y 63.52 +CONFIG_IP_NF_TARGET_REDIRECT=y 63.53 +CONFIG_NETDEVICES=y 63.54 +CONFIG_TUN=y
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 64.2 +++ b/linux-dev/stuff/vm-uml.in Wed Feb 21 19:48:17 2018 +0200 64.3 @@ -0,0 +1,17 @@ 64.4 +#!/bin/sh 64.5 + 64.6 +# /etc/inittab: "tty21::respawn:/bin/su -c '/boot/vm-uml 1 /boot/guests/slitaz.img 2 512m' nobody" 64.7 +n=${1:-0} 64.8 +tap=tap$n 64.9 +args="rw root=/dev/null" 64.10 +dev="initrd=$(ls -r /boot/rootfs*.gz | sed q)" 64.11 +if [ -n "$2" ]; then 64.12 + args="ro root=620${3:-1} screen=text sound=noconf" 64.13 + dev="ubd0=$2" 64.14 +fi 64.15 + 64.16 +cd $(dirname $0) 64.17 +ifconfig $tap 192.168.$n.1 64.18 +./linux-uml-@VERSION@ $dev mem=${4:-512m} fakehd fake_ide ubd=3 con0=fd:0,fd:1 \ 64.19 + con=pts ssl=pts eth0=tuntap,$tap,fe:f0:00:00:00:0$n,192.168.$n.1 \ 64.20 + $args cpuinfo=$(sed '/model name/!d;s/.*: //;s/ /_/g;q' /proc/cpuinfo)
65.1 --- a/m4/receipt Wed Feb 21 18:10:55 2018 +0200 65.2 +++ b/m4/receipt Wed Feb 21 19:48:17 2018 +0200 65.3 @@ -7,22 +7,17 @@ 65.4 MAINTAINER="pankso@slitaz.org" 65.5 LICENSE="GPL3" 65.6 WEB_SITE="https://www.gnu.org/software/m4/m4.html" 65.7 -HOST_ARCH="i486 arm" 65.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/m4.html" 65.9 65.10 TARBALL="$PACKAGE-$VERSION.tar.gz" 65.11 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 65.12 65.13 -DEPENDS="glibc-base" 65.14 -BUILD_DEPENDS="" 65.15 - 65.16 -# Rules to configure and make the package. 65.17 -compile_rules() 65.18 -{ 65.19 +compile_rules() { 65.20 ./configure $CONFIGURE_ARGS && make && make install 65.21 } 65.22 65.23 -# Rules to gen a SliTaz package suitable for Tazpkg. 65.24 -genpkg_rules() 65.25 -{ 65.26 - copy m4 65.27 +genpkg_rules() { 65.28 + copy @std 65.29 + DEPENDS="glibc-base" 65.30 + TAGS="LFS" 65.31 }
66.1 --- a/make/receipt Wed Feb 21 18:10:55 2018 +0200 66.2 +++ b/make/receipt Wed Feb 21 19:48:17 2018 +0200 66.3 @@ -7,21 +7,18 @@ 66.4 MAINTAINER="pankso@slitaz.org" 66.5 LICENSE="GPL3" 66.6 WEB_SITE="https://www.gnu.org/software/make/" 66.7 -HOST_ARCH="i486 arm x86_64" 66.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/make.html" 66.9 66.10 TARBALL="$PACKAGE-$VERSION.tar.bz2" 66.11 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 66.12 66.13 BUILD_DEPENDS="gettext" 66.14 66.15 -# Rules to configure and make the package. 66.16 -compile_rules() 66.17 -{ 66.18 +compile_rules() { 66.19 ./configure $CONFIGURE_ARGS && make && make install 66.20 } 66.21 66.22 -# Rules to gen a SliTaz package suitable for Tazpkg. 66.23 -genpkg_rules() 66.24 -{ 66.25 +genpkg_rules() { 66.26 copy @std 66.27 + TAGS="LFS" 66.28 }
67.1 --- a/man-db/receipt Wed Feb 21 18:10:55 2018 +0200 67.2 +++ b/man-db/receipt Wed Feb 21 19:48:17 2018 +0200 67.3 @@ -7,6 +7,7 @@ 67.4 MAINTAINER="al.bobylev@gmail.com" 67.5 LICENSE="GPL2" 67.6 WEB_SITE="http://www.nongnu.org/man-db/" 67.7 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/man-db.html" 67.8 67.9 TARBALL="$PACKAGE-$VERSION.tar.xz" 67.10 WGET_URL="http://download.savannah.gnu.org/releases/man-db/$TARBALL" 67.11 @@ -15,11 +16,8 @@ 67.12 zlib-dev" 67.13 SPLIT="man-db-dev" 67.14 67.15 -# Rules to configure and make the package. 67.16 -compile_rules() 67.17 -{ 67.18 +compile_rules() { 67.19 ./configure \ 67.20 - --docdir=/usr/share/doc/$PACKAGE-$VERSION \ 67.21 --sysconfdir=/etc \ 67.22 --disable-setuid \ 67.23 --with-browser=/usr/bin/lynx \ 67.24 @@ -31,13 +29,12 @@ 67.25 sed -i "s:man root:root root:g" $install/usr/lib/tmpfiles.d/man-db.conf 67.26 } 67.27 67.28 -# Rules to gen a SliTaz package suitable for Tazpkg. 67.29 -genpkg_rules() 67.30 -{ 67.31 +genpkg_rules() { 67.32 case $PACKAGE in 67.33 man-db) 67.34 copy @std 67.35 DEPENDS="gdbm libpipeline zlib" 67.36 + TAGS="LFS" 67.37 ;; 67.38 *-dev) copy @dev;; 67.39 esac
68.1 --- a/man-pages/receipt Wed Feb 21 18:10:55 2018 +0200 68.2 +++ b/man-pages/receipt Wed Feb 21 19:48:17 2018 +0200 68.3 @@ -1,24 +1,22 @@ 68.4 # SliTaz package receipt v2. 68.5 68.6 PACKAGE="man-pages" 68.7 -VERSION="4.09" 68.8 +VERSION="$(. $WOK/linux/receipt; echo $KBASEVER)" 68.9 CATEGORY="doc" 68.10 SHORT_DESC="Linux manual pages" 68.11 MAINTAINER="al.bobylev@gmail.com" 68.12 LICENSE="unknown" 68.13 WEB_SITE="https://www.kernel.org/doc/man-pages/" 68.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/man-pages.html" 68.15 68.16 TARBALL="$PACKAGE-$VERSION.tar.xz" 68.17 WGET_URL="https://www.kernel.org/pub/linux/docs/man-pages/$TARBALL" 68.18 68.19 -# Rules to configure and make the package. 68.20 -compile_rules() 68.21 -{ 68.22 +compile_rules() { 68.23 make DESTDIR=$install install 68.24 } 68.25 68.26 -# Rules to gen a SliTaz package suitable for Tazpkg. 68.27 -genpkg_rules() 68.28 -{ 68.29 +genpkg_rules() { 68.30 copy man/ 68.31 + TAGS="LFS" 68.32 }
69.1 --- a/mpc-library/receipt Wed Feb 21 18:10:55 2018 +0200 69.2 +++ b/mpc-library/receipt Wed Feb 21 19:48:17 2018 +0200 69.3 @@ -7,7 +7,7 @@ 69.4 MAINTAINER="pankso@slitaz.org" 69.5 LICENSE="GPL2" 69.6 WEB_SITE="http://www.multiprecision.org/" 69.7 -HOST_ARCH="i486 arm" 69.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/mpc.html" 69.9 69.10 TARBALL="mpc-$VERSION.tar.gz" 69.11 WGET_URL="${WEB_SITE}mpc/download/$TARBALL" 69.12 @@ -15,22 +15,19 @@ 69.13 BUILD_DEPENDS="mpfr-dev gmp-dev texinfo" 69.14 SPLIT="mpc-library-dev" 69.15 69.16 -compile_rules() 69.17 -{ 69.18 +compile_rules() { 69.19 ./configure \ 69.20 --disable-static \ 69.21 - --docdir=/usr/share/doc/mpc-$VERSION \ 69.22 $CONFIGURE_ARGS && 69.23 make && make html && make install && make install-html 69.24 } 69.25 69.26 -# Rules to gen a SliTaz package suitable for Tazpkg. 69.27 -genpkg_rules() 69.28 -{ 69.29 +genpkg_rules() { 69.30 case $PACKAGE in 69.31 mpc-library) 69.32 copy @std 69.33 DEPENDS="mpfr gmp" 69.34 + TAGS="LFS" 69.35 ;; 69.36 *-dev) 69.37 copy @dev
70.1 --- a/mpfr/receipt Wed Feb 21 18:10:55 2018 +0200 70.2 +++ b/mpfr/receipt Wed Feb 21 19:48:17 2018 +0200 70.3 @@ -7,7 +7,7 @@ 70.4 MAINTAINER="pankso@slitaz.org" 70.5 LICENSE="GPL3" 70.6 WEB_SITE="http://www.mpfr.org/" 70.7 -HOST_ARCH="i486 arm" 70.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/mpfr.html" 70.9 70.10 TARBALL="$PACKAGE-$VERSION.tar.xz" 70.11 WGET_URL="http://www.mpfr.org/$PACKAGE-$VERSION/$TARBALL" 70.12 @@ -15,30 +15,31 @@ 70.13 BUILD_DEPENDS="gmp-dev texinfo" 70.14 SPLIT="mpfr-dev" 70.15 70.16 +compile_rules() { 70.17 #--with-gmp-lib=/cross/$ARCH/sysroot/usr/lib 70.18 #--with-gmp-include=/cross/$ARCH/sysroot/usr/include 70.19 70.20 -# Rules to configure and make the package. 70.21 -compile_rules() 70.22 -{ 70.23 ./configure \ 70.24 --disable-static \ 70.25 --enable-thread-safe \ 70.26 - --docdir=/usr/share/doc/mpfr-$VERSION \ 70.27 $CONFIGURE_ARGS && 70.28 make && make html && make install && make install-html 70.29 } 70.30 70.31 -testsuite() 70.32 -{ 70.33 - case "$ARCH" in i?86) make check;; esac 70.34 +testsuite() { 70.35 + case "$ARCH" in 70.36 + arm*) ;; 70.37 + *) make check;; 70.38 + esac 70.39 } 70.40 70.41 -# Rules to gen a SliTaz package suitable for Tazpkg. 70.42 -genpkg_rules() 70.43 -{ 70.44 +genpkg_rules() { 70.45 case $PACKAGE in 70.46 - mpfr) copy @std; DEPENDS="gmp";; 70.47 + mpfr) 70.48 + copy @std 70.49 + DEPENDS="gmp" 70.50 + TAGS="LFS" 70.51 + ;; 70.52 *-dev) copy @dev;; 70.53 esac 70.54 }
71.1 --- a/ncurses/receipt Wed Feb 21 18:10:55 2018 +0200 71.2 +++ b/ncurses/receipt Wed Feb 21 19:48:17 2018 +0200 71.3 @@ -7,19 +7,17 @@ 71.4 MAINTAINER="pankso@slitaz.org" 71.5 LICENSE="MIT" 71.6 WEB_SITE="https://www.gnu.org/software/ncurses/" 71.7 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/ncurses.html" 71.8 71.9 TARBALL="$PACKAGE-$VERSION.tar.gz" 71.10 WGET_URL="http://ftp.gnu.org/gnu/ncurses/$TARBALL" 71.11 -HOST_ARCH="i486 arm" 71.12 71.13 +BUILD_DEPENDS_arm=" " 71.14 BUILD_DEPENDS="flex" 71.15 -BUILD_DEPENDS_arm="" 71.16 SPLIT="ncurses-libform ncurses-libmenu ncurses-libpanel ncurses-extra \ 71.17 ncurses-dev" 71.18 71.19 -# Rules to configure and make the package. 71.20 -compile_rules() 71.21 -{ 71.22 +compile_rules() { 71.23 sed -i '/LIBTOOL_INSTALL/d' c++/Makefile.in 71.24 71.25 ./configure \ 71.26 @@ -61,14 +59,13 @@ 71.27 ln -s xterm-256color $install/usr/share/terminfo/x/xterm 71.28 } 71.29 71.30 -# Rules to gen a SliTaz package suitable for Tazpkg. 71.31 -genpkg_rules() 71.32 -{ 71.33 +genpkg_rules() { 71.34 case $PACKAGE in 71.35 ncurses) 71.36 copy clear tset reset libncursesw.so* tabset/ \ 71.37 linux xterm xterm-256color 71.38 # ansi rxvt vt100 vt102* xterm-color xterm-new xterm-vt220 71.39 + TAGS="LFS" 71.40 ;; 71.41 ncurses-libform) 71.42 copy libformw.so* 71.43 @@ -86,8 +83,7 @@ 71.44 DEPENDS="ncurses" 71.45 ;; 71.46 ncurses-extra) 71.47 - copy @std 71.48 - remove_already_packed 71.49 + copy @std @rm 71.50 CAT="base-system|extra files" 71.51 DEPENDS="ncurses" 71.52 ;;
72.1 --- a/patch/receipt Wed Feb 21 18:10:55 2018 +0200 72.2 +++ b/patch/receipt Wed Feb 21 19:48:17 2018 +0200 72.3 @@ -7,33 +7,19 @@ 72.4 MAINTAINER="pankso@slitaz.org" 72.5 LICENSE="GPL3" 72.6 WEB_SITE="http://savannah.gnu.org/projects/patch/" 72.7 -HOST_ARCH="i486 arm" 72.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/patch.html" 72.9 72.10 TARBALL="$PACKAGE-$VERSION.tar.xz" 72.11 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 72.12 72.13 BUILD_DEPENDS="attr-dev" 72.14 72.15 -# Rules to configure and make the package. 72.16 -compile_rules() 72.17 -{ 72.18 +compile_rules() { 72.19 ./configure $CONFIGURE_ARGS && make && make install 72.20 } 72.21 72.22 -# Rules to gen a SliTaz package suitable for Tazpkg. 72.23 -genpkg_rules() 72.24 -{ 72.25 - copy patch 72.26 +genpkg_rules() { 72.27 + copy @std 72.28 DEPENDS="attr" 72.29 + TAGS="LFS" 72.30 } 72.31 - 72.32 -## Prevent erasing busybox... 72.33 -#pre_install() 72.34 -#{ 72.35 -# rm -f "$1/usr/bin/patch" 72.36 -#} 72.37 -# 72.38 -#post_remove() 72.39 -#{ 72.40 -# ln -s /bin/busybox "$1/usr/bin/patch" 72.41 -#}
73.1 --- a/perl-xml-parser/receipt Wed Feb 21 18:10:55 2018 +0200 73.2 +++ b/perl-xml-parser/receipt Wed Feb 21 19:48:17 2018 +0200 73.3 @@ -7,25 +7,22 @@ 73.4 MAINTAINER="pankso@slitaz.org" 73.5 LICENSE="GPL" 73.6 WEB_SITE="https://metacpan.org/release/XML-Parser" 73.7 -HOST_ARCH="i486 arm" 73.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/xml-parser.html" 73.9 73.10 TARBALL="XML-Parser-$VERSION.tar.gz" 73.11 WGET_URL="https://cpan.metacpan.org/authors/id/T/TO/TODDR/$TARBALL" 73.12 73.13 -DEPENDS="perl-libwww-perl expat" 73.14 -BUILD_DEPENDS="$DEPENDS perl-dev expat-dev" 73.15 +BUILD_DEPENDS="perl-libwww-perl expat perl-dev expat-dev" 73.16 73.17 -# Rules to configure and make the package. 73.18 -compile_rules() 73.19 -{ 73.20 +compile_rules() { 73.21 perl Makefile.PL && 73.22 make && make DESTDIR=$install install && 73.23 73.24 chmod -R u+w $install 73.25 } 73.26 73.27 -# Rules to gen a SliTaz package suitable for Tazpkg. 73.28 -genpkg_rules() 73.29 -{ 73.30 +genpkg_rules() { 73.31 copy @std 73.32 + DEPENDS="perl-libwww-perl expat" 73.33 + TAGS="LFS" 73.34 }
74.1 --- a/perl/receipt Wed Feb 21 18:10:55 2018 +0200 74.2 +++ b/perl/receipt Wed Feb 21 19:48:17 2018 +0200 74.3 @@ -1,68 +1,91 @@ 74.4 # SliTaz package receipt v2. 74.5 74.6 PACKAGE="perl" 74.7 -VERSION="5.24.1" 74.8 +VERSION="5.26.1" 74.9 CATEGORY="development" 74.10 SHORT_DESC="Perl interpreter and modules" 74.11 MAINTAINER="pankso@slitaz.org" 74.12 LICENSE="GPL" 74.13 WEB_SITE="https://www.perl.org/" 74.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/perl.html" 74.15 74.16 TARBALL="$PACKAGE-$VERSION.tar.bz2" 74.17 WGET_URL="http://www.cpan.org/src/5.0/$TARBALL" 74.18 74.19 COOKOPTS="!perlz" 74.20 BUILD_DEPENDS="zlib-dev bzip2-dev less gdbm-dev" 74.21 -SPLIT="perl-core perl-dev" 74.22 -SIBLINGS="microperl perl-thread" 74.23 +#SPLIT="perl-core perl perl-dev microperl:micro" 74.24 +SPLIT="perl-core perl perl-dev" 74.25 +# microperl: waiting for 5.26.2: https://rt.perl.org/Public/Bug/Display.html?id=132255 74.26 +# sv.c:(.text+0x1aa95): undefined reference to `Perl_fp_class_denorm' 74.27 74.28 # Rules to compile & install the temporary toolchain. 74.29 -cook_tmp_toolchain() 74.30 -{ 74.31 +cook_tmp_toolchain() { 74.32 cd $src 74.33 - { sh Configure -des -Dprefix=/tools \ 74.34 + sh Configure -des \ 74.35 + -Dprefix=/tools \ 74.36 -Dstatic_ext='Data/Dumper Fcntl IO' && 74.37 - 74.38 + 74.39 # Only few tools are needed in the tmp toolchain. 74.40 - make perl utilities ext/Errno/pm_to_blib 74.41 - } || return 1 74.42 + make perl utilities ext/Errno/pm_to_blib || return 1 74.43 + 74.44 cp perl pod/pod2man /tools/bin 74.45 mkdir -p /tools/lib/perl5/$VERSION 74.46 cp -R lib/* /tools/lib/perl5/$VERSION 74.47 } 74.48 74.49 -# Rules to configure and make the package. 74.50 -compile_rules() 74.51 -{ 74.52 - export BUILD_ZLIB=False 74.53 - export BUILD_BZIP2=0 74.54 - sh Configure -des \ 74.55 - -Dprefix=/usr \ 74.56 - -Dvendorprefix=/usr \ 74.57 - -Dman1dir=/usr/share/man/man1 \ 74.58 - -Dman3dir=/usr/share/man/man3 \ 74.59 - -Dpager="/usr/bin/less -isR" \ 74.60 - -Duseshrplib && 74.61 - make && make install 74.62 +compile_rules() { 74.63 + case $SET in 74.64 + micro) 74.65 + patch -p1 -i $stuff/microperl.patch 74.66 + sed -i.orig "s|usr/local|usr|; 74.67 + s|perl5/${VERSION%.*}|perl5/$VERSION|; 74.68 + s|unknown|$HOST_SYSTEM|" uconfig.sh uconfig64.sh 74.69 + 74.70 + case $ARCH in 74.71 + x86_64) make -f Makefile.micro regen_uconfig64;; 74.72 + *) make -f Makefile.micro regen_uconfig;; 74.73 + esac && 74.74 + make -f Makefile.micro && 74.75 + install -Dm755 microperl $install/usr/bin/microperl 74.76 + ;; 74.77 + *) 74.78 + export BUILD_ZLIB=False 74.79 + export BUILD_BZIP2=0 74.80 + sh Configure -des \ 74.81 + -Dprefix=/usr \ 74.82 + -Dvendorprefix=/usr \ 74.83 + -Dman1dir=/usr/share/man/man1 \ 74.84 + -Dman3dir=/usr/share/man/man3 \ 74.85 + -Dpager="/usr/bin/less -isR" \ 74.86 + -Duseshrplib \ 74.87 + -Dusethreads && 74.88 + make && make install 74.89 + ;; 74.90 + esac 74.91 } 74.92 74.93 -# Rules to gen a SliTaz package suitable for Tazpkg. 74.94 -genpkg_rules() 74.95 -{ 74.96 +genpkg_rules() { 74.97 case $PACKAGE in 74.98 - perl) 74.99 - copy @std 74.100 - find $fs \( -name perl -o -name perl$VERSION -o -name libperl.so \) -delete 74.101 - DEPENDS="bzlib gdbm zlib perl-core" 74.102 - PROVIDE="microperl" 74.103 - ;; 74.104 perl-core) 74.105 - # perl binary depends on libperl.so 74.106 copy perl perl$VERSION libperl.so 74.107 DEPENDS="glibc-base" 74.108 CAT="development|minimal interpreter" 74.109 ;; 74.110 - *-dev) copy @dev;; 74.111 + perl) 74.112 + copy @std @rm 74.113 + DEPENDS="bzlib gdbm zlib perl-core" 74.114 + PROVIDE="microperl perl-thread" 74.115 + TAGS="LFS" 74.116 + ;; 74.117 + *-dev) 74.118 + copy @dev 74.119 + ;; 74.120 + microperl) 74.121 + copy @std 74.122 + CAT="development|micro version" 74.123 + DEPENDS="glibc-base" 74.124 + ;; 74.125 esac 74.126 } 74.127
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 75.2 +++ b/perl/stuff/microperl.patch Wed Feb 21 19:48:17 2018 +0200 75.3 @@ -0,0 +1,40 @@ 75.4 +--- a/Makefile.micro 75.5 ++++ b/Makefile.micro 75.6 +@@ -1,7 +1,7 @@ 75.7 + LD = $(CC) 75.8 + CCFLAGS = -c 75.9 + DEFINES = -DPERL_CORE -DPERL_MICRO -DSTANDARD_C -DPERL_USE_SAFE_PUTENV \ 75.10 +- -DNO_MATHOMS 75.11 ++ -DNO_MATHOMS -DUSE_PERLIO 75.12 + OPTIMIZE = 75.13 + CFLAGS = $(DEFINES) $(OPTIMIZE) 75.14 + LDFLAGS = 75.15 +@@ -14,7 +14,7 @@ 75.16 + 75.17 + all: microperl 75.18 + 75.19 +-O = uav$(_O) udeb$(_O) udoio$(_O) udoop$(_O) udquote$(_O) udump$(_O) \ 75.20 ++O = uav$(_O) ucaretx$(_O) udeb$(_O) udoio$(_O) udoop$(_O) udquote$(_O) udump$(_O) \ 75.21 + uglobals$(_O) ugv$(_O) uhv$(_O) umro$(_O)\ 75.22 + umg$(_O) uperlmain$(_O) uop$(_O) ureentr$(_O) \ 75.23 + upad$(_O) uperl$(_O) uperlio$(_O) uperly$(_O) upp$(_O) \ 75.24 +@@ -66,6 +66,9 @@ 75.25 + 75.26 + uav$(_O): $(HE) av.c 75.27 + $(CC) $(CCFLAGS) -o $@ $(CFLAGS) av.c 75.28 ++ 75.29 ++ucaretx$(_O): $(HE) caretx.c 75.30 ++ $(CC) $(CCFLAGS) -o $@ $(CFLAGS) caretx.c 75.31 + 75.32 + udeb$(_O): $(HE) deb.c 75.33 + $(CC) $(CCFLAGS) -o $@ $(CFLAGS) deb.c 75.34 +--- a/EXTERN.h 75.35 ++++ b/EXTERN.h 75.36 +@@ -57,3 +57,7 @@ 75.37 + #define INIT(x) 75.38 + 75.39 + #undef DOINIT 75.40 ++ 75.41 ++#define I_LIMITS 75.42 ++#define I_FCNTL 75.43 ++#define I_FLOAT
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 76.2 +++ b/perl/stuff/miniperlmain.patch Wed Feb 21 19:48:17 2018 +0200 76.3 @@ -0,0 +1,16 @@ 76.4 +--- miniperlmain.c.orig 76.5 ++++ miniperlmain.c 76.6 +@@ -117,13 +117,6 @@ 76.7 + if (!exitstatus) 76.8 + perl_run(my_perl); 76.9 + 76.10 +- /* Unregister our signal handler before destroying my_perl */ 76.11 +- for (i = 0; PL_sig_name[i]; i++) { 76.12 +- if (rsignal_state(PL_sig_num[i]) == (Sighandler_t) PL_csighandlerp) { 76.13 +- rsignal(PL_sig_num[i], (Sighandler_t) SIG_DFL); 76.14 +- } 76.15 +- } 76.16 +- 76.17 + exitstatus = perl_destruct(my_perl); 76.18 + 76.19 + perl_free(my_perl);
77.1 --- a/pkg-config/receipt Wed Feb 21 18:10:55 2018 +0200 77.2 +++ b/pkg-config/receipt Wed Feb 21 19:48:17 2018 +0200 77.3 @@ -1,23 +1,21 @@ 77.4 # SliTaz package receipt v2. 77.5 77.6 PACKAGE="pkg-config" 77.7 -VERSION="0.29.1" 77.8 +VERSION="0.29.2" 77.9 CATEGORY="development" 77.10 SHORT_DESC="Free desktop packages manager" 77.11 MAINTAINER="pankso@slitaz.org" 77.12 LICENSE="GPL2" 77.13 WEB_SITE="https://www.freedesktop.org/wiki/Software/pkg-config/" 77.14 -HOST_ARCH="i486 arm" 77.15 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/pkg-config.html" 77.16 77.17 TARBALL="$PACKAGE-$VERSION.tar.gz" 77.18 WGET_URL="https://pkg-config.freedesktop.org/releases/$TARBALL" 77.19 77.20 +BUILD_DEPENDS_arm=" " 77.21 BUILD_DEPENDS="gcc libtool perl" 77.22 -BUILD_DEPENDS_arm=" " 77.23 77.24 -# Rules to configure and make the package. 77.25 -compile_rules() 77.26 -{ 77.27 +compile_rules() { 77.28 case "$ARCH" in 77.29 arm) 77.30 ./configure \ 77.31 @@ -27,13 +25,9 @@ 77.32 --cache-file=arm-linux.cache ;; 77.33 *) 77.34 ./configure \ 77.35 - --prefix=/usr \ 77.36 --with-internal-glib \ 77.37 - --disable-compile-warnings \ 77.38 --disable-host-tool \ 77.39 - --docdir=/usr/share/doc/pkg-config-$VERSION \ 77.40 - --build=$HOST_SYSTEM \ 77.41 - --host=$HOST_SYSTEM 77.42 + $CONFIGURE_ARGS 77.43 ;; 77.44 esac && 77.45 make && make install 77.46 @@ -43,9 +37,8 @@ 77.47 ln -s ${TOOLPREFIX}pkg-config pkg-config 77.48 } 77.49 77.50 -# Rules to gen a SliTaz package suitable for Tazpkg. 77.51 -genpkg_rules() 77.52 -{ 77.53 +genpkg_rules() { 77.54 copy @std @dev 77.55 DEPENDS="glibc-base" 77.56 + TAGS="LFS" 77.57 }
78.1 --- a/procps-ng/receipt Wed Feb 21 18:10:55 2018 +0200 78.2 +++ b/procps-ng/receipt Wed Feb 21 19:48:17 2018 +0200 78.3 @@ -7,6 +7,7 @@ 78.4 MAINTAINER="al.bobylev@gmail.com" 78.5 LICENSE="GPL2 LGPL2" 78.6 WEB_SITE="https://gitlab.com/procps-ng/procps" 78.7 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/procps-ng.html" 78.8 78.9 TARBALL="$PACKAGE-$VERSION.tar.xz" 78.10 WGET_URL="$SF_MIRROR/$PACKAGE/$TARBALL" 78.11 @@ -14,17 +15,15 @@ 78.12 BUILD_DEPENDS="gettext ncurses-dev" 78.13 SPLIT="procps-ng-dev" 78.14 78.15 -# Rules to configure and make the package. 78.16 -compile_rules() 78.17 -{ 78.18 +compile_rules() { 78.19 +# --docdir=/usr/share/doc/procps-ng-$VERSION \ 78.20 ./configure \ 78.21 --exec-prefix= \ 78.22 --libdir=/usr/lib \ 78.23 - --docdir=/usr/share/doc/procps-ng-$VERSION \ 78.24 --disable-static \ 78.25 --disable-kill \ 78.26 $CONFIGURE_ARGS && 78.27 - make && make install 78.28 + make && make install || return 1 78.29 78.30 mkdir -p $install/lib 78.31 mv $install/usr/lib/libprocps.so.* $install/lib 78.32 @@ -32,13 +31,12 @@ 78.33 $install/usr/lib/libprocps.so 78.34 } 78.35 78.36 -# Rules to gen a SliTaz package suitable for Tazpkg. 78.37 -genpkg_rules() 78.38 -{ 78.39 +genpkg_rules() { 78.40 case $PACKAGE in 78.41 procps-ng) 78.42 copy @std 78.43 DEPENDS="gettext-base ncurses" 78.44 + TAGS="LFS" 78.45 ;; 78.46 *-dev) copy @dev;; 78.47 esac
79.1 --- a/psmisc/receipt Wed Feb 21 18:10:55 2018 +0200 79.2 +++ b/psmisc/receipt Wed Feb 21 19:48:17 2018 +0200 79.3 @@ -1,21 +1,20 @@ 79.4 # SliTaz package receipt v2. 79.5 79.6 PACKAGE="psmisc" 79.7 -VERSION="22.21" 79.8 +VERSION="23.1" 79.9 CATEGORY="system-tools" 79.10 SHORT_DESC="PSmisc - Small utilities that use the /proc filesystem" 79.11 MAINTAINER="al.bobylev@gmail.com" 79.12 LICENSE="GPL2" 79.13 WEB_SITE="http://psmisc.sourceforge.net/" 79.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/psmisc.html" 79.15 79.16 -TARBALL="$PACKAGE-$VERSION.tar.gz" 79.17 +TARBALL="$PACKAGE-$VERSION.tar.xz" 79.18 WGET_URL="$SF_MIRROR/psmisc/$TARBALL" 79.19 79.20 BUILD_DEPENDS="gettext ncurses-dev" 79.21 79.22 -# Rules to configure and make the package. 79.23 -compile_rules() 79.24 -{ 79.25 +compile_rules() { 79.26 ./configure $CONFIGURE_ARGS && make && make install 79.27 79.28 mkdir -p $install/bin 79.29 @@ -23,9 +22,8 @@ 79.30 mv $install/usr/bin/killall $install/bin 79.31 } 79.32 79.33 -# Rules to gen a SliTaz package suitable for Tazpkg. 79.34 -genpkg_rules() 79.35 -{ 79.36 +genpkg_rules() { 79.37 copy @std 79.38 DEPENDS="ncurses" 79.39 + TAGS="LFS" 79.40 }
80.1 --- a/readline/receipt Wed Feb 21 18:10:55 2018 +0200 80.2 +++ b/readline/receipt Wed Feb 21 19:48:17 2018 +0200 80.3 @@ -6,8 +6,8 @@ 80.4 SHORT_DESC="GNU readline" 80.5 MAINTAINER="pankso@slitaz.org" 80.6 LICENSE="GPL3" 80.7 -WEB_SITE="http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html" 80.8 -HOST_ARCH="i486 arm" 80.9 +WEB_SITE="https://www.gnu.org/software/readline" 80.10 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/readline.html" 80.11 80.12 TARBALL="$PACKAGE-$VERSION.tar.gz" 80.13 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 80.14 @@ -15,9 +15,7 @@ 80.15 BUILD_DEPENDS="ncurses-dev flex" 80.16 SPLIT="readline-dev" 80.17 80.18 -# Rules to configure and make the package. 80.19 -compile_rules() 80.20 -{ 80.21 +compile_rules() { 80.22 case "$ARCH" in 80.23 arm*) export bash_cv_wcwidth_broken=true ;; 80.24 esac 80.25 @@ -27,30 +25,31 @@ 80.26 80.27 ./configure \ 80.28 --disable-static \ 80.29 - --libdir=/lib \ 80.30 - --docdir=/usr/share/doc/readline-$VERSION \ 80.31 $CONFIGURE_ARGS && 80.32 - make SHLIB_LIBS=-lncurses && 80.33 - make DESTDIR=$install install 80.34 + make SHLIB_LIBS="-lncursesw" && 80.35 + make SHLIB_LIBS="-lncurses" DESTDIR=$install install || return 1 80.36 80.37 - # *.so.* -> /lib 80.38 - # *.so -> /usr/lib 80.39 - mkdir -p $install/usr/lib 80.40 - ln -sfv ../../lib/$(readlink $install/lib/libreadline.so) \ 80.41 - $install/usr/lib/libreadline.so 80.42 - ln -sfv ../../lib/$(readlink $install/lib/libhistory.so ) \ 80.43 - $install/usr/lib/libhistory.so 80.44 - rm $install/lib/*.so 80.45 + mkdir -p $install/lib 80.46 + for i in readline history; do 80.47 + mv -v $install/usr/lib/lib$i.so.* $install/lib 80.48 + ln -sf ../../lib/$(readlink $install/usr/lib/lib$i.so) \ 80.49 + $install/usr/lib/lib$i.so 80.50 + done 80.51 + 80.52 + find $install -type f -name '*.so*' -exec chmod 755 '{}' \; 80.53 + rmdir --ignore-fail-on-non-empty $install/usr/bin/ 80.54 80.55 # install the documentation 80.56 - cp doc/*.pdf doc/*.html $install/usr/share/doc/readline-7.0 80.57 + cook_pick_docs doc/*.pdf doc/*.html 80.58 } 80.59 80.60 -# Rules to gen a SliTaz package suitable for Tazpkg. 80.61 -genpkg_rules() 80.62 -{ 80.63 +genpkg_rules() { 80.64 case $PACKAGE in 80.65 - readline) copy @std; DEPENDS="ncurses";; 80.66 + readline) 80.67 + copy @std 80.68 + DEPENDS="ncurses" 80.69 + TAGS="LFS" 80.70 + ;; 80.71 *-dev) copy @dev;; 80.72 esac 80.73 }
81.1 --- a/sed/receipt Wed Feb 21 18:10:55 2018 +0200 81.2 +++ b/sed/receipt Wed Feb 21 19:48:17 2018 +0200 81.3 @@ -7,29 +7,27 @@ 81.4 MAINTAINER="paul@slitaz.org" 81.5 LICENSE="GPL3" 81.6 WEB_SITE="https://www.gnu.org/software/sed/" 81.7 -HOST_ARCH="i486 arm" 81.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/sed.html" 81.9 81.10 TARBALL="$PACKAGE-$VERSION.tar.xz" 81.11 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 81.12 81.13 BUILD_DEPENDS="acl-dev gettext texinfo" 81.14 81.15 -# Rules to configure and make the package. 81.16 -compile_rules() 81.17 -{ 81.18 +compile_rules() { 81.19 # Rebuild after patching 81.20 msgfmt po/ru.po -o po/ru.gmo 81.21 81.22 ./configure \ 81.23 --bindir=/bin \ 81.24 - --htmldir=/usr/share/doc/sed-$VERSION \ 81.25 $CONFIGURE_ARGS && 81.26 - make $MAKEFLAGS && make html && make install && make -C doc install-html 81.27 + make $MAKEFLAGS && make html && make install || return 1 81.28 + 81.29 + cook_pick_docs doc/sed.html 81.30 } 81.31 81.32 -# Rules to gen a SliTaz package suitable for Tazpkg. 81.33 -genpkg_rules() 81.34 -{ 81.35 +genpkg_rules() { 81.36 copy @std 81.37 DEPENDS="acl" 81.38 + TAGS="LFS" 81.39 }
82.1 --- a/shadow/receipt Wed Feb 21 18:10:55 2018 +0200 82.2 +++ b/shadow/receipt Wed Feb 21 19:48:17 2018 +0200 82.3 @@ -7,16 +7,21 @@ 82.4 MAINTAINER="al.bobylev@gmail.com" 82.5 LICENSE="BSD" 82.6 WEB_SITE="http://pkg-shadow.alioth.debian.org/" 82.7 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/shadow.html" 82.8 82.9 TARBALL="$PACKAGE-$VERSION.tar.xz" 82.10 WGET_URL="https://github.com/shadow-maint/shadow/releases/download/$VERSION/$TARBALL" 82.11 82.12 -DEPENDS="acl attr" 82.13 BUILD_DEPENDS="acl-dev attr-dev gettext" 82.14 82.15 -# Rules to configure and make the package. 82.16 -compile_rules() 82.17 -{ 82.18 +compile_rules() { 82.19 + # Disable the installation of the `groups` program and its man pages, as 82.20 + # Coreutils provides a better version. 82.21 + sed -i 's/groups$(EXEEXT) //' src/Makefile.in 82.22 + find man -name Makefile.in -exec sed -i 's/groups\.1 / /' {} \; 82.23 + find man -name Makefile.in -exec sed -i 's/getspnam\.3 / /' {} \; 82.24 + find man -name Makefile.in -exec sed -i 's/passwd\.5 / /' {} \; 82.25 + 82.26 sed -i -e 's|#ENCRYPT_METHOD DES|ENCRYPT_METHOD SHA512|' \ 82.27 -e 's|/var/spool/mail|/var/mail|' etc/login.defs 82.28 sed -i 's|bash|sh|' etc/useradd 82.29 @@ -29,8 +34,8 @@ 82.30 mv $install/usr/bin/passwd $install/bin 82.31 } 82.32 82.33 -# Rules to gen a SliTaz package suitable for Tazpkg. 82.34 -genpkg_rules() 82.35 -{ 82.36 +genpkg_rules() { 82.37 copy @std 82.38 + DEPENDS="acl attr" 82.39 + TAGS="LFS" 82.40 }
83.1 --- a/sysklogd/receipt Wed Feb 21 18:10:55 2018 +0200 83.2 +++ b/sysklogd/receipt Wed Feb 21 19:48:17 2018 +0200 83.3 @@ -7,13 +7,12 @@ 83.4 MAINTAINER="al.bobylev@gmail.com" 83.5 LICENSE="GPL2" 83.6 WEB_SITE="http://www.infodrom.org/projects/sysklogd/" 83.7 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/sysklogd.html" 83.8 83.9 TARBALL="$PACKAGE-$VERSION.tar.gz" 83.10 WGET_URL="${WEB_SITE}download/$TARBALL" 83.11 83.12 -# Rules to configure and make the package. 83.13 -compile_rules() 83.14 -{ 83.15 +compile_rules() { 83.16 sed -i '/Error loading kernel symbols/{n;n;d}' ksym_mod.c 83.17 sed -i 's/union wait/int/' syslogd.c 83.18 mkdir -p $install/sbin $install/usr/share/man/man5 $install/usr/share/man/man8 83.19 @@ -24,8 +23,7 @@ 83.20 cp $stuff/syslog.conf $install/etc 83.21 } 83.22 83.23 -# Rules to gen a SliTaz package suitable for Tazpkg. 83.24 -genpkg_rules() 83.25 -{ 83.26 +genpkg_rules() { 83.27 copy @std 83.28 + TAGS="LFS" 83.29 }
84.1 --- a/tar/receipt Wed Feb 21 18:10:55 2018 +0200 84.2 +++ b/tar/receipt Wed Feb 21 19:48:17 2018 +0200 84.3 @@ -7,16 +7,14 @@ 84.4 MAINTAINER="pankso@slitaz.org" 84.5 LICENSE="GPL3" 84.6 WEB_SITE="https://www.gnu.org/software/tar/" 84.7 -HOST_ARCH="i486 arm" 84.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/tar.html" 84.9 84.10 TARBALL="$PACKAGE-$VERSION.tar.bz2" 84.11 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 84.12 84.13 BUILD_DEPENDS="acl-dev gettext texinfo" 84.14 84.15 -# Rules to configure and make the package. 84.16 -compile_rules() 84.17 -{ 84.18 +compile_rules() { 84.19 FORCE_UNSAFE_CONFIGURE=1 \ 84.20 ./configure \ 84.21 --bindir=/bin \ 84.22 @@ -25,10 +23,8 @@ 84.23 make -C doc install-html docdir=/usr/share/doc/tar-$VERSION 84.24 } 84.25 84.26 -# Rules to gen a SliTaz package suitable for Tazpkg. 84.27 -genpkg_rules() 84.28 -{ 84.29 +genpkg_rules() { 84.30 copy @std 84.31 DEPENDS="acl attr" 84.32 - TAGS="archive compression" 84.33 + TAGS="LFS archive compression" 84.34 }
85.1 --- a/texinfo/receipt Wed Feb 21 18:10:55 2018 +0200 85.2 +++ b/texinfo/receipt Wed Feb 21 19:48:17 2018 +0200 85.3 @@ -1,31 +1,28 @@ 85.4 # SliTaz package receipt v2. 85.5 85.6 PACKAGE="texinfo" 85.7 -VERSION="6.3" 85.8 +VERSION="6.4" 85.9 CATEGORY="development" 85.10 SHORT_DESC="GNU documentation tools" 85.11 MAINTAINER="rcx@zoominternet.net" 85.12 LICENSE="GPL3" 85.13 WEB_SITE="https://www.gnu.org/software/texinfo/" 85.14 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/texinfo.html" 85.15 85.16 TARBALL="$PACKAGE-$VERSION.tar.xz" 85.17 WGET_URL="$GNU_MIRROR/$PACKAGE/$TARBALL" 85.18 85.19 BUILD_DEPENDS="perl-dev ncurses-dev gettext" 85.20 85.21 -# Rules to configure and make the package. 85.22 -compile_rules() 85.23 -{ 85.24 +compile_rules() { 85.25 ./configure \ 85.26 --disable-static \ 85.27 $CONFIGURE_ARGS && 85.28 make && make install 85.29 } 85.30 85.31 -# Rules to gen a SliTaz package suitable for Tazpkg. 85.32 -genpkg_rules() 85.33 -{ 85.34 +genpkg_rules() { 85.35 copy @std @dev 85.36 DEPENDS="perl" 85.37 - TAGS="documentation" 85.38 + TAGS="LFS documentation" 85.39 }
86.1 --- a/util-linux/receipt Wed Feb 21 18:10:55 2018 +0200 86.2 +++ b/util-linux/receipt Wed Feb 21 19:48:17 2018 +0200 86.3 @@ -1,13 +1,13 @@ 86.4 # SliTaz package receipt v2. 86.5 86.6 PACKAGE="util-linux" 86.7 -VERSION="2.30.0" 86.8 +VERSION="2.30.1" 86.9 CATEGORY="meta" 86.10 SHORT_DESC="Random collection of Linux utilities" 86.11 MAINTAINER="pankso@slitaz.org" 86.12 LICENSE="GPL2 LGPL2.1 BSD PublicDomain" 86.13 WEB_SITE="https://en.wikipedia.org/wiki/Util-linux" 86.14 -HOST_ARCH="i486 arm" 86.15 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/util-linux.html" 86.16 86.17 TARBALL="$PACKAGE-${VERSION%.0}.tar.xz" 86.18 WGET_URL="https://www.kernel.org/pub/linux/utils/util-linux/v${VERSION%.*}/$TARBALL" 86.19 @@ -23,9 +23,7 @@ 86.20 util-linux-sfdisk util-linux-smartcols util-linux-smartcols-dev \ 86.21 util-linux-uuid util-linux-uuid-dev util-linux-whereis util-linux-misc" 86.22 86.23 -# Rules to configure and make the package. 86.24 -compile_rules() 86.25 -{ 86.26 +compile_rules() { 86.27 # Fix undeclared 'LINE_MAX' 86.28 case "$ARCH" in 86.29 arm) sed -i s'|LINE_MAX|25|' text-utils/*.c ;; 86.30 @@ -44,9 +42,7 @@ 86.31 cp $stuff/cfdisk.desktop $install/usr/share/applications 86.32 } 86.33 86.34 -# Rules to gen a SliTaz package suitable for Tazpkg. 86.35 -genpkg_rules() 86.36 -{ 86.37 +genpkg_rules() { 86.38 case ${PACKAGE#util-linux-} in 86.39 bash-completion) 86.40 copy bash-completion/ 86.41 @@ -182,10 +178,12 @@ 86.42 DEPENDS="glibc-base" 86.43 ;; 86.44 misc) 86.45 - copy @std @dev 86.46 - remove_already_packed 86.47 + copy @std @dev @rm 86.48 CAT="system-tools|misc utilities" 86.49 ;; 86.50 + util-linux) 86.51 + TAGS="LFS" 86.52 + ;; 86.53 esac 86.54 86.55 if [ "$PACKAGE" != 'util-linux-bash-completion' -a -d "$fs/usr/share/bash-completion" ]; then
87.1 --- a/xz/receipt Wed Feb 21 18:10:55 2018 +0200 87.2 +++ b/xz/receipt Wed Feb 21 19:48:17 2018 +0200 87.3 @@ -7,8 +7,7 @@ 87.4 MAINTAINER="pascal.bellard@slitaz.org" 87.5 LICENSE="PublicDomain LGPL2.1 GPL2 GPL3" 87.6 WEB_SITE="https://tukaani.org/xz/" 87.7 -TAGS="compression archive" 87.8 -HOST_ARCH="i486 arm x86_64" 87.9 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/xz.html" 87.10 87.11 TARBALL="$PACKAGE-$VERSION.tar.xz" 87.12 WGET_URL="$WEB_SITE$TARBALL" 87.13 @@ -16,15 +15,12 @@ 87.14 BUILD_DEPENDS="gettext" 87.15 SPLIT="xz-tools xz liblzma xz-dev" 87.16 87.17 -# Rules to configure and make the package. 87.18 -compile_rules() 87.19 -{ 87.20 +compile_rules() { 87.21 ./configure \ 87.22 --disable-static \ 87.23 - --docdir=/usr/share/doc/xz-$VERSION \ 87.24 --enable-small \ 87.25 $CONFIGURE_ARGS && 87.26 - make && make install 87.27 + make && make install || return 1 87.28 87.29 mkdir -p $install/bin $install/lib 87.30 for i in lzma unlzma lzcat xz unxz xzcat; do 87.31 @@ -35,9 +31,7 @@ 87.32 $install/usr/lib/liblzma.so 87.33 } 87.34 87.35 -# Rules to gen a SliTaz package suitable for Tazpkg. 87.36 -genpkg_rules() 87.37 -{ 87.38 +genpkg_rules() { 87.39 case $PACKAGE in 87.40 xz-tools) 87.41 copy /usr/bin/ 87.42 @@ -45,9 +39,9 @@ 87.43 DEPENDS="liblzma" 87.44 ;; 87.45 xz) 87.46 - copy bin/ 87.47 - remove_already_packed 87.48 + copy bin/ @rm 87.49 DEPENDS="liblzma" 87.50 + TAGS="LFS compression archive" 87.51 ;; 87.52 liblzma) 87.53 copy liblzma.so*
88.1 --- a/zlib/receipt Wed Feb 21 18:10:55 2018 +0200 88.2 +++ b/zlib/receipt Wed Feb 21 19:48:17 2018 +0200 88.3 @@ -7,19 +7,17 @@ 88.4 MAINTAINER="pankso@slitaz.org" 88.5 LICENSE="zlib/libpng" 88.6 WEB_SITE="http://www.zlib.net/" 88.7 -HOST_ARCH="i486 arm x86_64" 88.8 +LFS="http://www.linuxfromscratch.org/lfs/view/stable/chapter06/zlib.html" 88.9 88.10 TARBALL="$PACKAGE-$VERSION.tar.xz" 88.11 WGET_URL="$WEB_SITE$TARBALL" 88.12 88.13 SPLIT="zlib-dev" 88.14 88.15 -# Rules to configure and make the package. 88.16 -compile_rules() 88.17 -{ 88.18 +compile_rules() { 88.19 ./configure \ 88.20 --prefix=/usr && 88.21 - make && make install 88.22 + make && make install || return 1 88.23 88.24 mkdir -p $install/lib 88.25 mv -v $install/usr/lib/libz.so.* $install/lib 88.26 @@ -28,17 +26,13 @@ 88.27 } 88.28 88.29 # Important cross compiled package so run readelf. 88.30 -testsuite() 88.31 -{ 88.32 - cd $install 88.33 - readelf -h lib/*.so.$VERSION 88.34 +testsuite() { 88.35 + readelf -h $install/lib/libz.so.$VERSION 88.36 } 88.37 88.38 -# Rules to gen a SliTaz package suitable for Tazpkg. 88.39 -genpkg_rules() 88.40 -{ 88.41 +genpkg_rules() { 88.42 case $PACKAGE in 88.43 - zlib) copy @std ;; 88.44 - zlib-dev) copy @dev ;; 88.45 + zlib) copy @std; TAGS="LFS";; 88.46 + *-dev) copy @dev;; 88.47 esac 88.48 }