diff --git a/.gitignore b/.gitignore index de62e8f..6f14d2e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /coreutils-[0-9.]*.tar.xz +/coreutils-ss.tar.xz diff --git a/coreutils-4.5.3-langinfo.patch b/coreutils-4.5.3-langinfo.patch deleted file mode 100644 index a8af3bd..0000000 --- a/coreutils-4.5.3-langinfo.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/src/date.c b/src/date.c -index ddb011e..619a72b 100644 ---- a/src/date.c -+++ b/src/date.c -@@ -490,14 +490,7 @@ main (int argc, char **argv) - format = DATE_FMT_LANGINFO (); - if (! *format) - { -- /* Do not wrap the following literal format string with _(...). -- For example, suppose LC_ALL is unset, LC_TIME=POSIX, -- and LANG="ko_KR". In that case, POSIX says that LC_TIME -- determines the format and contents of date and time strings -- written by date, which means "date" must generate output -- using the POSIX locale; but adding _() would cause "date" -- to use a Korean translation of the format. */ -- format = "%a %b %e %H:%M:%S %Z %Y"; -+ format = dcgettext(NULL, N_("%a %b %e %H:%M:%S %Z %Y"), LC_TIME); - } - } - diff --git a/coreutils-8.2-uname-processortype.patch b/coreutils-8.2-uname-processortype.patch index ed01ab8..44c57f5 100644 --- a/coreutils-8.2-uname-processortype.patch +++ b/coreutils-8.2-uname-processortype.patch @@ -1,29 +1,24 @@ + src/uname.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + diff --git a/src/uname.c b/src/uname.c index 6371ca2..1ad8fd7 100644 --- a/src/uname.c +++ b/src/uname.c -@@ -300,13 +300,19 @@ main (int argc, char **argv) - - if (toprint & PRINT_PROCESSOR) - { -- char const *element = unknown; -+ char *element = unknown; - #if HAVE_SYSINFO && defined SI_ARCHITECTURE - { - static char processor[257]; - if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) - element = processor; - } +@@ -322,6 +322,12 @@ main (int argc, char **argv) + # elif defined __ppc__ || defined __ppc64__ + element = "powerpc"; + # endif +#else + { -+ static struct utsname u; -+ uname(&u); -+ element = u.machine; ++ static struct utsname u; ++ uname(&u); ++ element = u.machine; + } #endif - #ifdef UNAME_PROCESSOR + #if HAVE_SYSINFO && defined SI_ARCHITECTURE if (element == unknown) -@@ -344,7 +350,7 @@ main (int argc, char **argv) +@@ -347,7 +353,7 @@ main (int argc, char **argv) if (toprint & PRINT_HARDWARE_PLATFORM) { @@ -32,17 +27,17 @@ index 6371ca2..1ad8fd7 100644 #if HAVE_SYSINFO && defined SI_PLATFORM { static char hardware_platform[257]; -@@ -352,6 +358,14 @@ main (int argc, char **argv) +@@ -355,6 +361,14 @@ main (int argc, char **argv) hardware_platform, sizeof hardware_platform)) element = hardware_platform; } +#else + { -+ static struct utsname u; -+ uname(&u); -+ element = u.machine; -+ if(strlen(element)==4 && element[0]=='i' && element[2]=='8' && element[3]=='6') -+ element[1]='3'; ++ static struct utsname u; ++ uname(&u); ++ element = u.machine; ++ if(strlen(element)==4 && element[0]=='i' && element[2]=='8' && element[3]=='6') ++ element[1]='3'; + } #endif #ifdef UNAME_HARDWARE_PLATFORM diff --git a/coreutils-8.25-DIR_COLORS.patch b/coreutils-8.25-DIR_COLORS.patch deleted file mode 100644 index 26acdf9..0000000 --- a/coreutils-8.25-DIR_COLORS.patch +++ /dev/null @@ -1,683 +0,0 @@ -From a13bc34f1eeebdf8b87e4b5a570341bb77a62f76 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Fri, 17 Jun 2016 16:58:18 +0200 -Subject: [PATCH] downstream changes to default DIR_COLORS - ---- - DIR_COLORS | 41 ++++--- - DIR_COLORS.256color | 300 ++++++++++++++++++++++++------------------------ - DIR_COLORS.lightbgcolor | 211 ++++++++++++++++++---------------- - 3 files changed, 283 insertions(+), 269 deletions(-) - -diff --git a/DIR_COLORS b/DIR_COLORS -index d2ea453..27af9d7 100644 ---- a/DIR_COLORS -+++ b/DIR_COLORS -@@ -1,3 +1,7 @@ -+# This file goes in the /etc directory, and must be world readable. -+# You can copy this file to .dir_colors in your $HOME directory to override -+# the system defaults. -+ - # Configuration file for dircolors, a utility to help you set the - # LS_COLORS environment variable used by GNU ls with the --color option. - -@@ -8,6 +12,9 @@ - # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the - # slackware version of dircolors) are recognized but ignored. - -+# For compatibility, the pattern "^COLOR.*none" is recognized as a way to -+# disable colorization. See https://bugzilla.redhat.com/1349579 for details. -+ - # Below are TERM entries, which can be a glob patterns, to match - # against the TERM environment variable to determine if it is colorizable. - TERM Eterm -@@ -58,7 +65,7 @@ DOOR 01;35 # door - BLK 40;33;01 # block device driver - CHR 40;33;01 # character device driver - ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... --MISSING 00 # ... and the files they point to -+MISSING 01;37;41 # ... and the files they point to - SETUID 37;41 # file that is setuid (u+s) - SETGID 30;43 # file that is setgid (g+s) - CAPABILITY 30;41 # file with capability -@@ -186,21 +193,21 @@ EXEC 01;32 - .ogx 01;35 - - # audio formats --.aac 00;36 --.au 00;36 --.flac 00;36 --.m4a 00;36 --.mid 00;36 --.midi 00;36 --.mka 00;36 --.mp3 00;36 --.mpc 00;36 --.ogg 00;36 --.ra 00;36 --.wav 00;36 -+.aac 01;36 -+.au 01;36 -+.flac 01;36 -+.m4a 01;36 -+.mid 01;36 -+.midi 01;36 -+.mka 01;36 -+.mp3 01;36 -+.mpc 01;36 -+.ogg 01;36 -+.ra 01;36 -+.wav 01;36 - - # https://wiki.xiph.org/MIME_Types_and_File_Extensions --.oga 00;36 --.opus 00;36 --.spx 00;36 --.xspf 00;36 -+.oga 01;36 -+.opus 01;36 -+.spx 01;36 -+.xspf 01;36 -diff --git a/DIR_COLORS.256color b/DIR_COLORS.256color -index d2ea453..74c34ba 100644 ---- a/DIR_COLORS.256color -+++ b/DIR_COLORS.256color -@@ -1,3 +1,9 @@ -+# Configuration file for the 256color ls utility -+ -+# This file goes in the /etc directory, and must be world readable. -+# You can copy this file to .dir_colors in your $HOME directory to override -+# the system defaults. -+ - # Configuration file for dircolors, a utility to help you set the - # LS_COLORS environment variable used by GNU ls with the --color option. - -@@ -8,32 +14,13 @@ - # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the - # slackware version of dircolors) are recognized but ignored. - -+# For compatibility, the pattern "^COLOR.*none" is recognized as a way to -+# disable colorization. See https://bugzilla.redhat.com/1349579 for details. -+ - # Below are TERM entries, which can be a glob patterns, to match - # against the TERM environment variable to determine if it is colorizable. --TERM Eterm --TERM ansi --TERM *color* --TERM con[0-9]*x[0-9]* --TERM cons25 --TERM console --TERM cygwin --TERM dtterm --TERM gnome --TERM hurd --TERM jfbterm --TERM konsole --TERM kterm --TERM linux --TERM linux-c --TERM mlterm --TERM putty --TERM rxvt* --TERM screen* --TERM st --TERM terminator --TERM tmux* --TERM vt100 --TERM xterm* -+TERM *256color* -+TERM rxvt-unicode256 - - # Below are the color init strings for the basic file types. - # One can use codes for 256 or more colors supported by modern terminals. -@@ -45,29 +32,40 @@ TERM xterm* - # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white - # Background color codes: - # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white -+# Text color(256 colors mode) codes: -+# Valid syntax for text 256color is 38;5; , where color number -+# is number between 0 and 255. -+# You may find following command useful to search the best one for you: -+# for ((x=0; x<=255; x++));do echo -e "${x}:\033[38;5;${x}mcolor\033[000m";done -+# Background color(256 colors mode) codes: -+# Valid syntax for background 256color is 48;5; , where -+# color number is number between 0 and 255. -+# You may find following command useful to search the best one for you: -+# for ((x=0; x<=255; x++));do echo -e "${x}:\033[48;5;${x}mcolor\033[000m";done -+ - #NORMAL 00 # no color code at all - #FILE 00 # regular file: use no color at all - RESET 0 # reset to "normal" color --DIR 01;34 # directory --LINK 01;36 # symbolic link. (If you set this to 'target' instead of a -+DIR 38;5;33 # directory -+LINK 38;5;51 # symbolic link. (If you set this to 'target' instead of a - # numerical value, the color is as for the file pointed to.) - MULTIHARDLINK 00 # regular file with more than one link --FIFO 40;33 # pipe --SOCK 01;35 # socket --DOOR 01;35 # door --BLK 40;33;01 # block device driver --CHR 40;33;01 # character device driver --ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... --MISSING 00 # ... and the files they point to --SETUID 37;41 # file that is setuid (u+s) --SETGID 30;43 # file that is setgid (g+s) --CAPABILITY 30;41 # file with capability --STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) --OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky --STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable -+FIFO 40;38;5;11 # pipe -+SOCK 38;5;13 # socket -+DOOR 38;5;5 # door -+BLK 48;5;232;38;5;11 # block device driver -+CHR 48;5;232;38;5;3 # character device driver -+ORPHAN 48;5;232;38;5;9 # symlink to nonexistent file, or non-stat'able file ... -+MISSING 01;37;41 # ... and the files they point to -+SETUID 48;5;196;38;5;15 # file that is setuid (u+s) -+SETGID 48;5;11;38;5;16 # file that is setgid (g+s) -+CAPABILITY 48;5;196;38;5;226 # file with capability -+STICKY_OTHER_WRITABLE 48;5;10;38;5;16 # dir that is sticky and other-writable (+t,o+w) -+OTHER_WRITABLE 48;5;10;38;5;21 # dir that is other-writable (o+w) and not sticky -+STICKY 48;5;21;38;5;15 # dir with the sticky bit set (+t) and not other-writable - - # This is for files with execute permission: --EXEC 01;32 -+EXEC 38;5;40 - - # List any file extensions like '.gz' or '.tar' that you would like ls - # to colorize below. Put the extension, a space, and the color init string. -@@ -85,122 +83,122 @@ EXEC 01;32 - #.csh 01;32 - - # archives or compressed (bright red) --.tar 01;31 --.tgz 01;31 --.arc 01;31 --.arj 01;31 --.taz 01;31 --.lha 01;31 --.lz4 01;31 --.lzh 01;31 --.lzma 01;31 --.tlz 01;31 --.txz 01;31 --.tzo 01;31 --.t7z 01;31 --.zip 01;31 --.z 01;31 --.dz 01;31 --.gz 01;31 --.lrz 01;31 --.lz 01;31 --.lzo 01;31 --.xz 01;31 --.zst 01;31 --.tzst 01;31 --.bz2 01;31 --.bz 01;31 --.tbz 01;31 --.tbz2 01;31 --.tz 01;31 --.deb 01;31 --.rpm 01;31 --.jar 01;31 --.war 01;31 --.ear 01;31 --.sar 01;31 --.rar 01;31 --.alz 01;31 --.ace 01;31 --.zoo 01;31 --.cpio 01;31 --.7z 01;31 --.rz 01;31 --.cab 01;31 --.wim 01;31 --.swm 01;31 --.dwm 01;31 --.esd 01;31 -+.tar 38;5;9 -+.tgz 38;5;9 -+.arc 38;5;9 -+.arj 38;5;9 -+.taz 38;5;9 -+.lha 38;5;9 -+.lz4 38;5;9 -+.lzh 38;5;9 -+.lzma 38;5;9 -+.tlz 38;5;9 -+.txz 38;5;9 -+.tzo 38;5;9 -+.t7z 38;5;9 -+.zip 38;5;9 -+.z 38;5;9 -+.dz 38;5;9 -+.gz 38;5;9 -+.lrz 38;5;9 -+.lz 38;5;9 -+.lzo 38;5;9 -+.xz 38;5;9 -+.zst 38;5;9 -+.tzst 38;5;9 -+.bz2 38;5;9 -+.bz 38;5;9 -+.tbz 38;5;9 -+.tbz2 38;5;9 -+.tz 38;5;9 -+.deb 38;5;9 -+.rpm 38;5;9 -+.jar 38;5;9 -+.war 38;5;9 -+.ear 38;5;9 -+.sar 38;5;9 -+.rar 38;5;9 -+.alz 38;5;9 -+.ace 38;5;9 -+.zoo 38;5;9 -+.cpio 38;5;9 -+.7z 38;5;9 -+.rz 38;5;9 -+.cab 38;5;9 -+.wim 38;5;9 -+.swm 38;5;9 -+.dwm 38;5;9 -+.esd 38;5;9 - - # image formats --.jpg 01;35 --.jpeg 01;35 --.mjpg 01;35 --.mjpeg 01;35 --.gif 01;35 --.bmp 01;35 --.pbm 01;35 --.pgm 01;35 --.ppm 01;35 --.tga 01;35 --.xbm 01;35 --.xpm 01;35 --.tif 01;35 --.tiff 01;35 --.png 01;35 --.svg 01;35 --.svgz 01;35 --.mng 01;35 --.pcx 01;35 --.mov 01;35 --.mpg 01;35 --.mpeg 01;35 --.m2v 01;35 --.mkv 01;35 --.webm 01;35 --.ogm 01;35 --.mp4 01;35 --.m4v 01;35 --.mp4v 01;35 --.vob 01;35 --.qt 01;35 --.nuv 01;35 --.wmv 01;35 --.asf 01;35 --.rm 01;35 --.rmvb 01;35 --.flc 01;35 --.avi 01;35 --.fli 01;35 --.flv 01;35 --.gl 01;35 --.dl 01;35 --.xcf 01;35 --.xwd 01;35 --.yuv 01;35 --.cgm 01;35 --.emf 01;35 -+.jpg 38;5;13 -+.jpeg 38;5;13 -+.mjpg 38;5;13 -+.mjpeg 38;5;13 -+.gif 38;5;13 -+.bmp 38;5;13 -+.pbm 38;5;13 -+.pgm 38;5;13 -+.ppm 38;5;13 -+.tga 38;5;13 -+.xbm 38;5;13 -+.xpm 38;5;13 -+.tif 38;5;13 -+.tiff 38;5;13 -+.png 38;5;13 -+.svg 38;5;13 -+.svgz 38;5;13 -+.mng 38;5;13 -+.pcx 38;5;13 -+.mov 38;5;13 -+.mpg 38;5;13 -+.mpeg 38;5;13 -+.m2v 38;5;13 -+.mkv 38;5;13 -+.webm 38;5;13 -+.ogm 38;5;13 -+.mp4 38;5;13 -+.m4v 38;5;13 -+.mp4v 38;5;13 -+.vob 38;5;13 -+.qt 38;5;13 -+.nuv 38;5;13 -+.wmv 38;5;13 -+.asf 38;5;13 -+.rm 38;5;13 -+.rmvb 38;5;13 -+.flc 38;5;13 -+.avi 38;5;13 -+.fli 38;5;13 -+.flv 38;5;13 -+.gl 38;5;13 -+.dl 38;5;13 -+.xcf 38;5;13 -+.xwd 38;5;13 -+.yuv 38;5;13 -+.cgm 38;5;13 -+.emf 38;5;13 - - # https://wiki.xiph.org/MIME_Types_and_File_Extensions --.ogv 01;35 --.ogx 01;35 -+.ogv 38;5;13 -+.ogx 38;5;13 - - # audio formats --.aac 00;36 --.au 00;36 --.flac 00;36 --.m4a 00;36 --.mid 00;36 --.midi 00;36 --.mka 00;36 --.mp3 00;36 --.mpc 00;36 --.ogg 00;36 --.ra 00;36 --.wav 00;36 -+.aac 38;5;45 -+.au 38;5;45 -+.flac 38;5;45 -+.m4a 38;5;45 -+.mid 38;5;45 -+.midi 38;5;45 -+.mka 38;5;45 -+.mp3 38;5;45 -+.mpc 38;5;45 -+.ogg 38;5;45 -+.ra 38;5;45 -+.wav 38;5;45 - - # https://wiki.xiph.org/MIME_Types_and_File_Extensions --.oga 00;36 --.opus 00;36 --.spx 00;36 --.xspf 00;36 -+.oga 38;5;45 -+.opus 38;5;45 -+.spx 38;5;45 -+.xspf 38;5;45 -diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor -index d2ea453..95d6879 100644 ---- a/DIR_COLORS.lightbgcolor -+++ b/DIR_COLORS.lightbgcolor -@@ -1,3 +1,9 @@ -+# Configuration file for the color ls utility - modified for lighter backgrounds -+ -+# This file goes in the /etc directory, and must be world readable. -+# You can copy this file to .dir_colors in your $HOME directory to override -+# the system defaults. -+ - # Configuration file for dircolors, a utility to help you set the - # LS_COLORS environment variable used by GNU ls with the --color option. - -@@ -8,6 +14,9 @@ - # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the - # slackware version of dircolors) are recognized but ignored. - -+# For compatibility, the pattern "^COLOR.*none" is recognized as a way to -+# disable colorization. See https://bugzilla.redhat.com/1349579 for details. -+ - # Below are TERM entries, which can be a glob patterns, to match - # against the TERM environment variable to determine if it is colorizable. - TERM Eterm -@@ -48,17 +57,17 @@ TERM xterm* - #NORMAL 00 # no color code at all - #FILE 00 # regular file: use no color at all - RESET 0 # reset to "normal" color --DIR 01;34 # directory --LINK 01;36 # symbolic link. (If you set this to 'target' instead of a -+DIR 00;34 # directory -+LINK 00;36 # symbolic link. (If you set this to 'target' instead of a - # numerical value, the color is as for the file pointed to.) - MULTIHARDLINK 00 # regular file with more than one link - FIFO 40;33 # pipe --SOCK 01;35 # socket --DOOR 01;35 # door -+SOCK 00;35 # socket -+DOOR 00;35 # door - BLK 40;33;01 # block device driver - CHR 40;33;01 # character device driver - ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... --MISSING 00 # ... and the files they point to -+MISSING 01;37;41 # ... and the files they point to - SETUID 37;41 # file that is setuid (u+s) - SETGID 30;43 # file that is setgid (g+s) - CAPABILITY 30;41 # file with capability -@@ -67,7 +76,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky - STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable - - # This is for files with execute permission: --EXEC 01;32 -+EXEC 00;32 - - # List any file extensions like '.gz' or '.tar' that you would like ls - # to colorize below. Put the extension, a space, and the color init string. -@@ -85,105 +94,105 @@ EXEC 01;32 - #.csh 01;32 - - # archives or compressed (bright red) --.tar 01;31 --.tgz 01;31 --.arc 01;31 --.arj 01;31 --.taz 01;31 --.lha 01;31 --.lz4 01;31 --.lzh 01;31 --.lzma 01;31 --.tlz 01;31 --.txz 01;31 --.tzo 01;31 --.t7z 01;31 --.zip 01;31 --.z 01;31 --.dz 01;31 --.gz 01;31 --.lrz 01;31 --.lz 01;31 --.lzo 01;31 --.xz 01;31 --.zst 01;31 --.tzst 01;31 --.bz2 01;31 --.bz 01;31 --.tbz 01;31 --.tbz2 01;31 --.tz 01;31 --.deb 01;31 --.rpm 01;31 --.jar 01;31 --.war 01;31 --.ear 01;31 --.sar 01;31 --.rar 01;31 --.alz 01;31 --.ace 01;31 --.zoo 01;31 --.cpio 01;31 --.7z 01;31 --.rz 01;31 --.cab 01;31 --.wim 01;31 --.swm 01;31 --.dwm 01;31 --.esd 01;31 -+.tar 00;31 -+.tgz 00;31 -+.arc 00;31 -+.arj 00;31 -+.taz 00;31 -+.lha 00;31 -+.lz4 00;31 -+.lzh 00;31 -+.lzma 00;31 -+.tlz 00;31 -+.txz 00;31 -+.tzo 00;31 -+.t7z 00;31 -+.zip 00;31 -+.z 00;31 -+.dz 00;31 -+.gz 00;31 -+.lrz 00;31 -+.lz 00;31 -+.lzo 00;31 -+.xz 00;31 -+.zst 00;31 -+.tzst 00;31 -+.bz2 00;31 -+.bz 00;31 -+.tbz 00;31 -+.tbz2 00;31 -+.tz 00;31 -+.deb 00;31 -+.rpm 00;31 -+.jar 00;31 -+.war 00;31 -+.ear 00;31 -+.sar 00;31 -+.rar 00;31 -+.alz 00;31 -+.ace 00;31 -+.zoo 00;31 -+.cpio 00;31 -+.7z 00;31 -+.rz 00;31 -+.cab 00;31 -+.wim 00;31 -+.swm 00;31 -+.dwm 00;31 -+.esd 00;31 - - # image formats --.jpg 01;35 --.jpeg 01;35 --.mjpg 01;35 --.mjpeg 01;35 --.gif 01;35 --.bmp 01;35 --.pbm 01;35 --.pgm 01;35 --.ppm 01;35 --.tga 01;35 --.xbm 01;35 --.xpm 01;35 --.tif 01;35 --.tiff 01;35 --.png 01;35 --.svg 01;35 --.svgz 01;35 --.mng 01;35 --.pcx 01;35 --.mov 01;35 --.mpg 01;35 --.mpeg 01;35 --.m2v 01;35 --.mkv 01;35 --.webm 01;35 --.ogm 01;35 --.mp4 01;35 --.m4v 01;35 --.mp4v 01;35 --.vob 01;35 --.qt 01;35 --.nuv 01;35 --.wmv 01;35 --.asf 01;35 --.rm 01;35 --.rmvb 01;35 --.flc 01;35 --.avi 01;35 --.fli 01;35 --.flv 01;35 --.gl 01;35 --.dl 01;35 --.xcf 01;35 --.xwd 01;35 --.yuv 01;35 --.cgm 01;35 --.emf 01;35 -+.jpg 00;35 -+.jpeg 00;35 -+.mjpg 00;35 -+.mjpeg 00;35 -+.gif 00;35 -+.bmp 00;35 -+.pbm 00;35 -+.pgm 00;35 -+.ppm 00;35 -+.tga 00;35 -+.xbm 00;35 -+.xpm 00;35 -+.tif 00;35 -+.tiff 00;35 -+.png 00;35 -+.svg 00;35 -+.svgz 00;35 -+.mng 00;35 -+.pcx 00;35 -+.mov 00;35 -+.mpg 00;35 -+.mpeg 00;35 -+.m2v 00;35 -+.mkv 00;35 -+.webm 00;35 -+.ogm 00;35 -+.mp4 00;35 -+.m4v 00;35 -+.mp4v 00;35 -+.vob 00;35 -+.qt 00;35 -+.nuv 00;35 -+.wmv 00;35 -+.asf 00;35 -+.rm 00;35 -+.rmvb 00;35 -+.flc 00;35 -+.avi 00;35 -+.fli 00;35 -+.flv 00;35 -+.gl 00;35 -+.dl 00;35 -+.xcf 00;35 -+.xwd 00;35 -+.yuv 00;35 -+.cgm 00;35 -+.emf 00;35 - - # https://wiki.xiph.org/MIME_Types_and_File_Extensions --.ogv 01;35 --.ogx 01;35 -+.ogv 00;35 -+.ogx 00;35 - - # audio formats - .aac 00;36 --- -2.5.5 - diff --git a/coreutils-8.31-improve-test-cp-proc-short-read.patch b/coreutils-8.31-improve-test-cp-proc-short-read.patch deleted file mode 100644 index 188a75e..0000000 --- a/coreutils-8.31-improve-test-cp-proc-short-read.patch +++ /dev/null @@ -1,54 +0,0 @@ -From fb4cb651666adb43e8b332de95616e250b4d16f7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Tue, 4 Feb 2020 00:37:23 +0000 -Subject: [PATCH] tests: avoid false failure due to varying /proc/kallsyms - -* tests/cp/proc-short-read.sh: Switch to using /proc/cpuinfo, -rather than /proc/kallsyms which was seen to vary in some cases. -Fixes https://bugs.gnu.org/39357 - -Upstream-commit: ab108667ba6112efdd42f9618a1920dc9b8f6e51 -Signed-off-by: Kamil Dudka ---- - tests/cp/proc-short-read.sh | 22 +++++++++------------- - 1 file changed, 9 insertions(+), 13 deletions(-) - -diff --git a/tests/cp/proc-short-read.sh b/tests/cp/proc-short-read.sh -index 6c58881de..dcc8b30d5 100755 ---- a/tests/cp/proc-short-read.sh -+++ b/tests/cp/proc-short-read.sh -@@ -19,22 +19,18 @@ - . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src - print_ver_ cp - --kall=/proc/kallsyms -+proc_large=/proc/cpuinfo # usually > 4KiB - --test -r $kall || skip_ "your system lacks $kall" -+test -r $proc_large || skip_ "your system lacks $proc_large" - --# Before coreutils-7.3, cp would copy less than 4KiB of this 1MB+ file. --cp $kall 1 || fail=1 --cat $kall > 2 || fail=1 --compare 1 2 || fail=1 -+# Before coreutils-7.3, cp would copy less than 4KiB of this file. -+cp $proc_large 1 || fail=1 -+cat $proc_large > 2 || fail=1 - --# Also check md5sum, just for good measure. --md5sum $kall > 3 || fail=1 --md5sum 2 > 4 || fail=1 -+# adjust varying parts -+sed '/MHz/d; /bogomips/d;' 1 > proc.cp || framework_failure_ -+sed '/MHz/d; /bogomips/d;' 2 > proc.cat || framework_failure_ - --# Remove each file name before comparing checksums. --sed 's/ .*//' 3 > sum.proc || fail=1 --sed 's/ .*//' 4 > sum.2 || fail=1 --compare sum.proc sum.2 || fail=1 -+compare proc.cp proc.cat || fail=1 - - Exit $fail --- -2.21.1 - diff --git a/coreutils-8.31-root-tests.patch b/coreutils-8.31-root-tests.patch deleted file mode 100644 index 02a150a..0000000 --- a/coreutils-8.31-root-tests.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 57324f74fb8855d4888b1e6b6dbaaec781bb6db9 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Fri, 7 Feb 2020 17:05:06 +0100 -Subject: [PATCH] tests: ensure tests/cp/preserve-gid.sh works with single - binary - -* tests/cp/preserve-gid.sh: If configured with --enable-single-binary -copy the coreutils single binary, instead of the cp one-line launcher. - -Discussed at https://bugzilla.redhat.com/1800597 -Fixes https://bugs.gnu.org/39485 - -Upstream-commit: b96b1a47286632fd1cb738cf5a9893cf72a70d30 -Signed-off-by: Kamil Dudka ---- - tests/cp/preserve-gid.sh | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/tests/cp/preserve-gid.sh b/tests/cp/preserve-gid.sh -index e48584c1e..bba09df09 100755 ---- a/tests/cp/preserve-gid.sh -+++ b/tests/cp/preserve-gid.sh -@@ -110,7 +110,14 @@ cleanup_() { rm -rf "$tmp_path"; } - # is not readable by our nameless IDs. - test -d /tmp && TMPDIR=/tmp - tmp_path=$(mktemp -d) || fail_ "failed to create temporary directory" --cp "$abs_path_dir_/cp" "$tmp_path" -+if test -x "$abs_path_dir_/coreutils" && -+ { test -l "$abs_path_dir_/cp" || -+ test $(wc -l < "$abs_path_dir_/cp") = 1; } then -+ # if configured with --enable-single-binary we need to use the single binary -+ cp "$abs_path_dir_/coreutils" "$tmp_path/cp" || framework_failure_ -+else -+ cp "$abs_path_dir_/cp" "$tmp_path" -+fi - chmod -R a+rx "$tmp_path" - - t1() { --- -2.21.1 - -From 94a47b51e64c21fef4ad8faca1599099c459b2ad Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Mon, 10 Feb 2020 15:05:43 +0000 -Subject: [PATCH] tests: fix test for symlink - -* tests/cp/preserve-gid.sh: s/-l/-L/. -Reported by Kamil Dudka - -Upstream-commit: 3150f4a82ef6542c4a8f0bf413815e78766f044f -Signed-off-by: Kamil Dudka ---- - tests/cp/preserve-gid.sh | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/cp/preserve-gid.sh b/tests/cp/preserve-gid.sh -index bba09df09..547bf66bc 100755 ---- a/tests/cp/preserve-gid.sh -+++ b/tests/cp/preserve-gid.sh -@@ -111,7 +111,7 @@ cleanup_() { rm -rf "$tmp_path"; } - test -d /tmp && TMPDIR=/tmp - tmp_path=$(mktemp -d) || fail_ "failed to create temporary directory" - if test -x "$abs_path_dir_/coreutils" && -- { test -l "$abs_path_dir_/cp" || -+ { test -L "$abs_path_dir_/cp" || - test $(wc -l < "$abs_path_dir_/cp") = 1; } then - # if configured with --enable-single-binary we need to use the single binary - cp "$abs_path_dir_/coreutils" "$tmp_path/cp" || framework_failure_ --- -2.21.1 - diff --git a/coreutils-8.31-sums-man-pages.patch b/coreutils-8.31-sums-man-pages.patch deleted file mode 100644 index 094aaaa..0000000 --- a/coreutils-8.31-sums-man-pages.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ef6be60dcaf424bdb21392aff42331bd4dc272e0 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Thu, 14 Mar 2019 13:48:01 +0100 -Subject: [PATCH] md5sum,b2sum,sha*sum: --help: add note about binary/text mode - -* src/md5sum.c (usage): Make it clear that there is no difference -between binary mode and text mode on GNU systems. - -Bug: https://bugzilla.redhat.com/406981 -Bug: https://bugzilla.redhat.com/1688740 - -Upstream-commit: ae61b1066351bb784b54fbfd7b52caf129ec286c -Signed-off-by: Kamil Dudka ---- - src/md5sum.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/md5sum.c b/src/md5sum.c -index 3532f7b7a..f75b6de02 100644 ---- a/src/md5sum.c -+++ b/src/md5sum.c -@@ -287,7 +287,10 @@ The following five options are useful only when verifying checksums:\n\ - The sums are computed as described in %s. When checking, the input\n\ - should be a former output of this program. The default mode is to print a\n\ - line with checksum, a space, a character indicating input mode ('*' for binary,\ --\n' ' for text or where binary is insignificant), and name for each FILE.\n"), -+\n' ' for text or where binary is insignificant), and name for each FILE.\n\ -+\n\ -+Note: There is no difference between binary mode and text mode on GNU systems.\ -+\n"), - DIGEST_REFERENCE); - emit_ancillary_info (PROGRAM_NAME); - } --- -2.17.2 - diff --git a/coreutils-8.31.tar.xz.sig b/coreutils-8.31.tar.xz.sig deleted file mode 100644 index 5aa60a1..0000000 --- a/coreutils-8.31.tar.xz.sig +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v2 - -iQIcBAABCAAGBQJchaqkAAoJEN9v2XEwYDfZKBMQAJNjmYU6VrbHvlSJm1d+9Qch -rvVtE5VGsTj3jUj1dh9MpuN9GhJifWJat9DEKUat0J4Z5G8d55LvyzQJppby2az2 -kwbp/ffK0wR1tfGNii3Hop3pMVizqJn+LbT01qcS3E7tVQ2nJP/JVIeXOtOf9kJk -gPviDaqO8OUiV2l3gCwLtuOETKHXRGyraWRxCb9ZxOS12Gspqfwui7t4jQUDf2Ge -Kvhcawas+XomGdWx+io/VxwkOZkOCr9vQdMM7ZqLDnu+d7nGsnPMxxdGcP72WBnV -1LxFxHIel52yuRh3T1RggQMKxXPFPEyDRgaBNN0Yfk3a2CHFHf+YtySgLzKSqyS5 -1P5syvSbNj9ASEuX428lpwI3EC5G3T9W/MLTKUpwVhfU8/WELI261F95dnFIfoar -mMPqbBMHwHpIasJfDy60m8H8/z8PEOmpRP0xfAuOtf47YpDLsH+AvrAJM4CH9kkS -lysMUZITyIqUBSoUs8mVygV7b4mq2X2US0Mkja/hDFAcq2O7m2eyvi61z7Oa1Y/r -tV+q/XS8ZTOtSTBBZzRVTJDPno1ZwFBl/MIiD5FgF7szgiR2z0KVMfAlVBdQwxKw -Mj6N/HYeP6yE3g9I5+8LmRLwQcXeC2B0ZzpvGE7DaKd5aFDC6YVDD8wyLEQFDAav -XGtN62+yfXArdYVjXygm -=LVk4 ------END PGP SIGNATURE----- diff --git a/coreutils-8.32-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch new file mode 100644 index 0000000..3a0375d --- /dev/null +++ b/coreutils-8.32-DIR_COLORS.patch @@ -0,0 +1,100 @@ +From c7b13f5e1a7ad012c510a8bdd5a8943ab4b55833 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 17 Jun 2016 16:58:18 +0200 +Subject: [PATCH] downstream changes to default DIR_COLORS + +--- + DIR_COLORS | 9 ++++++++- + DIR_COLORS.lightbgcolor | 21 +++++++++++++++------ + 2 files changed, 23 insertions(+), 7 deletions(-) + +diff --git a/DIR_COLORS b/DIR_COLORS +index b465771..ad42b09 100644 +--- a/DIR_COLORS ++++ b/DIR_COLORS +@@ -1,3 +1,7 @@ ++# This file goes in the /etc directory, and must be world readable. ++# You can copy this file to .dir_colors in your $HOME directory to override ++# the system defaults. ++ + # Configuration file for dircolors, a utility to help you set the + # LS_COLORS environment variable used by GNU ls with the --color option. + +@@ -10,6 +14,9 @@ + + # Global config options can be specified before TERM or COLORTERM entries + ++# For compatibility, the pattern "^COLOR.*none" is recognized as a way to ++# disable colorization. See https://bugzilla.redhat.com/1349579 for details. ++ + # Below are TERM or COLORTERM entries, which can be glob patterns, which + # restrict following config to systems with matching environment variables. + COLORTERM ?* +@@ -62,7 +69,7 @@ DOOR 01;35 # door + BLK 40;33;01 # block device driver + CHR 40;33;01 # character device driver + ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... +-MISSING 00 # ... and the files they point to ++MISSING 01;37;41 # ... and the files they point to + SETUID 37;41 # file that is setuid (u+s) + SETGID 30;43 # file that is setgid (g+s) + CAPABILITY 00 # file with capability (very expensive to lookup) +diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor +index eab6258..1627b63 100644 +--- a/DIR_COLORS.lightbgcolor ++++ b/DIR_COLORS.lightbgcolor +@@ -1,3 +1,9 @@ ++# Configuration file for the color ls utility - modified for lighter backgrounds ++ ++# This file goes in the /etc directory, and must be world readable. ++# You can copy this file to .dir_colors in your $HOME directory to override ++# the system defaults. ++ + # Configuration file for dircolors, a utility to help you set the + # LS_COLORS environment variable used by GNU ls with the --color option. + +@@ -10,6 +16,9 @@ + + # Global config options can be specified before TERM or COLORTERM entries + ++# For compatibility, the pattern "^COLOR.*none" is recognized as a way to ++# disable colorization. See https://bugzilla.redhat.com/1349579 for details. ++ + # Below are TERM or COLORTERM entries, which can be glob patterns, which + # restrict following config to systems with matching environment variables. + COLORTERM ?* +@@ -52,17 +61,17 @@ TERM xterm* + #NORMAL 00 # no color code at all + #FILE 00 # regular file: use no color at all + RESET 0 # reset to "normal" color +-DIR 01;34 # directory +-LINK 01;36 # symbolic link. (If you set this to 'target' instead of a ++DIR 00;34 # directory ++LINK 00;36 # symbolic link. (If you set this to 'target' instead of a + # numerical value, the color is as for the file pointed to.) + MULTIHARDLINK 00 # regular file with more than one link + FIFO 40;33 # pipe +-SOCK 01;35 # socket +-DOOR 01;35 # door ++SOCK 00;35 # socket ++DOOR 00;35 # door + BLK 40;33;01 # block device driver + CHR 40;33;01 # character device driver + ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... +-MISSING 00 # ... and the files they point to ++MISSING 01;37;41 # ... and the files they point to + SETUID 37;41 # file that is setuid (u+s) + SETGID 30;43 # file that is setgid (g+s) + CAPABILITY 00 # file with capability (very expensive to lookup) +@@ -71,7 +80,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky + STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable + + # This is for files with execute permission: +-EXEC 01;32 ++EXEC 00;32 + + # List any file extensions like '.gz' or '.tar' that you would like ls + # to color below. Put the extension, a space, and the color init string. +-- +2.34.1 + diff --git a/coreutils-8.4-mkdir-modenote.patch b/coreutils-8.4-mkdir-modenote.patch index 51a129e..3973d44 100644 --- a/coreutils-8.4-mkdir-modenote.patch +++ b/coreutils-8.4-mkdir-modenote.patch @@ -2,7 +2,7 @@ diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 400e135..47e4480 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -10074,6 +10074,8 @@ incorrect. @xref{Directory Setuid and Setgid}, for how the +@@ -10829,6 +10829,8 @@ incorrect. @xref{Directory Setuid and Setgid}, for how the set-user-ID and set-group-ID bits of directories are inherited unless overridden in this way. diff --git a/coreutils-9.0-autofs-no-mount.patch b/coreutils-9.0-autofs-no-mount.patch new file mode 100644 index 0000000..b6d6523 --- /dev/null +++ b/coreutils-9.0-autofs-no-mount.patch @@ -0,0 +1,87 @@ +From f4422844dbcd839ce486bcbc15b7bd5b72c9198d Mon Sep 17 00:00:00 2001 +From: Rohan Sable +Date: Mon, 7 Mar 2022 14:14:13 +0000 +Subject: [PATCH 1/2] ls: avoid triggering automounts + +statx() has different defaults wrt automounting +compared to stat() or lstat(), so explicitly +set the AT_NO_AUTOMOUNT flag to suppress that behavior, +and avoid unintended operations or potential errors. + +* src/ls.c (do_statx): Pass AT_NO_AUTOMOUNT to avoid this behavior. +Fixes https://bugs.gnu.org/54286 + +Signed-off-by: Rohan Sable + +Upstream-commit: 85c975df2c25bd799370b04bb294e568e001102f +Signed-off-by: Kamil Dudka +--- + src/ls.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ls.c b/src/ls.c +index 1047801..fe0e9f8 100644 +--- a/src/ls.c ++++ b/src/ls.c +@@ -1175,7 +1175,7 @@ do_statx (int fd, char const *name, struct stat *st, int flags, + { + struct statx stx; + bool want_btime = mask & STATX_BTIME; +- int ret = statx (fd, name, flags, mask, &stx); ++ int ret = statx (fd, name, flags | AT_NO_AUTOMOUNT, mask, &stx); + if (ret >= 0) + { + statx_to_stat (&stx, st); +-- +2.34.1 + + +From 3d227f9e4f3fe806064721e4b9451ee06526bc80 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Mon, 7 Mar 2022 23:29:20 +0000 +Subject: [PATCH 2/2] stat: only automount with --cached=never + +Revert to the default behavior before the introduction of statx(). + +* src/stat.c (do_stat): Set AT_NO_AUTOMOUNT without --cached=never. +* doc/coreutils.texi (stat invocation): Mention the automount +behavior with --cached=never. + +Fixes https://bugs.gnu.org/54287 + +Upstream-commit: 92cb8427c537f37edd43c5cef1909585201372ab +Signed-off-by: Kamil Dudka +--- + doc/coreutils.texi | 1 + + src/stat.c | 3 +++ + 2 files changed, 4 insertions(+) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 19b535c..0f5c16a 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -12564,6 +12564,7 @@ Always read the already cached attributes if available. + + @item never + Always sychronize with the latest file system attributes. ++This also mounts automounted files. + + @item default + Leave the caching behavior to the underlying file system. +diff --git a/src/stat.c b/src/stat.c +index 0c34501..803340a 100644 +--- a/src/stat.c ++++ b/src/stat.c +@@ -1381,6 +1381,9 @@ do_stat (char const *filename, char const *format, char const *format2) + else if (force_sync) + flags |= AT_STATX_FORCE_SYNC; + ++ if (! force_sync) ++ flags |= AT_NO_AUTOMOUNT; ++ + fd = statx (fd, pathname, flags, format_to_mask (format), &stx); + if (fd < 0) + { +-- +2.34.1 + diff --git a/coreutils-9.0-chmod-symlink.patch b/coreutils-9.0-chmod-symlink.patch new file mode 100644 index 0000000..fad3b7a --- /dev/null +++ b/coreutils-9.0-chmod-symlink.patch @@ -0,0 +1,114 @@ +From c76e70637e529481478e26683ebd73c40621c382 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Fri, 24 Sep 2021 20:57:41 +0100 +Subject: [PATCH] chmod: fix exit status when ignoring symlinks + +* src/chmod.c: Reorder enum so CH_NOT_APPLIED +can be treated as a non error. +* tests/chmod/ignore-symlink.sh: A new test. +* tests/local.mk: Reference the new test. +* NEWS: Mention the bug fix. +Fixes https://bugs.gnu.org/50784 + +Upstream-commit: e8b56ebd536e82b15542a00c888109471936bfda +Signed-off-by: Kamil Dudka +--- + NEWS | 6 ++++++ + src/chmod.c | 4 ++-- + tests/chmod/ignore-symlink.sh | 31 +++++++++++++++++++++++++++++++ + tests/local.mk | 1 + + 4 files changed, 40 insertions(+), 2 deletions(-) + create mode 100755 tests/chmod/ignore-symlink.sh + +diff --git a/NEWS b/NEWS +index f2fbcbb..5722a8b 100644 +--- a/NEWS ++++ b/NEWS +@@ -143,6 +143,12 @@ GNU coreutils NEWS -*- outline -*- + where avx2 instructions are supported. + A new --debug option will indicate if avx2 is being used. + ++** Bug fixes ++ ++ chmod -R no longer exits with error status when encountering symlinks. ++ All files would be processed correctly, but the exit status was incorrect. ++ [bug introduced in coreutils-9.0] ++ + + * Noteworthy changes in release 8.32 (2020-03-05) [stable] + +diff --git a/src/chmod.c b/src/chmod.c +index 37b04f5..57ac47f 100644 +--- a/src/chmod.c ++++ b/src/chmod.c +@@ -44,8 +44,8 @@ struct change_status + enum + { + CH_NO_STAT, +- CH_NOT_APPLIED, + CH_FAILED, ++ CH_NOT_APPLIED, + CH_NO_CHANGE_REQUESTED, + CH_SUCCEEDED + } +@@ -322,7 +322,7 @@ process_file (FTS *fts, FTSENT *ent) + if ( ! recurse) + fts_set (fts, ent, FTS_SKIP); + +- return CH_NO_CHANGE_REQUESTED <= ch.status; ++ return CH_NOT_APPLIED <= ch.status; + } + + /* Recursively change the modes of the specified FILES (the last entry +diff --git a/tests/chmod/ignore-symlink.sh b/tests/chmod/ignore-symlink.sh +new file mode 100755 +index 0000000..5ce3de8 +--- /dev/null ++++ b/tests/chmod/ignore-symlink.sh +@@ -0,0 +1,31 @@ ++#!/bin/sh ++# Test for proper exit code of chmod on a processed symlink. ++ ++# Copyright (C) 2021 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ chmod ++ ++mkdir dir || framework_failure_ ++touch dir/f || framework_failure_ ++ln -s f dir/l || framework_failure_ ++ ++# This operation ignores symlinks but should succeed. ++chmod u+w -R dir 2> out || fail=1 ++ ++compare /dev/null out || fail=1 ++ ++Exit $fail +diff --git a/tests/local.mk b/tests/local.mk +index a76c808..a2164c9 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -458,6 +458,7 @@ all_tests = \ + tests/chmod/c-option.sh \ + tests/chmod/equal-x.sh \ + tests/chmod/equals.sh \ ++ tests/chmod/ignore-symlink.sh \ + tests/chmod/inaccessible.sh \ + tests/chmod/octal.sh \ + tests/chmod/setgid.sh \ +-- +2.31.1 + diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index f631762..66ec2fa 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -15,11 +15,6 @@ alias l. 'ls -d .*' set COLORS=/etc/DIR_COLORS if ($?TERM) then - if ( -e "/etc/DIR_COLORS.256color" ) then - if ( "`/usr/bin/tput colors`" == "256" ) then - set COLORS=/etc/DIR_COLORS.256color - endif - endif if ( -e "/etc/DIR_COLORS.$TERM" ) then set COLORS="/etc/DIR_COLORS.$TERM" endif diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index ac92268..5162f1e 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -22,10 +22,6 @@ if [ -z "$USER_LS_COLORS" ]; then [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.$TERM" ] && \ COLORS="/etc/DIR_COLORS.$TERM" - [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.256color" ] && \ - [ "x`/usr/bin/tty -s && /usr/bin/tput colors 2>/dev/null`" = "x256" ] && \ - COLORS="/etc/DIR_COLORS.256color" - [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS" ] && \ COLORS="/etc/DIR_COLORS" diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 248a6ae..2571fa4 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,8 +1,20 @@ +From 6e36198f10a2f63b89c89ebb5d5c185b20fb3a63 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 29 Mar 2010 17:20:34 +0000 +Subject: [PATCH] coreutils-df-direct.patch + +--- + doc/coreutils.texi | 7 ++++++ + src/df.c | 34 ++++++++++++++++++++++++++-- + tests/df/direct.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 94 insertions(+), 2 deletions(-) + create mode 100755 tests/df/direct.sh + diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index a507280..400e135 100644 +index 5b9a597..6810c15 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -11303,6 +11303,13 @@ some systems (notably SunOS), doing this yields more up to date results, +@@ -12074,6 +12074,13 @@ some systems (notably Solaris), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -15,12 +27,12 @@ index a507280..400e135 100644 + @item --total @opindex --total - @cindex grand total of disk size, usage and available space + @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index 8f760db..a7385fd 100644 +index 48025b9..c8efa5b 100644 --- a/src/df.c +++ b/src/df.c -@@ -120,6 +120,9 @@ static bool print_type; +@@ -125,6 +125,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -30,7 +42,7 @@ index 8f760db..a7385fd 100644 /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -247,13 +250,15 @@ enum +@@ -252,13 +255,15 @@ enum NO_SYNC_OPTION = CHAR_MAX + 1, SYNC_OPTION, TOTAL_OPTION, @@ -47,7 +59,7 @@ index 8f760db..a7385fd 100644 {"inodes", no_argument, NULL, 'i'}, {"human-readable", no_argument, NULL, 'h'}, {"si", no_argument, NULL, 'H'}, -@@ -509,7 +514,10 @@ get_header (void) +@@ -583,7 +588,10 @@ get_header (void) for (col = 0; col < ncolumns; col++) { char *cell = NULL; @@ -59,7 +71,7 @@ index 8f760db..a7385fd 100644 if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1397,6 +1405,19 @@ get_point (const char *point, const struct stat *statp) +@@ -1486,6 +1494,17 @@ get_point (char const *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -68,18 +80,16 @@ index 8f760db..a7385fd 100644 + char *resolved = canonicalize_file_name (name); + if (resolved) + { -+ char *mp = find_mount_point (name, statp); -+ get_dev (NULL, mp, resolved, NULL, NULL, false, false, NULL, false); -+ free(mp); ++ get_dev (NULL, resolved, name, NULL, NULL, false, false, NULL, false); + free (resolved); + return; + } + } + if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) - && get_disk (name)) + && get_device (name)) return; -@@ -1467,6 +1488,7 @@ or all file systems by default.\n\ +@@ -1556,6 +1575,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -87,7 +97,7 @@ index 8f760db..a7385fd 100644 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1557,6 +1579,9 @@ main (int argc, char **argv) +@@ -1646,6 +1666,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -97,7 +107,7 @@ index 8f760db..a7385fd 100644 case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1653,6 +1678,13 @@ main (int argc, char **argv) +@@ -1742,6 +1765,13 @@ main (int argc, char **argv) } } @@ -172,3 +182,6 @@ index 0000000..8e4cfb8 +compare file_out file_exp || fail=1 + +Exit $fail +-- +2.31.1 + diff --git a/coreutils-getgrouplist.patch b/coreutils-getgrouplist.patch index 5349337..93eef67 100644 --- a/coreutils-getgrouplist.patch +++ b/coreutils-getgrouplist.patch @@ -29,7 +29,7 @@ index 76474c2..0a9d221 100644 #include "xalloc-oversized.h" /* Work around an incompatibility of OS X 10.11: getgrouplist -@@ -121,9 +122,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) +@@ -119,9 +120,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) /* else no username, so fall through and use getgroups. */ #endif @@ -50,7 +50,7 @@ index 76474c2..0a9d221 100644 /* If we failed to count groups because there is no supplemental group support, then return an array containing just GID. -@@ -145,10 +154,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) +@@ -143,10 +152,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) if (g == NULL) return -1; @@ -84,7 +84,7 @@ diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4 index 62777c7..5180243 100644 --- a/m4/jm-macros.m4 +++ b/m4/jm-macros.m4 -@@ -82,6 +82,7 @@ AC_DEFUN([coreutils_MACROS], +@@ -68,6 +68,7 @@ AC_DEFUN([coreutils_MACROS], fchown fchmod ftruncate diff --git a/coreutils-i18n-cut-old.patch b/coreutils-i18n-cut-old.patch deleted file mode 100644 index 757ee0f..0000000 --- a/coreutils-i18n-cut-old.patch +++ /dev/null @@ -1,565 +0,0 @@ -diff --git a/src/cut.c b/src/cut.c -index 7ab6be4..022d0ad 100644 ---- a/src/cut.c -+++ b/src/cut.c -@@ -28,6 +28,11 @@ - #include - #include - #include -+ -+/* Get mbstate_t, mbrtowc(). */ -+#if HAVE_WCHAR_H -+# include -+#endif - #include "system.h" - - #include "error.h" -@@ -38,6 +43,18 @@ - - #include "set-fields.h" - -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC -+ installation; work around this configuration error. */ -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 -+# undef MB_LEN_MAX -+# define MB_LEN_MAX 16 -+#endif -+ -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ -+#if HAVE_MBRTOWC && defined mbstate_t -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) -+#endif -+ - /* The official name of this program (e.g., no 'g' prefix). */ - #define PROGRAM_NAME "cut" - -@@ -54,6 +71,52 @@ - } \ - while (0) - -+/* Refill the buffer BUF to get a multibyte character. */ -+#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM) \ -+ do \ -+ { \ -+ if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM)) \ -+ { \ -+ memmove (BUF, BUFPOS, BUFLEN); \ -+ BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \ -+ BUFPOS = BUF; \ -+ } \ -+ } \ -+ while (0) -+ -+/* Get wide character on BUFPOS. BUFPOS is not included after that. -+ If byte sequence is not valid as a character, CONVFAIL is true. Otherwise false. */ -+#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ -+ do \ -+ { \ -+ mbstate_t state_bak; \ -+ \ -+ if (BUFLEN < 1) \ -+ { \ -+ WC = WEOF; \ -+ break; \ -+ } \ -+ \ -+ /* Get a wide character. */ \ -+ CONVFAIL = false; \ -+ state_bak = STATE; \ -+ MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \ -+ \ -+ switch (MBLENGTH) \ -+ { \ -+ case (size_t)-1: \ -+ case (size_t)-2: \ -+ CONVFAIL = true; \ -+ STATE = state_bak; \ -+ /* Fall througn. */ \ -+ \ -+ case 0: \ -+ MBLENGTH = 1; \ -+ break; \ -+ } \ -+ } \ -+ while (0) -+ - - /* Pointer inside RP. When checking if a byte or field is selected - by a finite range, we check if it is between CURRENT_RP.LO -@@ -61,6 +124,9 @@ - CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ - static struct field_range_pair *current_rp; - -+/* Length of the delimiter given as argument to -d. */ -+size_t delimlen; -+ - /* This buffer is used to support the semantics of the -s option - (or lack of same) when the specified field list includes (does - not include) the first field. In both of those cases, the entire -@@ -77,15 +143,25 @@ enum operating_mode - { - undefined_mode, - -- /* Output characters that are in the given bytes. */ -+ /* Output bytes that are at the given positions. */ - byte_mode, - -+ /* Output characters that are at the given positions. */ -+ character_mode, -+ - /* Output the given delimiter-separated fields. */ - field_mode - }; - - static enum operating_mode operating_mode; - -+/* If nonzero, when in byte mode, don't split multibyte characters. */ -+static int byte_mode_character_aware; -+ -+/* If nonzero, the function for single byte locale is work -+ if this program runs on multibyte locale. */ -+static int force_singlebyte_mode; -+ - /* If true do not output lines containing no delimiter characters. - Otherwise, all such lines are printed. This option is valid only - with field mode. */ -@@ -97,6 +173,9 @@ static bool complement; - - /* The delimiter character for field mode. */ - static unsigned char delim; -+#if HAVE_WCHAR_H -+static wchar_t wcdelim; -+#endif - - /* The delimiter for each line/record. */ - static unsigned char line_delim = '\n'; -@@ -164,7 +243,7 @@ Print selected parts of lines from each FILE to standard output.\n\ - -f, --fields=LIST select only these fields; also print any line\n\ - that contains no delimiter character, unless\n\ - the -s option is specified\n\ -- -n (ignored)\n\ -+ -n with -b: don't split multibyte characters\n\ - "), stdout); - fputs (_("\ - --complement complement the set of selected bytes, characters\n\ -@@ -280,6 +359,82 @@ cut_bytes (FILE *stream) - } - } - -+#if HAVE_MBRTOWC -+/* This function is in use for the following case. -+ -+ 1. Read from the stream STREAM, printing to standard output any selected -+ characters. -+ -+ 2. Read from stream STREAM, printing to standard output any selected bytes, -+ without splitting multibyte characters. */ -+ -+static void -+cut_characters_or_cut_bytes_no_split (FILE *stream) -+{ -+ uintmax_t idx; /* number of bytes or characters in the line so far. */ -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ char *bufpos; /* Next read position of BUF. */ -+ size_t buflen; /* The length of the byte sequence in buf. */ -+ wint_t wc; /* A gotten wide character. */ -+ size_t mblength; /* The byte size of a multibyte character which shows -+ as same character as WC. */ -+ mbstate_t state; /* State of the stream. */ -+ bool convfail = false; /* true, when conversion failed. Otherwise false. */ -+ /* Whether to begin printing delimiters between ranges for the current line. -+ Set after we've begun printing data corresponding to the first range. */ -+ bool print_delimiter = false; -+ -+ idx = 0; -+ buflen = 0; -+ bufpos = buf; -+ memset (&state, '\0', sizeof(mbstate_t)); -+ -+ current_rp = frp; -+ -+ while (1) -+ { -+ REFILL_BUFFER (buf, bufpos, buflen, stream); -+ -+ GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); -+ (void) convfail; /* ignore unused */ -+ -+ if (wc == WEOF) -+ { -+ if (idx > 0) -+ putchar (line_delim); -+ break; -+ } -+ else if (wc == line_delim) -+ { -+ putchar (line_delim); -+ idx = 0; -+ print_delimiter = false; -+ current_rp = frp; -+ } -+ else -+ { -+ next_item (&idx); -+ if (print_kth (idx)) -+ { -+ if (output_delimiter_specified) -+ { -+ if (print_delimiter && is_range_start_index (idx)) -+ { -+ fwrite (output_delimiter_string, sizeof (char), -+ output_delimiter_length, stdout); -+ } -+ print_delimiter = true; -+ } -+ fwrite (bufpos, mblength, sizeof(char), stdout); -+ } -+ } -+ -+ buflen -= mblength; -+ bufpos += mblength; -+ } -+} -+#endif -+ - /* Read from stream STREAM, printing to standard output any selected fields. */ - - static void -@@ -425,13 +580,211 @@ cut_fields (FILE *stream) - } - } - -+#if HAVE_MBRTOWC -+static void -+cut_fields_mb (FILE *stream) -+{ -+ int c; -+ uintmax_t field_idx; -+ int found_any_selected_field; -+ int buffer_first_field; -+ int empty_input; -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ char *bufpos; /* Next read position of BUF. */ -+ size_t buflen; /* The length of the byte sequence in buf. */ -+ wint_t wc = 0; /* A gotten wide character. */ -+ size_t mblength; /* The byte size of a multibyte character which shows -+ as same character as WC. */ -+ mbstate_t state; /* State of the stream. */ -+ bool convfail = false; /* true, when conversion failed. Otherwise false. */ -+ -+ current_rp = frp; -+ -+ found_any_selected_field = 0; -+ field_idx = 1; -+ bufpos = buf; -+ buflen = 0; -+ memset (&state, '\0', sizeof(mbstate_t)); -+ -+ c = getc (stream); -+ empty_input = (c == EOF); -+ if (c != EOF) -+ { -+ ungetc (c, stream); -+ wc = 0; -+ } -+ else -+ wc = WEOF; -+ -+ /* To support the semantics of the -s flag, we may have to buffer -+ all of the first field to determine whether it is `delimited.' -+ But that is unnecessary if all non-delimited lines must be printed -+ and the first field has been selected, or if non-delimited lines -+ must be suppressed and the first field has *not* been selected. -+ That is because a non-delimited line has exactly one field. */ -+ buffer_first_field = (suppress_non_delimited ^ !print_kth (1)); -+ -+ while (1) -+ { -+ if (field_idx == 1 && buffer_first_field) -+ { -+ int len = 0; -+ -+ while (1) -+ { -+ REFILL_BUFFER (buf, bufpos, buflen, stream); -+ -+ GET_NEXT_WC_FROM_BUFFER -+ (wc, bufpos, buflen, mblength, state, convfail); -+ -+ if (wc == WEOF) -+ break; -+ -+ field_1_buffer = xrealloc (field_1_buffer, len + mblength); -+ memcpy (field_1_buffer + len, bufpos, mblength); -+ len += mblength; -+ buflen -= mblength; -+ bufpos += mblength; -+ -+ if (!convfail && (wc == line_delim || wc == wcdelim)) -+ break; -+ } -+ -+ if (len <= 0 && wc == WEOF) -+ break; -+ -+ /* If the first field extends to the end of line (it is not -+ delimited) and we are printing all non-delimited lines, -+ print this one. */ -+ if (convfail || (!convfail && wc != wcdelim)) -+ { -+ if (suppress_non_delimited) -+ { -+ /* Empty. */ -+ } -+ else -+ { -+ fwrite (field_1_buffer, sizeof (char), len, stdout); -+ /* Make sure the output line is newline terminated. */ -+ if (convfail || (!convfail && wc != line_delim)) -+ putchar (line_delim); -+ } -+ continue; -+ } -+ -+ if (print_kth (1)) -+ { -+ /* Print the field, but not the trailing delimiter. */ -+ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); -+ found_any_selected_field = 1; -+ } -+ next_item (&field_idx); -+ } -+ -+ if (wc != WEOF) -+ { -+ if (print_kth (field_idx)) -+ { -+ if (found_any_selected_field) -+ { -+ fwrite (output_delimiter_string, sizeof (char), -+ output_delimiter_length, stdout); -+ } -+ found_any_selected_field = 1; -+ } -+ -+ while (1) -+ { -+ REFILL_BUFFER (buf, bufpos, buflen, stream); -+ -+ GET_NEXT_WC_FROM_BUFFER -+ (wc, bufpos, buflen, mblength, state, convfail); -+ -+ if (wc == WEOF) -+ break; -+ else if (!convfail && (wc == wcdelim || wc == line_delim)) -+ { -+ buflen -= mblength; -+ bufpos += mblength; -+ break; -+ } -+ -+ if (print_kth (field_idx)) -+ fwrite (bufpos, mblength, sizeof(char), stdout); -+ -+ buflen -= mblength; -+ bufpos += mblength; -+ } -+ } -+ -+ if ((!convfail || wc == line_delim) && buflen < 1) -+ wc = WEOF; -+ -+ if (!convfail && wc == wcdelim) -+ next_item (&field_idx); -+ else if (wc == WEOF || (!convfail && wc == line_delim)) -+ { -+ if (found_any_selected_field -+ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) -+ putchar (line_delim); -+ if (wc == WEOF) -+ break; -+ field_idx = 1; -+ current_rp = frp; -+ found_any_selected_field = 0; -+ } -+ } -+} -+#endif -+ - static void - cut_stream (FILE *stream) - { -- if (operating_mode == byte_mode) -- cut_bytes (stream); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) -+ { -+ switch (operating_mode) -+ { -+ case byte_mode: -+ if (byte_mode_character_aware) -+ cut_characters_or_cut_bytes_no_split (stream); -+ else -+ cut_bytes (stream); -+ break; -+ -+ case character_mode: -+ cut_characters_or_cut_bytes_no_split (stream); -+ break; -+ -+ case field_mode: -+ if (delimlen == 1) -+ { -+ /* Check if we have utf8 multibyte locale, so we can use this -+ optimization because of uniqueness of characters, which is -+ not true for e.g. SJIS */ -+ char * loc = setlocale(LC_CTYPE, NULL); -+ if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") || -+ strstr (loc, "UTF8") || strstr (loc, "utf8"))) -+ { -+ cut_fields (stream); -+ break; -+ } -+ } -+ cut_fields_mb (stream); -+ break; -+ -+ default: -+ abort (); -+ } -+ } - else -- cut_fields (stream); -+#endif -+ { -+ if (operating_mode == field_mode) -+ cut_fields (stream); -+ else -+ cut_bytes (stream); -+ } - } - - /* Process file FILE to standard output. -@@ -483,6 +836,7 @@ main (int argc, char **argv) - bool ok; - bool delim_specified = false; - char *spec_list_string IF_LINT ( = NULL); -+ char mbdelim[MB_LEN_MAX + 1]; - - initialize_main (&argc, &argv); - set_program_name (argv[0]); -@@ -505,7 +859,6 @@ main (int argc, char **argv) - switch (optc) - { - case 'b': -- case 'c': - /* Build the byte list. */ - if (operating_mode != undefined_mode) - FATAL_ERROR (_("only one type of list may be specified")); -@@ -513,6 +866,14 @@ main (int argc, char **argv) - spec_list_string = optarg; - break; - -+ case 'c': -+ /* Build the character list. */ -+ if (operating_mode != undefined_mode) -+ FATAL_ERROR (_("only one type of list may be specified")); -+ operating_mode = character_mode; -+ spec_list_string = optarg; -+ break; -+ - case 'f': - /* Build the field list. */ - if (operating_mode != undefined_mode) -@@ -524,10 +885,38 @@ main (int argc, char **argv) - case 'd': - /* New delimiter. */ - /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ -- if (optarg[0] != '\0' && optarg[1] != '\0') -- FATAL_ERROR (_("the delimiter must be a single character")); -- delim = optarg[0]; -- delim_specified = true; -+ { -+#if HAVE_MBRTOWC -+ if(MB_CUR_MAX > 1) -+ { -+ mbstate_t state; -+ -+ memset (&state, '\0', sizeof(mbstate_t)); -+ delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state); -+ -+ if (delimlen == (size_t)-1 || delimlen == (size_t)-2) -+ ++force_singlebyte_mode; -+ else -+ { -+ delimlen = (delimlen < 1) ? 1 : delimlen; -+ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') -+ FATAL_ERROR (_("the delimiter must be a single character")); -+ memcpy (mbdelim, optarg, delimlen); -+ mbdelim[delimlen] = '\0'; -+ if (delimlen == 1) -+ delim = *optarg; -+ } -+ } -+ -+ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) -+#endif -+ { -+ if (optarg[0] != '\0' && optarg[1] != '\0') -+ FATAL_ERROR (_("the delimiter must be a single character")); -+ delim = (unsigned char) optarg[0]; -+ } -+ delim_specified = true; -+ } - break; - - case OUTPUT_DELIMITER_OPTION: -@@ -540,6 +929,7 @@ main (int argc, char **argv) - break; - - case 'n': -+ byte_mode_character_aware = 1; - break; - - case 's': -@@ -579,15 +969,34 @@ main (int argc, char **argv) - | (complement ? SETFLD_COMPLEMENT : 0) ); - - if (!delim_specified) -- delim = '\t'; -+ { -+ delim = '\t'; -+#ifdef HAVE_MBRTOWC -+ wcdelim = L'\t'; -+ mbdelim[0] = '\t'; -+ mbdelim[1] = '\0'; -+ delimlen = 1; -+#endif -+ } - - if (output_delimiter_string == NULL) - { -- static char dummy[2]; -- dummy[0] = delim; -- dummy[1] = '\0'; -- output_delimiter_string = dummy; -- output_delimiter_length = 1; -+#ifdef HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) -+ { -+ output_delimiter_string = xstrdup(mbdelim); -+ output_delimiter_length = delimlen; -+ } -+ -+ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) -+#endif -+ { -+ static char dummy[2]; -+ dummy[0] = delim; -+ dummy[1] = '\0'; -+ output_delimiter_string = dummy; -+ output_delimiter_length = 1; -+ } - } - - if (optind == argc) diff --git a/coreutils-i18n-expand-unexpand.patch b/coreutils-i18n-expand-unexpand.patch deleted file mode 100644 index b5f571f..0000000 --- a/coreutils-i18n-expand-unexpand.patch +++ /dev/null @@ -1,848 +0,0 @@ -From e87ab5b991b08092a7e07af82b3ec822a8604151 Mon Sep 17 00:00:00 2001 -From: Ondrej Oprala -Date: Wed, 5 Aug 2015 09:15:09 +0200 -Subject: [PATCH] expand,unexpand: add multibyte support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -* NEWS: Mention the changes. -* bootstrap.conf: Add mbfile to the list of modules. -* configure.ac: Properly initialize mbfile. -* src/expand.c (expand): Iterate over multibyte characters properly. -* src/unexpand.c (unexpand): Iterate over multibyte characters -properly. -* tests/local.mk: Add new tests. -* tests/{expand,unexpand}/mb.sh: New tests. - -Co-authored-by: Pádraig Brady ---- - bootstrap.conf | 1 + - configure.ac | 2 + - lib/mbfile.c | 3 + - lib/mbfile.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++ - m4/mbfile.m4 | 14 +++ - src/expand.c | 43 +++++---- - src/unexpand.c | 54 +++++++---- - tests/expand/mb.sh | 98 ++++++++++++++++++++ - tests/local.mk | 2 + - tests/unexpand/mb.sh | 97 ++++++++++++++++++++ - 10 files changed, 535 insertions(+), 34 deletions(-) - create mode 100644 lib/mbfile.c - create mode 100644 lib/mbfile.h - create mode 100644 m4/mbfile.m4 - create mode 100755 tests/expand/mb.sh - create mode 100755 tests/unexpand/mb.sh - -diff --git a/bootstrap.conf b/bootstrap.conf -index 8a0ff31..a1c78b2 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -152,6 +152,7 @@ gnulib_modules=" - maintainer-makefile - malloc-gnu - manywarnings -+ mbfile - mbrlen - mbrtowc - mbsalign -diff --git a/configure.ac b/configure.ac -index 1e74b36..24c9725 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -427,6 +427,8 @@ fi - # I'm leaving it here for now. This whole thing needs to be modernized... - gl_WINSIZE_IN_PTEM - -+gl_MBFILE -+ - gl_HEADER_TIOCGWINSZ_IN_TERMIOS_H - - if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ -diff --git a/lib/mbfile.c b/lib/mbfile.c -new file mode 100644 -index 0000000..b0a468e ---- /dev/null -+++ b/lib/mbfile.c -@@ -0,0 +1,3 @@ -+#include -+#define MBFILE_INLINE _GL_EXTERN_INLINE -+#include "mbfile.h" -diff --git a/lib/mbfile.h b/lib/mbfile.h -new file mode 100644 -index 0000000..11f1b12 ---- /dev/null -+++ b/lib/mbfile.h -@@ -0,0 +1,255 @@ -+/* Multibyte character I/O: macros for multi-byte encodings. -+ Copyright (C) 2001, 2005, 2009-2015 Free Software Foundation, Inc. -+ -+ This program is free software: you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . */ -+ -+/* Written by Mitsuru Chinen -+ and Bruno Haible . */ -+ -+/* The macros in this file implement multi-byte character input from a -+ stream. -+ -+ mb_file_t -+ is the type for multibyte character input stream, usable for variable -+ declarations. -+ -+ mbf_char_t -+ is the type for multibyte character or EOF, usable for variable -+ declarations. -+ -+ mbf_init (mbf, stream) -+ initializes the MB_FILE for reading from stream. -+ -+ mbf_getc (mbc, mbf) -+ reads the next multibyte character from mbf and stores it in mbc. -+ -+ mb_iseof (mbc) -+ returns true if mbc represents the EOF value. -+ -+ Here are the function prototypes of the macros. -+ -+ extern void mbf_init (mb_file_t mbf, FILE *stream); -+ extern void mbf_getc (mbf_char_t mbc, mb_file_t mbf); -+ extern bool mb_iseof (const mbf_char_t mbc); -+ */ -+ -+#ifndef _MBFILE_H -+#define _MBFILE_H 1 -+ -+#include -+#include -+#include -+#include -+ -+/* Tru64 with Desktop Toolkit C has a bug: must be included before -+ . -+ BSD/OS 4.1 has a bug: and must be included before -+ . */ -+#include -+#include -+#include -+ -+#include "mbchar.h" -+ -+#ifndef _GL_INLINE_HEADER_BEGIN -+ #error "Please include config.h first." -+#endif -+_GL_INLINE_HEADER_BEGIN -+#ifndef MBFILE_INLINE -+# define MBFILE_INLINE _GL_INLINE -+#endif -+ -+struct mbfile_multi { -+ FILE *fp; -+ bool eof_seen; -+ bool have_pushback; -+ mbstate_t state; -+ unsigned int bufcount; -+ char buf[MBCHAR_BUF_SIZE]; -+ struct mbchar pushback; -+}; -+ -+MBFILE_INLINE void -+mbfile_multi_getc (struct mbchar *mbc, struct mbfile_multi *mbf) -+{ -+ size_t bytes; -+ -+ /* If EOF has already been seen, don't use getc. This matters if -+ mbf->fp is connected to an interactive tty. */ -+ if (mbf->eof_seen) -+ goto eof; -+ -+ /* Return character pushed back, if there is one. */ -+ if (mbf->have_pushback) -+ { -+ mb_copy (mbc, &mbf->pushback); -+ mbf->have_pushback = false; -+ return; -+ } -+ -+ /* Before using mbrtowc, we need at least one byte. */ -+ if (mbf->bufcount == 0) -+ { -+ int c = getc (mbf->fp); -+ if (c == EOF) -+ { -+ mbf->eof_seen = true; -+ goto eof; -+ } -+ mbf->buf[0] = (unsigned char) c; -+ mbf->bufcount++; -+ } -+ -+ /* Handle most ASCII characters quickly, without calling mbrtowc(). */ -+ if (mbf->bufcount == 1 && mbsinit (&mbf->state) && is_basic (mbf->buf[0])) -+ { -+ /* These characters are part of the basic character set. ISO C 99 -+ guarantees that their wide character code is identical to their -+ char code. */ -+ mbc->wc = mbc->buf[0] = mbf->buf[0]; -+ mbc->wc_valid = true; -+ mbc->ptr = &mbc->buf[0]; -+ mbc->bytes = 1; -+ mbf->bufcount = 0; -+ return; -+ } -+ -+ /* Use mbrtowc on an increasing number of bytes. Read only as many bytes -+ from mbf->fp as needed. This is needed to give reasonable interactive -+ behaviour when mbf->fp is connected to an interactive tty. */ -+ for (;;) -+ { -+ /* We don't know whether the 'mbrtowc' function updates the state when -+ it returns -2, - this is the ISO C 99 and glibc-2.2 behaviour - or -+ not - amended ANSI C, glibc-2.1 and Solaris 2.7 behaviour. We -+ don't have an autoconf test for this, yet. -+ The new behaviour would allow us to feed the bytes one by one into -+ mbrtowc. But the old behaviour forces us to feed all bytes since -+ the end of the last character into mbrtowc. Since we want to retry -+ with more bytes when mbrtowc returns -2, we must backup the state -+ before calling mbrtowc, because implementations with the new -+ behaviour will clobber it. */ -+ mbstate_t backup_state = mbf->state; -+ -+ bytes = mbrtowc (&mbc->wc, &mbf->buf[0], mbf->bufcount, &mbf->state); -+ -+ if (bytes == (size_t) -1) -+ { -+ /* An invalid multibyte sequence was encountered. */ -+ /* Return a single byte. */ -+ bytes = 1; -+ mbc->wc_valid = false; -+ break; -+ } -+ else if (bytes == (size_t) -2) -+ { -+ /* An incomplete multibyte character. */ -+ mbf->state = backup_state; -+ if (mbf->bufcount == MBCHAR_BUF_SIZE) -+ { -+ /* An overlong incomplete multibyte sequence was encountered. */ -+ /* Return a single byte. */ -+ bytes = 1; -+ mbc->wc_valid = false; -+ break; -+ } -+ else -+ { -+ /* Read one more byte and retry mbrtowc. */ -+ int c = getc (mbf->fp); -+ if (c == EOF) -+ { -+ /* An incomplete multibyte character at the end. */ -+ mbf->eof_seen = true; -+ bytes = mbf->bufcount; -+ mbc->wc_valid = false; -+ break; -+ } -+ mbf->buf[mbf->bufcount] = (unsigned char) c; -+ mbf->bufcount++; -+ } -+ } -+ else -+ { -+ if (bytes == 0) -+ { -+ /* A null wide character was encountered. */ -+ bytes = 1; -+ assert (mbf->buf[0] == '\0'); -+ assert (mbc->wc == 0); -+ } -+ mbc->wc_valid = true; -+ break; -+ } -+ } -+ -+ /* Return the multibyte sequence mbf->buf[0..bytes-1]. */ -+ mbc->ptr = &mbc->buf[0]; -+ memcpy (&mbc->buf[0], &mbf->buf[0], bytes); -+ mbc->bytes = bytes; -+ -+ mbf->bufcount -= bytes; -+ if (mbf->bufcount > 0) -+ { -+ /* It's not worth calling memmove() for so few bytes. */ -+ unsigned int count = mbf->bufcount; -+ char *p = &mbf->buf[0]; -+ -+ do -+ { -+ *p = *(p + bytes); -+ p++; -+ } -+ while (--count > 0); -+ } -+ return; -+ -+eof: -+ /* An mbchar_t with bytes == 0 is used to indicate EOF. */ -+ mbc->ptr = NULL; -+ mbc->bytes = 0; -+ mbc->wc_valid = false; -+ return; -+} -+ -+MBFILE_INLINE void -+mbfile_multi_ungetc (const struct mbchar *mbc, struct mbfile_multi *mbf) -+{ -+ mb_copy (&mbf->pushback, mbc); -+ mbf->have_pushback = true; -+} -+ -+typedef struct mbfile_multi mb_file_t; -+ -+typedef mbchar_t mbf_char_t; -+ -+#define mbf_init(mbf, stream) \ -+ ((mbf).fp = (stream), \ -+ (mbf).eof_seen = false, \ -+ (mbf).have_pushback = false, \ -+ memset (&(mbf).state, '\0', sizeof (mbstate_t)), \ -+ (mbf).bufcount = 0) -+ -+#define mbf_getc(mbc, mbf) mbfile_multi_getc (&(mbc), &(mbf)) -+ -+#define mbf_ungetc(mbc, mbf) mbfile_multi_ungetc (&(mbc), &(mbf)) -+ -+#define mb_iseof(mbc) ((mbc).bytes == 0) -+ -+#ifndef _GL_INLINE_HEADER_BEGIN -+ #error "Please include config.h first." -+#endif -+_GL_INLINE_HEADER_BEGIN -+ -+#endif /* _MBFILE_H */ -diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 -new file mode 100644 -index 0000000..8589902 ---- /dev/null -+++ b/m4/mbfile.m4 -@@ -0,0 +1,14 @@ -+# mbfile.m4 serial 7 -+dnl Copyright (C) 2005, 2008-2015 Free Software Foundation, Inc. -+dnl This file is free software; the Free Software Foundation -+dnl gives unlimited permission to copy and/or distribute it, -+dnl with or without modifications, as long as this notice is preserved. -+ -+dnl autoconf tests required for use of mbfile.h -+dnl From Bruno Haible. -+ -+AC_DEFUN([gl_MBFILE], -+[ -+ AC_REQUIRE([AC_TYPE_MBSTATE_T]) -+ : -+]) -diff --git a/src/expand.c b/src/expand.c -index 9fa2e10..380e020 100644 ---- a/src/expand.c -+++ b/src/expand.c -@@ -37,6 +37,9 @@ - #include - #include - #include -+ -+#include -+ - #include "system.h" - #include "die.h" - #include "xstrndup.h" -@@ -100,19 +103,19 @@ expand (void) - { - /* Input stream. */ - FILE *fp = next_file (NULL); -+ mb_file_t mbf; -+ mbf_char_t c; - - if (!fp) - return; - -+ mbf_init (mbf, fp); -+ - while (true) - { -- /* Input character, or EOF. */ -- int c; -- - /* If true, perform translations. */ - bool convert = true; - -- - /* The following variables have valid values only when CONVERT - is true: */ - -@@ -122,17 +125,23 @@ expand (void) - /* Index in TAB_LIST of next tab stop to examine. */ - size_t tab_index = 0; - -- - /* Convert a line of text. */ - - do - { -- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) -- continue; -+ do { -+ mbf_getc (c, mbf); -+ if (mb_iseof (c)) -+ { -+ mbf_init (mbf, fp = next_file (fp)); -+ continue; -+ } -+ } -+ while (false); - - if (convert) - { -- if (c == '\t') -+ if (mb_iseq (c, '\t')) - { - /* Column the next input tab stop is on. */ - uintmax_t next_tab_column; -@@ -151,32 +160,34 @@ expand (void) - if (putchar (' ') < 0) - die (EXIT_FAILURE, errno, _("write error")); - -- c = ' '; -+ mb_setascii (&c, ' '); - } -- else if (c == '\b') -+ else if (mb_iseq (c, '\b')) - { - /* Go back one column, and force recalculation of the - next tab stop. */ - column -= !!column; - tab_index -= !!tab_index; - } -- else -+ /* A leading control character could make us trip over. */ -+ else if (!mb_iscntrl (c)) - { -- column++; -+ column += mb_width (c); - if (!column) - die (EXIT_FAILURE, 0, _("input line is too long")); - } - -- convert &= convert_entire_line || !! isblank (c); -+ convert &= convert_entire_line || mb_isblank (c); - } - -- if (c < 0) -+ if (mb_iseof (c)) - return; - -- if (putchar (c) < 0) -+ mb_putc (c, stdout); -+ if (ferror (stdout)) - die (EXIT_FAILURE, errno, _("write error")); - } -- while (c != '\n'); -+ while (!mb_iseq (c, '\n')); - } - } - -diff --git a/src/unexpand.c b/src/unexpand.c -index 7801274..569a7ee 100644 ---- a/src/unexpand.c -+++ b/src/unexpand.c -@@ -38,6 +38,9 @@ - #include - #include - #include -+ -+#include -+ - #include "system.h" - #include "die.h" - #include "xstrndup.h" -@@ -107,11 +110,12 @@ unexpand (void) - { - /* Input stream. */ - FILE *fp = next_file (NULL); -+ mb_file_t mbf; - - /* The array of pending blanks. In non-POSIX locales, blanks can - include characters other than spaces, so the blanks must be - stored, not merely counted. */ -- char *pending_blank; -+ mbf_char_t *pending_blank; - - if (!fp) - return; -@@ -119,12 +123,14 @@ unexpand (void) - /* The worst case is a non-blank character, then one blank, then a - tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so - allocate MAX_COLUMN_WIDTH bytes to store the blanks. */ -- pending_blank = xmalloc (max_column_width); -+ pending_blank = xmalloc (max_column_width * sizeof (mbf_char_t)); -+ -+ mbf_init (mbf, fp); - - while (true) - { - /* Input character, or EOF. */ -- int c; -+ mbf_char_t c; - - /* If true, perform translations. */ - bool convert = true; -@@ -158,12 +164,19 @@ unexpand (void) - - do - { -- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) -- continue; -+ do { -+ mbf_getc (c, mbf); -+ if (mb_iseof (c)) -+ { -+ mbf_init (mbf, fp = next_file (fp)); -+ continue; -+ } -+ } -+ while (false); - - if (convert) - { -- bool blank = !! isblank (c); -+ bool blank = mb_isblank (c); - - if (blank) - { -@@ -180,16 +193,16 @@ unexpand (void) - if (next_tab_column < column) - die (EXIT_FAILURE, 0, _("input line is too long")); - -- if (c == '\t') -+ if (mb_iseq (c, '\t')) - { - column = next_tab_column; - - if (pending) -- pending_blank[0] = '\t'; -+ mb_setascii (&pending_blank[0], '\t'); - } - else - { -- column++; -+ column += mb_width (c); - - if (! (prev_blank && column == next_tab_column)) - { -@@ -197,13 +210,14 @@ unexpand (void) - will be replaced by tabs. */ - if (column == next_tab_column) - one_blank_before_tab_stop = true; -- pending_blank[pending++] = c; -+ mb_copy (&pending_blank[pending++], &c); - prev_blank = true; - continue; - } - - /* Replace the pending blanks by a tab or two. */ -- pending_blank[0] = c = '\t'; -+ mb_setascii (&c, '\t'); -+ mb_setascii (&pending_blank[0], '\t'); - } - - /* Discard pending blanks, unless it was a single -@@ -211,7 +225,7 @@ unexpand (void) - pending = one_blank_before_tab_stop; - } - } -- else if (c == '\b') -+ else if (mb_iseq (c, '\b')) - { - /* Go back one column, and force recalculation of the - next tab stop. */ -@@ -221,7 +235,7 @@ unexpand (void) - } - else - { -- column++; -+ column += mb_width (c); - if (!column) - die (EXIT_FAILURE, 0, _("input line is too long")); - } -@@ -229,8 +243,11 @@ unexpand (void) - if (pending) - { - if (pending > 1 && one_blank_before_tab_stop) -- pending_blank[0] = '\t'; -- if (fwrite (pending_blank, 1, pending, stdout) != pending) -+ mb_setascii (&pending_blank[0], '\t'); -+ -+ for (int n = 0; n < pending; ++n) -+ mb_putc (pending_blank[n], stdout); -+ if (ferror (stdout)) - die (EXIT_FAILURE, errno, _("write error")); - pending = 0; - one_blank_before_tab_stop = false; -@@ -240,16 +257,17 @@ unexpand (void) - convert &= convert_entire_line || blank; - } - -- if (c < 0) -+ if (mb_iseof (c)) - { - free (pending_blank); - return; - } - -- if (putchar (c) < 0) -+ mb_putc (c, stdout); -+ if (ferror (stdout)) - die (EXIT_FAILURE, errno, _("write error")); - } -- while (c != '\n'); -+ while (!mb_iseq (c, '\n')); - } - } - -diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh -new file mode 100755 -index 0000000..7971e18 ---- /dev/null -+++ b/tests/expand/mb.sh -@@ -0,0 +1,98 @@ -+#!/bin/sh -+ -+# Copyright (C) 2012-2015 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ expand -+ -+export LC_ALL=en_US.UTF-8 -+ -+#input containing multibyte characters -+cat <<\EOF > in || framework_failure_ -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+EOF -+env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ -+ -+cat <<\EOF > exp || framework_failure_ -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+ äöü . öüä. ä xx -+EOF -+ -+expand < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+#test characters with display widths != 1 -+env printf '12345678 -+e\t|ascii(1) -+\u00E9\t|composed(1) -+e\u0301\t|decomposed(1) -+\u3000\t|ideo-space(2) -+\uFF0D\t|full-hypen(2) -+' > in || framework_failure_ -+ -+env printf '12345678 -+e |ascii(1) -+\u00E9 |composed(1) -+e\u0301 |decomposed(1) -+\u3000 |ideo-space(2) -+\uFF0D |full-hypen(2) -+' > exp || framework_failure_ -+ -+expand < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+#shouldn't fail with "input line too long" -+#when a line starts with a control character -+env printf '\n' > in || framework_failure_ -+ -+expand < in > out || fail=1 -+compare in out > /dev/null 2>&1 || fail=1 -+ -+#non-Unicode characters interspersed between Unicode ones -+env printf '12345678 -+\t\xFF| -+\xFF\t| -+\t\xFFä| -+ä\xFF\t| -+\tä\xFF| -+\xFF\tä| -+äbcdef\xFF\t| -+' > in || framework_failure_ -+ -+env printf '12345678 -+ \xFF| -+\xFF | -+ \xFFä| -+ä\xFF | -+ ä\xFF| -+\xFF ä| -+äbcdef\xFF | -+' > exp || framework_failure_ -+ -+expand < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+exit $fail -diff --git a/tests/local.mk b/tests/local.mk -index 192f776..8053397 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -544,6 +544,7 @@ all_tests = \ - tests/du/threshold.sh \ - tests/du/trailing-slash.sh \ - tests/du/two-args.sh \ -+ tests/expand/mb.sh \ - tests/id/gnu-zero-uids.sh \ - tests/id/no-context.sh \ - tests/id/context.sh \ -@@ -684,6 +685,7 @@ all_tests = \ - tests/touch/read-only.sh \ - tests/touch/relative.sh \ - tests/touch/trailing-slash.sh \ -+ tests/unexpand/mb.sh \ - $(all_root_tests) - - # See tests/factor/create-test.sh. -diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh -new file mode 100755 -index 0000000..60d4c1a ---- /dev/null -+++ b/tests/unexpand/mb.sh -@@ -0,0 +1,97 @@ -+#!/bin/sh -+ -+# Copyright (C) 2012-2015 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ unexpand -+ -+export LC_ALL=en_US.UTF-8 -+ -+#input containing multibyte characters -+cat > in <<\EOF -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+ äöü . öüä. ä xx -+EOF -+ -+cat > exp <<\EOF -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+ äöü . öüä. ä xx -+EOF -+ -+unexpand -a < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+#test characters with a display width larger than 1 -+ -+env printf '12345678 -+e |ascii(1) -+\u00E9 |composed(1) -+e\u0301 |decomposed(1) -+\u3000 |ideo-space(2) -+\uFF0D |full-hypen(2) -+' > in || framework_failure_ -+ -+env printf '12345678 -+e\t|ascii(1) -+\u00E9\t|composed(1) -+e\u0301\t|decomposed(1) -+\u3000\t|ideo-space(2) -+\uFF0D\t|full-hypen(2) -+' > exp || framework_failure_ -+ -+unexpand -a < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+#test input where a blank of width > 1 is not being substituted -+in="$(LC_ALL=en_US.UTF-8 printf ' \u3000 ö ü ß')" -+exp='   ö ü ß' -+ -+unexpand -a < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+#non-Unicode characters interspersed between Unicode ones -+env printf '12345678 -+ \xFF| -+\xFF | -+ \xFFä| -+ä\xFF | -+ ä\xFF| -+\xFF ä| -+äbcdef\xFF | -+' > in || framework_failure_ -+ -+env printf '12345678 -+\t\xFF| -+\xFF\t| -+\t\xFFä| -+ä\xFF\t| -+\tä\xFF| -+\xFF\tä| -+äbcdef\xFF\t| -+' > exp || framework_failure_ -+ -+unexpand -a < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 --- -2.7.4 - diff --git a/coreutils-i18n-fix-unexpand.patch b/coreutils-i18n-fix-unexpand.patch deleted file mode 100644 index f0c347c..0000000 --- a/coreutils-i18n-fix-unexpand.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 02424bfcd719bbaa695f4e1c3ef17ad91b0d23c0 Mon Sep 17 00:00:00 2001 -From: Lubomir Rintel -Date: Thu, 28 Jan 2016 20:57:22 +0100 -Subject: [PATCH] unexpand: fix blank line handling - - echo '' |./src/unexpand -a - -Really? ---- - src/unexpand.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/unexpand.c b/src/unexpand.c -index 569a7ee..3bbbd66 100644 ---- a/src/unexpand.c -+++ b/src/unexpand.c -@@ -233,7 +233,7 @@ unexpand (void) - next_tab_column = column; - tab_index -= !!tab_index; - } -- else -+ else if (!mb_iseq (c, '\n')) - { - column += mb_width (c); - if (!column) --- -2.7.4 - diff --git a/coreutils-i18n-fix2-expand-unexpand.patch b/coreutils-i18n-fix2-expand-unexpand.patch deleted file mode 100644 index b34d7b7..0000000 --- a/coreutils-i18n-fix2-expand-unexpand.patch +++ /dev/null @@ -1,108 +0,0 @@ -diff --git a/src/expand.c b/src/expand.c -index 380e020..310b349 100644 ---- a/src/expand.c -+++ b/src/expand.c -@@ -129,15 +129,19 @@ expand (void) - - do - { -- do { -+ while (true) { - mbf_getc (c, mbf); -- if (mb_iseof (c)) -+ if ((mb_iseof (c)) && (fp = next_file (fp))) - { -- mbf_init (mbf, fp = next_file (fp)); -+ mbf_init (mbf, fp); - continue; - } -+ else -+ { -+ break; -+ } - } -- while (false); -+ - - if (convert) - { -diff --git a/src/unexpand.c b/src/unexpand.c -index 3bbbd66..863a90a 100644 ---- a/src/unexpand.c -+++ b/src/unexpand.c -@@ -164,15 +164,19 @@ unexpand (void) - - do - { -- do { -+ while (true) { - mbf_getc (c, mbf); -- if (mb_iseof (c)) -+ if ((mb_iseof (c)) && (fp = next_file (fp))) - { -- mbf_init (mbf, fp = next_file (fp)); -+ mbf_init (mbf, fp); - continue; - } -+ else -+ { -+ break; -+ } - } -- while (false); -+ - - if (convert) - { -diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh -index 7971e18..031be7a 100755 ---- a/tests/expand/mb.sh -+++ b/tests/expand/mb.sh -@@ -44,6 +44,20 @@ EOF - expand < in > out || fail=1 - compare exp out > /dev/null 2>&1 || fail=1 - -+#multiple files as an input -+cat <<\EOF >> exp || framework_failure_ -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+ äöü . öüä. ä xx -+EOF -+ -+expand ./in ./in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ - #test characters with display widths != 1 - env printf '12345678 - e\t|ascii(1) -diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh -index 60d4c1a..8d75652 100755 ---- a/tests/unexpand/mb.sh -+++ b/tests/unexpand/mb.sh -@@ -44,6 +44,22 @@ EOF - unexpand -a < in > out || fail=1 - compare exp out > /dev/null 2>&1 || fail=1 - -+ -+#multiple files as an input -+cat >> exp <<\EOF -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+ äöü . öüä. ä xx -+EOF -+ -+ -+unexpand -a ./in ./in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ - #test characters with a display width larger than 1 - - env printf '12345678 diff --git a/coreutils-i18n-fold-newline.patch b/coreutils-i18n-fold-newline.patch deleted file mode 100644 index f7286ef..0000000 --- a/coreutils-i18n-fold-newline.patch +++ /dev/null @@ -1,80 +0,0 @@ -From ff424639fe863cbd6963add1a79b97290c1606c6 Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Fri, 3 Feb 2017 12:26:53 +0100 -Subject: [PATCH] fold.c: preserve new-lines in mutlibyte text - ---- - src/fold.c | 49 ++++++++++++++++++++++++------------------------- - 1 file changed, 24 insertions(+), 25 deletions(-) - -diff --git a/src/fold.c b/src/fold.c -index d23edd5..8c232a7 100644 ---- a/src/fold.c -+++ b/src/fold.c -@@ -342,39 +342,38 @@ fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) - } - - rescan: -- if (operating_mode == byte_mode) /* byte mode */ -+ if (convfail) -+ increment = 1; -+ else if (wc == L'\n') -+ { -+ /* preserve newline */ -+ fwrite (line_out, sizeof(char), offset_out, stdout); -+ START_NEW_LINE; -+ continue; -+ } -+ else if (operating_mode == byte_mode) /* byte mode */ - increment = mblength; - else if (operating_mode == character_mode) /* character mode */ - increment = 1; -- else /* column mode */ -+ else /* column mode */ - { -- if (convfail) -- increment = 1; -- else -+ switch (wc) - { -- switch (wc) -- { -- case L'\n': -- fwrite (line_out, sizeof(char), offset_out, stdout); -- START_NEW_LINE; -- continue; -+ case L'\b': -+ increment = (column > 0) ? -1 : 0; -+ break; - -- case L'\b': -- increment = (column > 0) ? -1 : 0; -- break; -+ case L'\r': -+ increment = -1 * column; -+ break; - -- case L'\r': -- increment = -1 * column; -- break; -+ case L'\t': -+ increment = 8 - column % 8; -+ break; - -- case L'\t': -- increment = 8 - column % 8; -- break; -- -- default: -- increment = wcwidth (wc); -- increment = (increment < 0) ? 0 : increment; -- } -+ default: -+ increment = wcwidth (wc); -+ increment = (increment < 0) ? 0 : increment; - } - } - --- -2.7.4 - diff --git a/coreutils-i18n-sort-human.patch b/coreutils-i18n-sort-human.patch deleted file mode 100644 index 6752493..0000000 --- a/coreutils-i18n-sort-human.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 3976ef5a20369d8b490907ab2cba2d617305a5e0 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Mon, 30 May 2016 16:19:20 +0200 -Subject: [PATCH] sort: do not use static array 'blanks' in human_numcompare() - -... because the array is not initialized with MB locales. Note this is -rather a conservative fix. I plan to do more cleanup of the i18n patch -in Fedora to prevent mistakes like this in future updates of coreutils. ---- - src/sort.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/src/sort.c b/src/sort.c -index 9e07ad8..e47b039 100644 ---- a/src/sort.c -+++ b/src/sort.c -@@ -2304,12 +2304,10 @@ find_unit_order (char const *number) - < K/k < M < G < T < P < E < Z < Y */ - - static int --human_numcompare (char const *a, char const *b) -+human_numcompare (char *a, char *b) - { -- while (blanks[to_uchar (*a)]) -- a++; -- while (blanks[to_uchar (*b)]) -- b++; -+ skipblanks(&a, a + strlen(a)); -+ skipblanks(&b, b + strlen(b)); - - int diff = find_unit_order (a) - find_unit_order (b); - return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); --- -2.5.5 - diff --git a/coreutils-i18n-un-expand-BOM.patch b/coreutils-i18n-un-expand-BOM.patch deleted file mode 100644 index 6210ce7..0000000 --- a/coreutils-i18n-un-expand-BOM.patch +++ /dev/null @@ -1,456 +0,0 @@ -From 7a7c776a4e228d180e74614fd8c8afcad5d4bdf7 Mon Sep 17 00:00:00 2001 -From: Jakub Martisko -Date: Thu, 7 Jul 2016 12:53:26 +0200 -Subject: [PATCH] coreutils-i18n-un-expand-BOM.patch - ---- - src/expand-common.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++ - src/expand-common.h | 12 ++++++ - src/expand.c | 45 +++++++++++++++++++- - src/unexpand.c | 43 ++++++++++++++++++- - tests/expand/mb.sh | 71 ++++++++++++++++++++++++++++++++ - tests/unexpand/mb.sh | 59 ++++++++++++++++++++++++++ - 6 files changed, 342 insertions(+), 2 deletions(-) - -diff --git a/src/expand-common.c b/src/expand-common.c -index 4657e46..97cbb09 100644 ---- a/src/expand-common.c -+++ b/src/expand-common.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include "system.h" - #include "die.h" - #include "error.h" -@@ -126,6 +127,119 @@ set_increment_size (uintmax_t tabval) - return ok; - } - -+extern int -+set_utf_locale (void) -+{ -+ /*try using some predefined locale */ -+ const char* predef_locales[] = {"C.UTF8","en_US.UTF8","en_GB.UTF8"}; -+ -+ const int predef_locales_count=3; -+ for (int i=0;ibufcount=0; -+ if (c == 0xEF) -+ { -+ c=fgetc(fp); -+ } -+ else -+ { -+ if (c != EOF) -+ { -+ ungetc(c,fp); -+ } -+ return false; -+ } -+ -+ if (c == 0xBB) -+ { -+ c=fgetc(fp); -+ } -+ else -+ { -+ if ( c!= EOF ) -+ { -+ mbf->buf[0]=(unsigned char) 0xEF; -+ mbf->bufcount=1; -+ ungetc(c,fp); -+ return false; -+ } -+ else -+ { -+ ungetc(0xEF,fp); -+ return false; -+ } -+ } -+ if (c == 0xBF) -+ { -+ mbf->bufcount=0; -+ return true; -+ } -+ else -+ { -+ if (c != EOF) -+ { -+ mbf->buf[0]=(unsigned char) 0xEF; -+ mbf->buf[1]=(unsigned char) 0xBB; -+ mbf->bufcount=2; -+ ungetc(c,fp); -+ return false; -+ } -+ else -+ { -+ mbf->buf[0]=(unsigned char) 0xEF; -+ mbf->bufcount=1; -+ ungetc(0xBB,fp); -+ return false; -+ } -+ } -+ return false; -+} -+ -+extern void -+print_bom(void) -+{ -+ putc (0xEF, stdout); -+ putc (0xBB, stdout); -+ putc (0xBF, stdout); -+} -+ - /* Add the comma or blank separated list of tab stops STOPS - to the list of tab stops. */ - extern void -diff --git a/src/expand-common.h b/src/expand-common.h -index 8cb2079..763bfda 100644 ---- a/src/expand-common.h -+++ b/src/expand-common.h -@@ -34,6 +34,18 @@ extern size_t max_column_width; - /* The desired exit status. */ - extern int exit_status; - -+extern int -+set_utf_locale (void); -+ -+extern bool -+check_utf_locale(void); -+ -+extern bool -+check_bom(FILE* fp, mb_file_t *mbf); -+ -+extern void -+print_bom(void); -+ - /* Add tab stop TABVAL to the end of 'tab_list'. */ - extern void - add_tab_stop (uintmax_t tabval); -diff --git a/src/expand.c b/src/expand.c -index 310b349..4136824 100644 ---- a/src/expand.c -+++ b/src/expand.c -@@ -103,11 +103,33 @@ expand (void) - FILE *fp = next_file (NULL); - mb_file_t mbf; - mbf_char_t c; -+ /* True if the starting locale is utf8. */ -+ bool using_utf_locale; -+ -+ /* True if the first file contains BOM header. */ -+ bool found_bom; -+ using_utf_locale=check_utf_locale(); - - if (!fp) - return; -- - mbf_init (mbf, fp); -+ found_bom=check_bom(fp,&mbf); -+ -+ if (using_utf_locale == false && found_bom == true) -+ { -+ /*try using some predefined locale */ -+ -+ if (set_utf_locale () != 0) -+ { -+ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); -+ } -+ } -+ -+ -+ if (found_bom == true) -+ { -+ print_bom(); -+ } - - while (true) - { -@@ -132,6 +154,27 @@ expand (void) - if ((mb_iseof (c)) && (fp = next_file (fp))) - { - mbf_init (mbf, fp); -+ if (fp!=NULL) -+ { -+ if (check_bom(fp,&mbf)==true) -+ { -+ /*Not the first file - check BOM header*/ -+ if (using_utf_locale==false && found_bom==false) -+ { -+ /*BOM header in subsequent file but not in the first one. */ -+ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); -+ } -+ } -+ else -+ { -+ if(using_utf_locale==false && found_bom==true) -+ { -+ /*First file conatined BOM header - locale was switched to UTF -+ *all subsequent files should contain BOM. */ -+ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); -+ } -+ } -+ } - continue; - } - else -diff --git a/src/unexpand.c b/src/unexpand.c -index 863a90a..5681b58 100644 ---- a/src/unexpand.c -+++ b/src/unexpand.c -@@ -116,16 +116,36 @@ unexpand (void) - include characters other than spaces, so the blanks must be - stored, not merely counted. */ - mbf_char_t *pending_blank; -+ /* True if the starting locale is utf8. */ -+ bool using_utf_locale; -+ -+ /* True if the first file contains BOM header. */ -+ bool found_bom; -+ using_utf_locale=check_utf_locale(); - - if (!fp) - return; -+ mbf_init (mbf, fp); -+ found_bom=check_bom(fp,&mbf); -+ -+ if (using_utf_locale == false && found_bom == true) -+ { -+ /*try using some predefined locale */ - -+ if (set_utf_locale () != 0) -+ { -+ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); -+ } -+ } - /* The worst case is a non-blank character, then one blank, then a - tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so - allocate MAX_COLUMN_WIDTH bytes to store the blanks. */ - pending_blank = xmalloc (max_column_width * sizeof (mbf_char_t)); - -- mbf_init (mbf, fp); -+ if (found_bom == true) -+ { -+ print_bom(); -+ } - - while (true) - { -@@ -169,6 +189,27 @@ unexpand (void) - if ((mb_iseof (c)) && (fp = next_file (fp))) - { - mbf_init (mbf, fp); -+ if (fp!=NULL) -+ { -+ if (check_bom(fp,&mbf)==true) -+ { -+ /*Not the first file - check BOM header*/ -+ if (using_utf_locale==false && found_bom==false) -+ { -+ /*BOM header in subsequent file but not in the first one. */ -+ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); -+ } -+ } -+ else -+ { -+ if(using_utf_locale==false && found_bom==true) -+ { -+ /*First file conatined BOM header - locale was switched to UTF -+ *all subsequent files should contain BOM. */ -+ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); -+ } -+ } -+ } - continue; - } - else -diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh -index 031be7a..1621c84 100755 ---- a/tests/expand/mb.sh -+++ b/tests/expand/mb.sh -@@ -109,4 +109,75 @@ env printf '12345678 - expand < in > out || fail=1 - compare exp out > /dev/null 2>&1 || fail=1 - -+ -+ -+#BOM header test 1 -+printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+EOF -+env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ -+ -+printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+ äöü . öüä. ä xx -+EOF -+ -+ -+expand < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+LANG=C expand < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+LC_ALL=C expand < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+ -+printf '\xEF\xBB\xBF' > in1; cat <<\EOF >> in1 || framework_failure_ -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+EOF -+env printf ' äöü\t. öüä. \tä xx\n' >> in1 || framework_failure_ -+ -+ -+printf '\xEF\xBB\xBF' > exp; cat <<\EOF >> exp || framework_failure_ -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+ äöü . öüä. ä xx -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+ äöü . öüä. ä xx -+EOF -+ -+expand in1 in1 > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+LANG=C expand in1 in1 > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+LC_ALL=C expand in1 in1 > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ - exit $fail -diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh -index 8d75652..9d4ee3e 100755 ---- a/tests/unexpand/mb.sh -+++ b/tests/unexpand/mb.sh -@@ -111,3 +111,62 @@ env printf '12345678 - - unexpand -a < in > out || fail=1 - compare exp out > /dev/null 2>&1 || fail=1 -+ -+#BOM header test 1 -+printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+ äöü . öüä. ä xx -+EOF -+env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ -+ -+printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+ äöü . öüä. ä xx -+EOF -+ -+unexpand < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+LANG=C unexpand < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+LC_ALL=C unexpand < in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+ -+printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+ äöü . öüä. ä xx -+1234567812345678123456781 -+. . . . -+a b c d -+. . . . -+ä ö ü ß -+. . . . -+ äöü . öüä. ä xx -+EOF -+ -+ -+unexpand in in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+LANG=C unexpand in in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 -+ -+LC_ALL=C unexpand in in > out || fail=1 -+compare exp out > /dev/null 2>&1 || fail=1 --- -2.9.3 - diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index e3428d9..4ff0911 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,37 +1,80 @@ -From 29117b2d07af00f4d4b87cf778e4294588ab1a83 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Thu, 1 Dec 2016 15:10:04 +0100 +From 01010419a6499768563e7b2f3fd56cf16edda75e Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Mon, 4 Oct 2021 08:54:37 +0200 Subject: [PATCH] coreutils-i18n.patch -TODO: merge upstream --- + bootstrap.conf | 1 + + configure.ac | 2 + lib/linebuffer.h | 8 + - src/fold.c | 308 ++++++++++++++++-- - src/join.c | 359 ++++++++++++++++++--- - src/pr.c | 443 ++++++++++++++++++++++--- - src/sort.c | 764 +++++++++++++++++++++++++++++++++++++++++--- - src/uniq.c | 265 ++++++++++++++- + lib/mbfile.c | 3 + + lib/mbfile.h | 255 ++++++++++++ + m4/mbfile.m4 | 14 + + src/cut.c | 508 +++++++++++++++++++++-- + src/expand-common.c | 114 ++++++ + src/expand-common.h | 12 + + src/expand.c | 90 +++- + src/fold.c | 312 ++++++++++++-- + src/join.c | 359 ++++++++++++++-- + src/local.mk | 4 +- + src/pr.c | 443 ++++++++++++++++++-- + src/sort.c | 792 +++++++++++++++++++++++++++++++++--- + src/unexpand.c | 101 ++++- + src/uniq.c | 119 +++++- + tests/Coreutils.pm | 3 + + tests/expand/mb.sh | 183 +++++++++ tests/i18n/sort.sh | 29 ++ - tests/local.mk | 2 + - tests/misc/expand.pl | 42 +++ + tests/local.mk | 4 + + tests/misc/expand.pl | 42 ++ tests/misc/fold.pl | 50 ++- tests/misc/join.pl | 50 +++ - tests/misc/sort-mb-tests.sh | 45 +++ - tests/misc/sort-merge.pl | 42 +++ - tests/misc/sort.pl | 40 ++- - tests/misc/unexpand.pl | 39 +++ - tests/misc/uniq.pl | 55 ++++ + tests/misc/sort-mb-tests.sh | 45 ++ + tests/misc/sort-merge.pl | 42 ++ + tests/misc/sort.pl | 40 +- + tests/misc/unexpand.pl | 39 ++ + tests/misc/uniq.pl | 55 +++ tests/pr/pr-tests.pl | 49 +++ - 17 files changed, 2430 insertions(+), 160 deletions(-) + tests/unexpand/mb.sh | 172 ++++++++ + 31 files changed, 3698 insertions(+), 242 deletions(-) + create mode 100644 lib/mbfile.c + create mode 100644 lib/mbfile.h + create mode 100644 m4/mbfile.m4 + create mode 100755 tests/expand/mb.sh create mode 100755 tests/i18n/sort.sh create mode 100755 tests/misc/sort-mb-tests.sh + create mode 100755 tests/unexpand/mb.sh +diff --git a/bootstrap.conf b/bootstrap.conf +index c1399e3..60b39cf 100644 +--- a/bootstrap.conf ++++ b/bootstrap.conf +@@ -162,6 +162,7 @@ gnulib_modules=" + maintainer-makefile + malloc-gnu + manywarnings ++ mbfile + mbrlen + mbrtowc + mbsalign +diff --git a/configure.ac b/configure.ac +index 7e4afc9..4656a35 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -476,6 +476,8 @@ fi + # I'm leaving it here for now. This whole thing needs to be modernized... + gl_WINSIZE_IN_PTEM + ++gl_MBFILE ++ + gl_HEADER_TIOCGWINSZ_IN_TERMIOS_H + + if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ diff --git a/lib/linebuffer.h b/lib/linebuffer.h -index 64181af..9b8fe5a 100644 +index 07d45ca..af62e6c 100644 --- a/lib/linebuffer.h +++ b/lib/linebuffer.h -@@ -21,6 +21,11 @@ - +@@ -22,6 +22,11 @@ + # include "idx.h" # include +/* Get mbstate_t. */ @@ -42,9 +85,9 @@ index 64181af..9b8fe5a 100644 /* A 'struct linebuffer' holds a line of text. */ struct linebuffer -@@ -28,6 +33,9 @@ struct linebuffer - size_t size; /* Allocated. */ - size_t length; /* Used. */ +@@ -29,6 +34,9 @@ struct linebuffer + idx_t size; /* Allocated. */ + idx_t length; /* Used. */ char *buffer; +# if HAVE_WCHAR_H + mbstate_t state; @@ -52,8 +95,1269 @@ index 64181af..9b8fe5a 100644 }; /* Initialize linebuffer LINEBUFFER for use. */ +diff --git a/lib/mbfile.c b/lib/mbfile.c +new file mode 100644 +index 0000000..b0a468e +--- /dev/null ++++ b/lib/mbfile.c +@@ -0,0 +1,3 @@ ++#include ++#define MBFILE_INLINE _GL_EXTERN_INLINE ++#include "mbfile.h" +diff --git a/lib/mbfile.h b/lib/mbfile.h +new file mode 100644 +index 0000000..11f1b12 +--- /dev/null ++++ b/lib/mbfile.h +@@ -0,0 +1,255 @@ ++/* Multibyte character I/O: macros for multi-byte encodings. ++ Copyright (C) 2001, 2005, 2009-2015 Free Software Foundation, Inc. ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++/* Written by Mitsuru Chinen ++ and Bruno Haible . */ ++ ++/* The macros in this file implement multi-byte character input from a ++ stream. ++ ++ mb_file_t ++ is the type for multibyte character input stream, usable for variable ++ declarations. ++ ++ mbf_char_t ++ is the type for multibyte character or EOF, usable for variable ++ declarations. ++ ++ mbf_init (mbf, stream) ++ initializes the MB_FILE for reading from stream. ++ ++ mbf_getc (mbc, mbf) ++ reads the next multibyte character from mbf and stores it in mbc. ++ ++ mb_iseof (mbc) ++ returns true if mbc represents the EOF value. ++ ++ Here are the function prototypes of the macros. ++ ++ extern void mbf_init (mb_file_t mbf, FILE *stream); ++ extern void mbf_getc (mbf_char_t mbc, mb_file_t mbf); ++ extern bool mb_iseof (const mbf_char_t mbc); ++ */ ++ ++#ifndef _MBFILE_H ++#define _MBFILE_H 1 ++ ++#include ++#include ++#include ++#include ++ ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.1 has a bug: and must be included before ++ . */ ++#include ++#include ++#include ++ ++#include "mbchar.h" ++ ++#ifndef _GL_INLINE_HEADER_BEGIN ++ #error "Please include config.h first." ++#endif ++_GL_INLINE_HEADER_BEGIN ++#ifndef MBFILE_INLINE ++# define MBFILE_INLINE _GL_INLINE ++#endif ++ ++struct mbfile_multi { ++ FILE *fp; ++ bool eof_seen; ++ bool have_pushback; ++ mbstate_t state; ++ unsigned int bufcount; ++ char buf[MBCHAR_BUF_SIZE]; ++ struct mbchar pushback; ++}; ++ ++MBFILE_INLINE void ++mbfile_multi_getc (struct mbchar *mbc, struct mbfile_multi *mbf) ++{ ++ size_t bytes; ++ ++ /* If EOF has already been seen, don't use getc. This matters if ++ mbf->fp is connected to an interactive tty. */ ++ if (mbf->eof_seen) ++ goto eof; ++ ++ /* Return character pushed back, if there is one. */ ++ if (mbf->have_pushback) ++ { ++ mb_copy (mbc, &mbf->pushback); ++ mbf->have_pushback = false; ++ return; ++ } ++ ++ /* Before using mbrtowc, we need at least one byte. */ ++ if (mbf->bufcount == 0) ++ { ++ int c = getc (mbf->fp); ++ if (c == EOF) ++ { ++ mbf->eof_seen = true; ++ goto eof; ++ } ++ mbf->buf[0] = (unsigned char) c; ++ mbf->bufcount++; ++ } ++ ++ /* Handle most ASCII characters quickly, without calling mbrtowc(). */ ++ if (mbf->bufcount == 1 && mbsinit (&mbf->state) && is_basic (mbf->buf[0])) ++ { ++ /* These characters are part of the basic character set. ISO C 99 ++ guarantees that their wide character code is identical to their ++ char code. */ ++ mbc->wc = mbc->buf[0] = mbf->buf[0]; ++ mbc->wc_valid = true; ++ mbc->ptr = &mbc->buf[0]; ++ mbc->bytes = 1; ++ mbf->bufcount = 0; ++ return; ++ } ++ ++ /* Use mbrtowc on an increasing number of bytes. Read only as many bytes ++ from mbf->fp as needed. This is needed to give reasonable interactive ++ behaviour when mbf->fp is connected to an interactive tty. */ ++ for (;;) ++ { ++ /* We don't know whether the 'mbrtowc' function updates the state when ++ it returns -2, - this is the ISO C 99 and glibc-2.2 behaviour - or ++ not - amended ANSI C, glibc-2.1 and Solaris 2.7 behaviour. We ++ don't have an autoconf test for this, yet. ++ The new behaviour would allow us to feed the bytes one by one into ++ mbrtowc. But the old behaviour forces us to feed all bytes since ++ the end of the last character into mbrtowc. Since we want to retry ++ with more bytes when mbrtowc returns -2, we must backup the state ++ before calling mbrtowc, because implementations with the new ++ behaviour will clobber it. */ ++ mbstate_t backup_state = mbf->state; ++ ++ bytes = mbrtowc (&mbc->wc, &mbf->buf[0], mbf->bufcount, &mbf->state); ++ ++ if (bytes == (size_t) -1) ++ { ++ /* An invalid multibyte sequence was encountered. */ ++ /* Return a single byte. */ ++ bytes = 1; ++ mbc->wc_valid = false; ++ break; ++ } ++ else if (bytes == (size_t) -2) ++ { ++ /* An incomplete multibyte character. */ ++ mbf->state = backup_state; ++ if (mbf->bufcount == MBCHAR_BUF_SIZE) ++ { ++ /* An overlong incomplete multibyte sequence was encountered. */ ++ /* Return a single byte. */ ++ bytes = 1; ++ mbc->wc_valid = false; ++ break; ++ } ++ else ++ { ++ /* Read one more byte and retry mbrtowc. */ ++ int c = getc (mbf->fp); ++ if (c == EOF) ++ { ++ /* An incomplete multibyte character at the end. */ ++ mbf->eof_seen = true; ++ bytes = mbf->bufcount; ++ mbc->wc_valid = false; ++ break; ++ } ++ mbf->buf[mbf->bufcount] = (unsigned char) c; ++ mbf->bufcount++; ++ } ++ } ++ else ++ { ++ if (bytes == 0) ++ { ++ /* A null wide character was encountered. */ ++ bytes = 1; ++ assert (mbf->buf[0] == '\0'); ++ assert (mbc->wc == 0); ++ } ++ mbc->wc_valid = true; ++ break; ++ } ++ } ++ ++ /* Return the multibyte sequence mbf->buf[0..bytes-1]. */ ++ mbc->ptr = &mbc->buf[0]; ++ memcpy (&mbc->buf[0], &mbf->buf[0], bytes); ++ mbc->bytes = bytes; ++ ++ mbf->bufcount -= bytes; ++ if (mbf->bufcount > 0) ++ { ++ /* It's not worth calling memmove() for so few bytes. */ ++ unsigned int count = mbf->bufcount; ++ char *p = &mbf->buf[0]; ++ ++ do ++ { ++ *p = *(p + bytes); ++ p++; ++ } ++ while (--count > 0); ++ } ++ return; ++ ++eof: ++ /* An mbchar_t with bytes == 0 is used to indicate EOF. */ ++ mbc->ptr = NULL; ++ mbc->bytes = 0; ++ mbc->wc_valid = false; ++ return; ++} ++ ++MBFILE_INLINE void ++mbfile_multi_ungetc (const struct mbchar *mbc, struct mbfile_multi *mbf) ++{ ++ mb_copy (&mbf->pushback, mbc); ++ mbf->have_pushback = true; ++} ++ ++typedef struct mbfile_multi mb_file_t; ++ ++typedef mbchar_t mbf_char_t; ++ ++#define mbf_init(mbf, stream) \ ++ ((mbf).fp = (stream), \ ++ (mbf).eof_seen = false, \ ++ (mbf).have_pushback = false, \ ++ memset (&(mbf).state, '\0', sizeof (mbstate_t)), \ ++ (mbf).bufcount = 0) ++ ++#define mbf_getc(mbc, mbf) mbfile_multi_getc (&(mbc), &(mbf)) ++ ++#define mbf_ungetc(mbc, mbf) mbfile_multi_ungetc (&(mbc), &(mbf)) ++ ++#define mb_iseof(mbc) ((mbc).bytes == 0) ++ ++#ifndef _GL_INLINE_HEADER_BEGIN ++ #error "Please include config.h first." ++#endif ++_GL_INLINE_HEADER_BEGIN ++ ++#endif /* _MBFILE_H */ +diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 +new file mode 100644 +index 0000000..8589902 +--- /dev/null ++++ b/m4/mbfile.m4 +@@ -0,0 +1,14 @@ ++# mbfile.m4 serial 7 ++dnl Copyright (C) 2005, 2008-2015 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++dnl autoconf tests required for use of mbfile.h ++dnl From Bruno Haible. ++ ++AC_DEFUN([gl_MBFILE], ++[ ++ AC_REQUIRE([AC_TYPE_MBSTATE_T]) ++ : ++]) +diff --git a/src/cut.c b/src/cut.c +index 6fd8978..faef877 100644 +--- a/src/cut.c ++++ b/src/cut.c +@@ -28,6 +28,11 @@ + #include + #include + #include ++ ++/* Get mbstate_t, mbrtowc(). */ ++#if HAVE_WCHAR_H ++# include ++#endif + #include "system.h" + + #include "error.h" +@@ -37,6 +42,18 @@ + + #include "set-fields.h" + ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC ++ installation; work around this configuration error. */ ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 ++# undef MB_LEN_MAX ++# define MB_LEN_MAX 16 ++#endif ++ ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ ++#if HAVE_MBRTOWC && defined mbstate_t ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) ++#endif ++ + /* The official name of this program (e.g., no 'g' prefix). */ + #define PROGRAM_NAME "cut" + +@@ -53,6 +70,52 @@ + } \ + while (0) + ++/* Refill the buffer BUF to get a multibyte character. */ ++#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM) \ ++ do \ ++ { \ ++ if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM)) \ ++ { \ ++ memmove (BUF, BUFPOS, BUFLEN); \ ++ BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \ ++ BUFPOS = BUF; \ ++ } \ ++ } \ ++ while (0) ++ ++/* Get wide character on BUFPOS. BUFPOS is not included after that. ++ If byte sequence is not valid as a character, CONVFAIL is true. Otherwise false. */ ++#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ ++ do \ ++ { \ ++ mbstate_t state_bak; \ ++ \ ++ if (BUFLEN < 1) \ ++ { \ ++ WC = WEOF; \ ++ break; \ ++ } \ ++ \ ++ /* Get a wide character. */ \ ++ CONVFAIL = false; \ ++ state_bak = STATE; \ ++ MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \ ++ \ ++ switch (MBLENGTH) \ ++ { \ ++ case (size_t)-1: \ ++ case (size_t)-2: \ ++ CONVFAIL = true; \ ++ STATE = state_bak; \ ++ /* Fall througn. */ \ ++ \ ++ case 0: \ ++ MBLENGTH = 1; \ ++ break; \ ++ } \ ++ } \ ++ while (0) ++ + + /* Pointer inside RP. When checking if a byte or field is selected + by a finite range, we check if it is between CURRENT_RP.LO +@@ -60,6 +123,9 @@ + CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ + static struct field_range_pair *current_rp; + ++/* Length of the delimiter given as argument to -d. */ ++size_t delimlen; ++ + /* This buffer is used to support the semantics of the -s option + (or lack of same) when the specified field list includes (does + not include) the first field. In both of those cases, the entire +@@ -72,6 +138,29 @@ static char *field_1_buffer; + /* The number of bytes allocated for FIELD_1_BUFFER. */ + static size_t field_1_bufsize; + ++enum operating_mode ++ { ++ undefined_mode, ++ ++ /* Output bytes that are at the given positions. */ ++ byte_mode, ++ ++ /* Output characters that are at the given positions. */ ++ character_mode, ++ ++ /* Output the given delimiter-separated fields. */ ++ field_mode ++ }; ++ ++static enum operating_mode operating_mode; ++ ++/* If nonzero, when in byte mode, don't split multibyte characters. */ ++static int byte_mode_character_aware; ++ ++/* If nonzero, the function for single byte locale is work ++ if this program runs on multibyte locale. */ ++static int force_singlebyte_mode; ++ + /* If true do not output lines containing no delimiter characters. + Otherwise, all such lines are printed. This option is valid only + with field mode. */ +@@ -83,10 +172,16 @@ static bool complement; + + /* The delimiter character for field mode. */ + static unsigned char delim; ++#if HAVE_WCHAR_H ++static wchar_t wcdelim; ++#endif + + /* The delimiter for each line/record. */ + static unsigned char line_delim = '\n'; + ++/* True if the --output-delimiter=STRING option was specified. */ ++static bool output_delimiter_specified; ++ + /* The length of output_delimiter_string. */ + static size_t output_delimiter_length; + +@@ -94,9 +189,6 @@ static size_t output_delimiter_length; + string consisting of the input delimiter. */ + static char *output_delimiter_string; + +-/* The output delimiter string contents, if the default. */ +-static char output_delimiter_default[1]; +- + /* True if we have ever read standard input. */ + static bool have_read_stdin; + +@@ -150,7 +242,7 @@ Print selected parts of lines from each FILE to standard output.\n\ + -f, --fields=LIST select only these fields; also print any line\n\ + that contains no delimiter character, unless\n\ + the -s option is specified\n\ +- -n (ignored)\n\ ++ -n with -b: don't split multibyte characters\n\ + "), stdout); + fputs (_("\ + --complement complement the set of selected bytes, characters\n\ +@@ -250,7 +342,7 @@ cut_bytes (FILE *stream) + next_item (&byte_idx); + if (print_kth (byte_idx)) + { +- if (output_delimiter_string != output_delimiter_default) ++ if (output_delimiter_specified) + { + if (print_delimiter && is_range_start_index (byte_idx)) + { +@@ -266,6 +358,82 @@ cut_bytes (FILE *stream) + } + } + ++#if HAVE_MBRTOWC ++/* This function is in use for the following case. ++ ++ 1. Read from the stream STREAM, printing to standard output any selected ++ characters. ++ ++ 2. Read from stream STREAM, printing to standard output any selected bytes, ++ without splitting multibyte characters. */ ++ ++static void ++cut_characters_or_cut_bytes_no_split (FILE *stream) ++{ ++ uintmax_t idx; /* number of bytes or characters in the line so far. */ ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ ++ char *bufpos; /* Next read position of BUF. */ ++ size_t buflen; /* The length of the byte sequence in buf. */ ++ wint_t wc; /* A gotten wide character. */ ++ size_t mblength; /* The byte size of a multibyte character which shows ++ as same character as WC. */ ++ mbstate_t state; /* State of the stream. */ ++ bool convfail = false; /* true, when conversion failed. Otherwise false. */ ++ /* Whether to begin printing delimiters between ranges for the current line. ++ Set after we've begun printing data corresponding to the first range. */ ++ bool print_delimiter = false; ++ ++ idx = 0; ++ buflen = 0; ++ bufpos = buf; ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ current_rp = frp; ++ ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ ++ GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); ++ (void) convfail; /* ignore unused */ ++ ++ if (wc == WEOF) ++ { ++ if (idx > 0) ++ putchar (line_delim); ++ break; ++ } ++ else if (wc == line_delim) ++ { ++ putchar (line_delim); ++ idx = 0; ++ print_delimiter = false; ++ current_rp = frp; ++ } ++ else ++ { ++ next_item (&idx); ++ if (print_kth (idx)) ++ { ++ if (output_delimiter_specified) ++ { ++ if (print_delimiter && is_range_start_index (idx)) ++ { ++ fwrite (output_delimiter_string, sizeof (char), ++ output_delimiter_length, stdout); ++ } ++ print_delimiter = true; ++ } ++ fwrite (bufpos, mblength, sizeof(char), stdout); ++ } ++ } ++ ++ buflen -= mblength; ++ bufpos += mblength; ++ } ++} ++#endif ++ + /* Read from stream STREAM, printing to standard output any selected fields. */ + + static void +@@ -411,11 +579,218 @@ cut_fields (FILE *stream) + } + } + +-/* Process file FILE to standard output, using CUT_STREAM. ++#if HAVE_MBRTOWC ++static void ++cut_fields_mb (FILE *stream) ++{ ++ int c; ++ uintmax_t field_idx; ++ int found_any_selected_field; ++ int buffer_first_field; ++ int empty_input; ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ ++ char *bufpos; /* Next read position of BUF. */ ++ size_t buflen; /* The length of the byte sequence in buf. */ ++ wint_t wc = 0; /* A gotten wide character. */ ++ size_t mblength; /* The byte size of a multibyte character which shows ++ as same character as WC. */ ++ mbstate_t state; /* State of the stream. */ ++ bool convfail = false; /* true, when conversion failed. Otherwise false. */ ++ ++ current_rp = frp; ++ ++ found_any_selected_field = 0; ++ field_idx = 1; ++ bufpos = buf; ++ buflen = 0; ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ c = getc (stream); ++ empty_input = (c == EOF); ++ if (c != EOF) ++ { ++ ungetc (c, stream); ++ wc = 0; ++ } ++ else ++ wc = WEOF; ++ ++ /* To support the semantics of the -s flag, we may have to buffer ++ all of the first field to determine whether it is `delimited.' ++ But that is unnecessary if all non-delimited lines must be printed ++ and the first field has been selected, or if non-delimited lines ++ must be suppressed and the first field has *not* been selected. ++ That is because a non-delimited line has exactly one field. */ ++ buffer_first_field = (suppress_non_delimited ^ !print_kth (1)); ++ ++ while (1) ++ { ++ if (field_idx == 1 && buffer_first_field) ++ { ++ int len = 0; ++ ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ ++ GET_NEXT_WC_FROM_BUFFER ++ (wc, bufpos, buflen, mblength, state, convfail); ++ ++ if (wc == WEOF) ++ break; ++ ++ field_1_buffer = xrealloc (field_1_buffer, len + mblength); ++ memcpy (field_1_buffer + len, bufpos, mblength); ++ len += mblength; ++ buflen -= mblength; ++ bufpos += mblength; ++ ++ if (!convfail && (wc == line_delim || wc == wcdelim)) ++ break; ++ } ++ ++ if (len <= 0 && wc == WEOF) ++ break; ++ ++ /* If the first field extends to the end of line (it is not ++ delimited) and we are printing all non-delimited lines, ++ print this one. */ ++ if (convfail || (!convfail && wc != wcdelim)) ++ { ++ if (suppress_non_delimited) ++ { ++ /* Empty. */ ++ } ++ else ++ { ++ fwrite (field_1_buffer, sizeof (char), len, stdout); ++ /* Make sure the output line is newline terminated. */ ++ if (convfail || (!convfail && wc != line_delim)) ++ putchar (line_delim); ++ } ++ continue; ++ } ++ ++ if (print_kth (1)) ++ { ++ /* Print the field, but not the trailing delimiter. */ ++ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); ++ found_any_selected_field = 1; ++ } ++ next_item (&field_idx); ++ } ++ ++ if (wc != WEOF) ++ { ++ if (print_kth (field_idx)) ++ { ++ if (found_any_selected_field) ++ { ++ fwrite (output_delimiter_string, sizeof (char), ++ output_delimiter_length, stdout); ++ } ++ found_any_selected_field = 1; ++ } ++ ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ ++ GET_NEXT_WC_FROM_BUFFER ++ (wc, bufpos, buflen, mblength, state, convfail); ++ ++ if (wc == WEOF) ++ break; ++ else if (!convfail && (wc == wcdelim || wc == line_delim)) ++ { ++ buflen -= mblength; ++ bufpos += mblength; ++ break; ++ } ++ ++ if (print_kth (field_idx)) ++ fwrite (bufpos, mblength, sizeof(char), stdout); ++ ++ buflen -= mblength; ++ bufpos += mblength; ++ } ++ } ++ ++ if ((!convfail || wc == line_delim) && buflen < 1) ++ wc = WEOF; ++ ++ if (!convfail && wc == wcdelim) ++ next_item (&field_idx); ++ else if (wc == WEOF || (!convfail && wc == line_delim)) ++ { ++ if (found_any_selected_field ++ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) ++ putchar (line_delim); ++ if (wc == WEOF) ++ break; ++ field_idx = 1; ++ current_rp = frp; ++ found_any_selected_field = 0; ++ } ++ } ++} ++#endif ++ ++static void ++cut_stream (FILE *stream) ++{ ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) ++ { ++ switch (operating_mode) ++ { ++ case byte_mode: ++ if (byte_mode_character_aware) ++ cut_characters_or_cut_bytes_no_split (stream); ++ else ++ cut_bytes (stream); ++ break; ++ ++ case character_mode: ++ cut_characters_or_cut_bytes_no_split (stream); ++ break; ++ ++ case field_mode: ++ if (delimlen == 1) ++ { ++ /* Check if we have utf8 multibyte locale, so we can use this ++ optimization because of uniqueness of characters, which is ++ not true for e.g. SJIS */ ++ char * loc = setlocale(LC_CTYPE, NULL); ++ if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") || ++ strstr (loc, "UTF8") || strstr (loc, "utf8"))) ++ { ++ cut_fields (stream); ++ break; ++ } ++ } ++ cut_fields_mb (stream); ++ break; ++ ++ default: ++ abort (); ++ } ++ } ++ else ++#endif ++ { ++ if (operating_mode == field_mode) ++ cut_fields (stream); ++ else ++ cut_bytes (stream); ++ } ++} ++ ++/* Process file FILE to standard output. + Return true if successful. */ + + static bool +-cut_file (char const *file, void (*cut_stream) (FILE *)) ++cut_file (char const *file) + { + FILE *stream; + +@@ -459,8 +834,8 @@ main (int argc, char **argv) + int optc; + bool ok; + bool delim_specified = false; +- bool byte_mode = false; +- char *spec_list_string = NULL; ++ char *spec_list_string IF_LINT ( = NULL); ++ char mbdelim[MB_LEN_MAX + 1]; + + initialize_main (&argc, &argv); + set_program_name (argv[0]); +@@ -470,6 +845,8 @@ main (int argc, char **argv) + + atexit (close_stdout); + ++ operating_mode = undefined_mode; ++ + /* By default, all non-delimited lines are printed. */ + suppress_non_delimited = false; + +@@ -481,35 +858,77 @@ main (int argc, char **argv) + switch (optc) + { + case 'b': +- case 'c': + /* Build the byte list. */ +- byte_mode = true; +- FALLTHROUGH; ++ if (operating_mode != undefined_mode) ++ FATAL_ERROR (_("only one type of list may be specified")); ++ operating_mode = byte_mode; ++ spec_list_string = optarg; ++ break; ++ ++ case 'c': ++ /* Build the character list. */ ++ if (operating_mode != undefined_mode) ++ FATAL_ERROR (_("only one type of list may be specified")); ++ operating_mode = character_mode; ++ spec_list_string = optarg; ++ break; ++ + case 'f': + /* Build the field list. */ +- if (spec_list_string) +- FATAL_ERROR (_("only one list may be specified")); ++ if (operating_mode != undefined_mode) ++ FATAL_ERROR (_("only one type of list may be specified")); ++ operating_mode = field_mode; + spec_list_string = optarg; + break; + + case 'd': + /* New delimiter. */ + /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ +- if (optarg[0] != '\0' && optarg[1] != '\0') +- FATAL_ERROR (_("the delimiter must be a single character")); +- delim = optarg[0]; +- delim_specified = true; ++ { ++#if HAVE_MBRTOWC ++ if(MB_CUR_MAX > 1) ++ { ++ mbstate_t state; ++ ++ memset (&state, '\0', sizeof(mbstate_t)); ++ delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state); ++ ++ if (delimlen == (size_t)-1 || delimlen == (size_t)-2) ++ ++force_singlebyte_mode; ++ else ++ { ++ delimlen = (delimlen < 1) ? 1 : delimlen; ++ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') ++ FATAL_ERROR (_("the delimiter must be a single character")); ++ memcpy (mbdelim, optarg, delimlen); ++ mbdelim[delimlen] = '\0'; ++ if (delimlen == 1) ++ delim = *optarg; ++ } ++ } ++ ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) ++#endif ++ { ++ if (optarg[0] != '\0' && optarg[1] != '\0') ++ FATAL_ERROR (_("the delimiter must be a single character")); ++ delim = (unsigned char) optarg[0]; ++ } ++ delim_specified = true; ++ } + break; + + case OUTPUT_DELIMITER_OPTION: ++ output_delimiter_specified = true; + /* Interpret --output-delimiter='' to mean + 'use the NUL byte as the delimiter.' */ + output_delimiter_length = (optarg[0] == '\0' + ? 1 : strlen (optarg)); +- output_delimiter_string = optarg; ++ output_delimiter_string = xstrdup (optarg); + break; + + case 'n': ++ byte_mode_character_aware = 1; + break; + + case 's': +@@ -533,40 +952,57 @@ main (int argc, char **argv) + } + } + +- if (!spec_list_string) ++ if (operating_mode == undefined_mode) + FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); + +- if (byte_mode) +- { +- if (delim_specified) +- FATAL_ERROR (_("an input delimiter may be specified only\ ++ if (delim_specified && operating_mode != field_mode) ++ FATAL_ERROR (_("an input delimiter may be specified only\ + when operating on fields")); + +- if (suppress_non_delimited) +- FATAL_ERROR (_("suppressing non-delimited lines makes sense\n\ ++ if (suppress_non_delimited && operating_mode != field_mode) ++ FATAL_ERROR (_("suppressing non-delimited lines makes sense\n\ + \tonly when operating on fields")); +- } + + set_fields (spec_list_string, +- ((byte_mode ? SETFLD_ERRMSG_USE_POS : 0) +- | (complement ? SETFLD_COMPLEMENT : 0))); ++ ( (operating_mode == field_mode) ? 0 : SETFLD_ERRMSG_USE_POS) ++ | (complement ? SETFLD_COMPLEMENT : 0) ); + + if (!delim_specified) +- delim = '\t'; ++ { ++ delim = '\t'; ++#ifdef HAVE_MBRTOWC ++ wcdelim = L'\t'; ++ mbdelim[0] = '\t'; ++ mbdelim[1] = '\0'; ++ delimlen = 1; ++#endif ++ } + + if (output_delimiter_string == NULL) + { +- output_delimiter_default[0] = delim; +- output_delimiter_string = output_delimiter_default; +- output_delimiter_length = 1; ++#ifdef HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) ++ { ++ output_delimiter_string = xstrdup(mbdelim); ++ output_delimiter_length = delimlen; ++ } ++ ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) ++#endif ++ { ++ static char dummy[2]; ++ dummy[0] = delim; ++ dummy[1] = '\0'; ++ output_delimiter_string = dummy; ++ output_delimiter_length = 1; ++ } + } + +- void (*cut_stream) (FILE *) = byte_mode ? cut_bytes : cut_fields; + if (optind == argc) +- ok = cut_file ("-", cut_stream); ++ ok = cut_file ("-"); + else + for (ok = true; optind < argc; optind++) +- ok &= cut_file (argv[optind], cut_stream); ++ ok &= cut_file (argv[optind]); + + + if (have_read_stdin && fclose (stdin) == EOF) +diff --git a/src/expand-common.c b/src/expand-common.c +index deec1bd..b39f740 100644 +--- a/src/expand-common.c ++++ b/src/expand-common.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include "system.h" + #include "die.h" + #include "error.h" +@@ -125,6 +126,119 @@ set_increment_size (uintmax_t tabval) + return ok; + } + ++extern int ++set_utf_locale (void) ++{ ++ /*try using some predefined locale */ ++ const char* predef_locales[] = {"C.UTF8","en_US.UTF8","en_GB.UTF8"}; ++ ++ const int predef_locales_count=3; ++ for (int i=0;ibufcount=0; ++ if (c == 0xEF) ++ { ++ c=fgetc(fp); ++ } ++ else ++ { ++ if (c != EOF) ++ { ++ ungetc(c,fp); ++ } ++ return false; ++ } ++ ++ if (c == 0xBB) ++ { ++ c=fgetc(fp); ++ } ++ else ++ { ++ if ( c!= EOF ) ++ { ++ mbf->buf[0]=(unsigned char) 0xEF; ++ mbf->bufcount=1; ++ ungetc(c,fp); ++ return false; ++ } ++ else ++ { ++ ungetc(0xEF,fp); ++ return false; ++ } ++ } ++ if (c == 0xBF) ++ { ++ mbf->bufcount=0; ++ return true; ++ } ++ else ++ { ++ if (c != EOF) ++ { ++ mbf->buf[0]=(unsigned char) 0xEF; ++ mbf->buf[1]=(unsigned char) 0xBB; ++ mbf->bufcount=2; ++ ungetc(c,fp); ++ return false; ++ } ++ else ++ { ++ mbf->buf[0]=(unsigned char) 0xEF; ++ mbf->bufcount=1; ++ ungetc(0xBB,fp); ++ return false; ++ } ++ } ++ return false; ++} ++ ++extern void ++print_bom(void) ++{ ++ putc (0xEF, stdout); ++ putc (0xBB, stdout); ++ putc (0xBF, stdout); ++} ++ + /* Add the comma or blank separated list of tab stops STOPS + to the list of tab stops. */ + extern void +diff --git a/src/expand-common.h b/src/expand-common.h +index 5f59a0e..835b9d5 100644 +--- a/src/expand-common.h ++++ b/src/expand-common.h +@@ -25,6 +25,18 @@ extern size_t max_column_width; + /* The desired exit status. */ + extern int exit_status; + ++extern int ++set_utf_locale (void); ++ ++extern bool ++check_utf_locale(void); ++ ++extern bool ++check_bom(FILE* fp, mb_file_t *mbf); ++ ++extern void ++print_bom(void); ++ + /* Add tab stop TABVAL to the end of 'tab_list'. */ + extern void + add_tab_stop (uintmax_t tabval); +diff --git a/src/expand.c b/src/expand.c +index ed78ca8..a4cefa1 100644 +--- a/src/expand.c ++++ b/src/expand.c +@@ -37,6 +37,9 @@ + #include + #include + #include ++ ++#include ++ + #include "system.h" + #include "die.h" + +@@ -97,19 +100,41 @@ expand (void) + { + /* Input stream. */ + FILE *fp = next_file (NULL); ++ mb_file_t mbf; ++ mbf_char_t c; ++ /* True if the starting locale is utf8. */ ++ bool using_utf_locale; ++ ++ /* True if the first file contains BOM header. */ ++ bool found_bom; ++ using_utf_locale=check_utf_locale(); + + if (!fp) + return; ++ mbf_init (mbf, fp); ++ found_bom=check_bom(fp,&mbf); + +- while (true) ++ if (using_utf_locale == false && found_bom == true) ++ { ++ /*try using some predefined locale */ ++ ++ if (set_utf_locale () != 0) + { +- /* Input character, or EOF. */ +- int c; ++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); ++ } ++ } ++ ++ ++ if (found_bom == true) ++ { ++ print_bom(); ++ } + ++ while (true) ++ { + /* If true, perform translations. */ + bool convert = true; + +- + /* The following variables have valid values only when CONVERT + is true: */ + +@@ -119,17 +144,48 @@ expand (void) + /* Index in TAB_LIST of next tab stop to examine. */ + size_t tab_index = 0; + +- + /* Convert a line of text. */ + + do + { +- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) +- continue; ++ while (true) { ++ mbf_getc (c, mbf); ++ if ((mb_iseof (c)) && (fp = next_file (fp))) ++ { ++ mbf_init (mbf, fp); ++ if (fp!=NULL) ++ { ++ if (check_bom(fp,&mbf)==true) ++ { ++ /*Not the first file - check BOM header*/ ++ if (using_utf_locale==false && found_bom==false) ++ { ++ /*BOM header in subsequent file but not in the first one. */ ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); ++ } ++ } ++ else ++ { ++ if(using_utf_locale==false && found_bom==true) ++ { ++ /*First file conatined BOM header - locale was switched to UTF ++ *all subsequent files should contain BOM. */ ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); ++ } ++ } ++ } ++ continue; ++ } ++ else ++ { ++ break; ++ } ++ } ++ + + if (convert) + { +- if (c == '\t') ++ if (mb_iseq (c, '\t')) + { + /* Column the next input tab stop is on. */ + uintmax_t next_tab_column; +@@ -148,32 +204,34 @@ expand (void) + if (putchar (' ') < 0) + die (EXIT_FAILURE, errno, _("write error")); + +- c = ' '; ++ mb_setascii (&c, ' '); + } +- else if (c == '\b') ++ else if (mb_iseq (c, '\b')) + { + /* Go back one column, and force recalculation of the + next tab stop. */ + column -= !!column; + tab_index -= !!tab_index; + } +- else ++ /* A leading control character could make us trip over. */ ++ else if (!mb_iscntrl (c)) + { +- column++; ++ column += mb_width (c); + if (!column) + die (EXIT_FAILURE, 0, _("input line is too long")); + } + +- convert &= convert_entire_line || !! isblank (c); ++ convert &= convert_entire_line || mb_isblank (c); + } + +- if (c < 0) ++ if (mb_iseof (c)) + return; + +- if (putchar (c) < 0) ++ mb_putc (c, stdout); ++ if (ferror (stdout)) + die (EXIT_FAILURE, errno, _("write error")); + } +- while (c != '\n'); ++ while (!mb_iseq (c, '\n')); + } + } + diff --git a/src/fold.c b/src/fold.c -index 8cd0d6b..d23edd5 100644 +index f07a90b..d32dbfd 100644 --- a/src/fold.c +++ b/src/fold.c @@ -22,12 +22,34 @@ @@ -203,12 +1507,15 @@ index 8cd0d6b..d23edd5 100644 /* Look for the last blank. */ while (logical_end) { -@@ -215,11 +252,221 @@ fold_file (char const *filename, size_t width) +@@ -215,13 +252,225 @@ fold_file (char const *filename, size_t width) line_out[offset_out++] = c; } - saved_errno = errno; + *saved_errno = errno; + if (!ferror (istream)) +- saved_errno = 0; ++ *saved_errno = 0; if (offset_out) fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); @@ -384,6 +1691,8 @@ index 8cd0d6b..d23edd5 100644 + } + + *saved_errno = errno; ++ if (!ferror (istream)) ++ *saved_errno = 0; + + if (offset_out) + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); @@ -423,10 +1732,10 @@ index 8cd0d6b..d23edd5 100644 +#endif + fold_text (istream, width, &saved_errno); + - if (ferror (istream)) - { - error (0, saved_errno, "%s", quotef (filename)); -@@ -252,7 +499,8 @@ main (int argc, char **argv) + if (STREQ (filename, "-")) + clearerr (istream); + else if (fclose (istream) != 0 && !saved_errno) +@@ -252,7 +501,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -436,7 +1745,7 @@ index 8cd0d6b..d23edd5 100644 while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -261,7 +509,15 @@ main (int argc, char **argv) +@@ -261,7 +511,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -454,7 +1763,7 @@ index 8cd0d6b..d23edd5 100644 case 's': /* Break at word boundaries. */ diff --git a/src/join.c b/src/join.c -index 98b461c..9990f38 100644 +index f2fd172..6c7d1ed 100644 --- a/src/join.c +++ b/src/join.c @@ -22,19 +22,33 @@ @@ -509,7 +1818,7 @@ index 98b461c..9990f38 100644 /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -276,13 +292,14 @@ xfields (struct line *line) +@@ -280,13 +296,14 @@ xfields (struct line *line) if (ptr == lim) return; @@ -527,7 +1836,7 @@ index 98b461c..9990f38 100644 { /* Skip leading blanks before the first field. */ while (field_sep (*ptr)) -@@ -306,6 +323,147 @@ xfields (struct line *line) +@@ -310,6 +327,147 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -675,7 +1984,7 @@ index 98b461c..9990f38 100644 static void freeline (struct line *line) { -@@ -327,56 +485,133 @@ keycmp (struct line const *line1, struct line const *line2, +@@ -331,56 +489,133 @@ keycmp (struct line const *line1, struct line const *line2, size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -832,7 +2141,7 @@ index 98b461c..9990f38 100644 } /* Check that successive input lines PREV and CURRENT from input file -@@ -468,6 +703,11 @@ get_line (FILE *fp, struct line **linep, int which) +@@ -472,6 +707,11 @@ get_line (FILE *fp, struct line **linep, int which) } ++line_no[which - 1]; @@ -844,7 +2153,7 @@ index 98b461c..9990f38 100644 xfields (line); if (prevline[which - 1]) -@@ -563,21 +803,28 @@ prfield (size_t n, struct line const *line) +@@ -567,21 +807,28 @@ prfield (size_t n, struct line const *line) /* Output all the fields in line, other than the join field. */ @@ -876,7 +2185,7 @@ index 98b461c..9990f38 100644 prfield (i, line); } } -@@ -588,7 +835,6 @@ static void +@@ -592,7 +839,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; @@ -884,7 +2193,7 @@ index 98b461c..9990f38 100644 size_t field; struct line const *line; -@@ -622,7 +868,7 @@ prjoin (struct line const *line1, struct line const *line2) +@@ -626,7 +872,7 @@ prjoin (struct line const *line1, struct line const *line2) o = o->next; if (o == NULL) break; @@ -893,7 +2202,7 @@ index 98b461c..9990f38 100644 } putchar (eolchar); } -@@ -1099,20 +1345,43 @@ main (int argc, char **argv) +@@ -1102,20 +1348,43 @@ main (int argc, char **argv) case 't': { @@ -946,8 +2255,23 @@ index 98b461c..9990f38 100644 } break; +diff --git a/src/local.mk b/src/local.mk +index e1d15ce..1a5ffaa 100644 +--- a/src/local.mk ++++ b/src/local.mk +@@ -434,8 +434,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) + src_basenc_SOURCES = src/basenc.c + src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) + +-src_expand_SOURCES = src/expand.c src/expand-common.c +-src_unexpand_SOURCES = src/unexpand.c src/expand-common.c ++src_expand_SOURCES = src/expand.c src/expand-common.c lib/mbfile.c ++src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c + + src_wc_SOURCES = src/wc.c + if USE_AVX2_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index 26f221f..633f50e 100644 +index 4c17c00..b4fab1c 100644 --- a/src/pr.c +++ b/src/pr.c @@ -311,6 +311,24 @@ @@ -975,8 +2299,8 @@ index 26f221f..633f50e 100644 #include "system.h" #include "die.h" #include "error.h" -@@ -324,6 +342,18 @@ - #include "xstrtol.h" +@@ -325,6 +343,18 @@ + #include "xstrtol-error.h" #include "xdectoint.h" +/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ @@ -994,7 +2318,7 @@ index 26f221f..633f50e 100644 /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" -@@ -416,7 +446,20 @@ struct COLUMN +@@ -417,7 +447,20 @@ struct COLUMN typedef struct COLUMN COLUMN; @@ -1016,23 +2340,23 @@ index 26f221f..633f50e 100644 static bool read_line (COLUMN *p); static bool print_page (void); static bool print_stored (COLUMN *p); -@@ -428,6 +471,7 @@ static void add_line_number (COLUMN *p); - static void getoptnum (const char *n_str, int min, int *num, - const char *errfmt); +@@ -429,6 +472,7 @@ static void add_line_number (COLUMN *p); + static void getoptnum (char const *n_str, int min, int *num, + char const *errfmt); static void getoptarg (char *arg, char switch_char, char *character, + int *character_length, int *character_width, int *number); static void print_files (int number_of_files, char **av); static void init_parameters (int number_of_files); -@@ -441,7 +485,6 @@ static void store_char (char c); +@@ -442,7 +486,6 @@ static void store_char (char c); static void pad_down (unsigned int lines); static void read_rest_of_line (COLUMN *p); static void skip_read (COLUMN *p, int column_number); -static void print_char (char c); static void cleanup (void); static void print_sep_string (void); - static void separator_string (const char *optarg_S); -@@ -453,7 +496,7 @@ static COLUMN *column_vector; + static void separator_string (char const *optarg_S); +@@ -454,7 +497,7 @@ static COLUMN *column_vector; we store the leftmost columns contiguously in buff. To print a line from buff, get the index of the first character from line_vector[i], and print up to line_vector[i + 1]. */ @@ -1041,7 +2365,7 @@ index 26f221f..633f50e 100644 /* Index of the position in buff where the next character will be stored. */ -@@ -557,7 +600,7 @@ static int chars_per_column; +@@ -558,7 +601,7 @@ static int chars_per_column; static bool untabify_input = false; /* (-e) The input tab character. */ @@ -1050,7 +2374,7 @@ index 26f221f..633f50e 100644 /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... where the leftmost column is 1. */ -@@ -567,7 +610,10 @@ static int chars_per_input_tab = 8; +@@ -568,7 +611,10 @@ static int chars_per_input_tab = 8; static bool tabify_output = false; /* (-i) The output tab character. */ @@ -1062,7 +2386,7 @@ index 26f221f..633f50e 100644 /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -637,7 +683,13 @@ static int line_number; +@@ -638,7 +684,13 @@ static int line_number; static bool numbered_lines = false; /* (-n) Character which follows each line number. */ @@ -1077,7 +2401,7 @@ index 26f221f..633f50e 100644 /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ -@@ -690,6 +742,7 @@ static bool use_col_separator = false; +@@ -691,6 +743,7 @@ static bool use_col_separator = false; -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ static char const *col_sep_string = ""; static int col_sep_length = 0; @@ -1085,7 +2409,7 @@ index 26f221f..633f50e 100644 static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -851,6 +904,13 @@ separator_string (const char *optarg_S) +@@ -853,6 +906,13 @@ separator_string (char const *optarg_S) integer_overflow (); col_sep_length = len; col_sep_string = optarg_S; @@ -1099,7 +2423,7 @@ index 26f221f..633f50e 100644 } int -@@ -875,6 +935,21 @@ main (int argc, char **argv) +@@ -877,6 +937,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1121,7 +2445,7 @@ index 26f221f..633f50e 100644 n_files = 0; file_names = (argc > 1 ? xnmalloc (argc - 1, sizeof (char *)) -@@ -951,8 +1026,12 @@ main (int argc, char **argv) +@@ -953,8 +1028,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -1136,7 +2460,7 @@ index 26f221f..633f50e 100644 /* Could check tab width > 0. */ untabify_input = true; break; -@@ -965,8 +1044,12 @@ main (int argc, char **argv) +@@ -967,8 +1046,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -1151,7 +2475,7 @@ index 26f221f..633f50e 100644 /* Could check tab width > 0. */ tabify_output = true; break; -@@ -984,8 +1067,8 @@ main (int argc, char **argv) +@@ -986,8 +1069,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -1162,7 +2486,7 @@ index 26f221f..633f50e 100644 break; case 'N': skip_count = false; -@@ -1010,6 +1093,7 @@ main (int argc, char **argv) +@@ -1012,6 +1095,7 @@ main (int argc, char **argv) /* Reset an additional input of -s, -S dominates -s */ col_sep_string = ""; col_sep_length = 0; @@ -1170,7 +2494,7 @@ index 26f221f..633f50e 100644 use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1165,10 +1249,45 @@ getoptnum (const char *n_str, int min, int *num, const char *err) +@@ -1166,10 +1250,45 @@ getoptnum (char const *n_str, int min, int *num, char const *err) a number. */ static void @@ -1218,7 +2542,7 @@ index 26f221f..633f50e 100644 if (*arg) { long int tmp_long; -@@ -1190,6 +1309,11 @@ static void +@@ -1191,6 +1310,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -1230,7 +2554,7 @@ index 26f221f..633f50e 100644 lines_per_body = lines_per_page - lines_per_header - lines_per_footer; if (lines_per_body <= 0) -@@ -1227,7 +1351,7 @@ init_parameters (int number_of_files) +@@ -1228,7 +1352,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -1239,7 +2563,7 @@ index 26f221f..633f50e 100644 use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1257,11 +1381,11 @@ init_parameters (int number_of_files) +@@ -1260,11 +1384,11 @@ init_parameters (int number_of_files) + TAB_WIDTH (chars_per_input_tab, chars_per_number); */ /* Estimate chars_per_text without any margin and keep it constant. */ @@ -1253,7 +2577,7 @@ index 26f221f..633f50e 100644 /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1270,7 +1394,7 @@ init_parameters (int number_of_files) +@@ -1273,7 +1397,7 @@ init_parameters (int number_of_files) } int sep_chars, useful_chars; @@ -1262,7 +2586,7 @@ index 26f221f..633f50e 100644 sep_chars = INT_MAX; if (INT_SUBTRACT_WRAPV (chars_per_line - chars_used_by_number, sep_chars, &useful_chars)) -@@ -1293,7 +1417,7 @@ init_parameters (int number_of_files) +@@ -1296,7 +1420,7 @@ init_parameters (int number_of_files) We've to use 8 as the lower limit, if we use chars_per_default_tab = 8 to expand a tab which is not an input_tab-char. */ free (clump_buff); @@ -1271,7 +2595,7 @@ index 26f221f..633f50e 100644 } /* Open the necessary files, -@@ -1399,7 +1523,7 @@ init_funcs (void) +@@ -1402,7 +1526,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -1280,7 +2604,7 @@ index 26f221f..633f50e 100644 /* This loop takes care of all but the rightmost column. */ -@@ -1433,7 +1557,7 @@ init_funcs (void) +@@ -1436,7 +1560,7 @@ init_funcs (void) } else { @@ -1289,7 +2613,7 @@ index 26f221f..633f50e 100644 h_next = h + chars_per_column; } } -@@ -1724,9 +1848,9 @@ static void +@@ -1733,9 +1857,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -1301,7 +2625,7 @@ index 26f221f..633f50e 100644 padding_not_printed = ANYWHERE; } -@@ -2001,13 +2125,13 @@ store_char (char c) +@@ -2010,13 +2134,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -1317,7 +2641,7 @@ index 26f221f..633f50e 100644 char *s; int num_width; -@@ -2024,22 +2148,24 @@ add_line_number (COLUMN *p) +@@ -2033,22 +2157,24 @@ add_line_number (COLUMN *p) /* Tabification is assumed for multiple columns, also for n-separators, but 'default n-separator = TAB' hasn't been given priority over equal column_width also specified by POSIX. */ @@ -1346,7 +2670,7 @@ index 26f221f..633f50e 100644 output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2198,7 +2324,7 @@ print_white_space (void) +@@ -2207,7 +2333,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -1355,7 +2679,7 @@ index 26f221f..633f50e 100644 h_old = h_new; } while (++h_old <= goal) -@@ -2218,6 +2344,7 @@ print_sep_string (void) +@@ -2227,6 +2353,7 @@ print_sep_string (void) { char const *s = col_sep_string; int l = col_sep_length; @@ -1363,7 +2687,7 @@ index 26f221f..633f50e 100644 if (separators_not_printed <= 0) { -@@ -2229,6 +2356,7 @@ print_sep_string (void) +@@ -2238,6 +2365,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -1371,7 +2695,7 @@ index 26f221f..633f50e 100644 while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2242,12 +2370,15 @@ print_sep_string (void) +@@ -2251,12 +2379,15 @@ print_sep_string (void) } else { @@ -1388,7 +2712,7 @@ index 26f221f..633f50e 100644 /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2275,7 +2406,7 @@ print_clump (COLUMN *p, int n, char *clump) +@@ -2284,7 +2415,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -1397,7 +2721,7 @@ index 26f221f..633f50e 100644 { if (tabify_output) { -@@ -2299,6 +2430,74 @@ print_char (char c) +@@ -2308,6 +2439,74 @@ print_char (char c) putchar (c); } @@ -1472,7 +2796,7 @@ index 26f221f..633f50e 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2476,9 +2675,9 @@ read_line (COLUMN *p) +@@ -2485,9 +2684,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -1484,7 +2808,7 @@ index 26f221f..633f50e 100644 padding_not_printed = ANYWHERE; } -@@ -2547,7 +2746,7 @@ print_stored (COLUMN *p) +@@ -2556,7 +2755,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -1493,7 +2817,7 @@ index 26f221f..633f50e 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2559,7 +2758,7 @@ print_stored (COLUMN *p) +@@ -2568,7 +2767,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -1502,7 +2826,7 @@ index 26f221f..633f50e 100644 pad_vertically = true; -@@ -2579,9 +2778,9 @@ print_stored (COLUMN *p) +@@ -2588,9 +2787,9 @@ print_stored (COLUMN *p) } } @@ -1514,7 +2838,7 @@ index 26f221f..633f50e 100644 padding_not_printed = ANYWHERE; } -@@ -2594,8 +2793,8 @@ print_stored (COLUMN *p) +@@ -2603,8 +2802,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -1525,7 +2849,7 @@ index 26f221f..633f50e 100644 } return true; -@@ -2614,7 +2813,7 @@ print_stored (COLUMN *p) +@@ -2623,7 +2822,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -1534,7 +2858,7 @@ index 26f221f..633f50e 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2624,10 +2823,10 @@ char_to_clump (char c) +@@ -2633,10 +2832,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -1547,7 +2871,7 @@ index 26f221f..633f50e 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2708,6 +2907,164 @@ char_to_clump (char c) +@@ -2717,6 +2916,164 @@ char_to_clump (char c) return chars; } @@ -1713,7 +3037,7 @@ index 26f221f..633f50e 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 6d2eec5..f189a0d 100644 +index 3b775d6..a0ba243 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -1731,9 +3055,9 @@ index 6d2eec5..f189a0d 100644 #include "system.h" #include "argmatch.h" #include "die.h" -@@ -161,14 +169,39 @@ static int decimal_point; - /* Thousands separator; if -1, then there isn't one. */ - static int thousands_sep; +@@ -159,14 +167,39 @@ static int thousands_sep; + /* We currently ignore multi-byte grouping chars. */ + static bool thousands_sep_ignored; +/* True if -f is specified. */ +static bool folding; @@ -1772,9 +3096,9 @@ index 6d2eec5..f189a0d 100644 /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -342,13 +375,11 @@ static bool reverse; - they were read if all keys compare equal. */ - static bool stable; +@@ -343,13 +376,11 @@ static bool stable; + /* An int value outside char range. */ + enum { NON_CHAR = CHAR_MAX + 1 }; -/* If TAB has this value, blanks separate fields. */ -enum { TAB_DEFAULT = CHAR_MAX + 1 }; @@ -1789,7 +3113,7 @@ index 6d2eec5..f189a0d 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -806,6 +837,46 @@ reap_all (void) +@@ -805,6 +836,46 @@ reap_all (void) reap (-1); } @@ -1836,7 +3160,7 @@ index 6d2eec5..f189a0d 100644 /* Clean up any remaining temporary files. */ static void -@@ -1274,7 +1345,7 @@ zaptemp (char const *name) +@@ -1272,7 +1343,7 @@ zaptemp (char const *name) free (node); } @@ -1845,7 +3169,7 @@ index 6d2eec5..f189a0d 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1289,7 +1360,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1287,7 +1358,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -1854,7 +3178,7 @@ index 6d2eec5..f189a0d 100644 { size_t i; -@@ -1301,7 +1372,7 @@ inittables (void) +@@ -1299,7 +1370,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -1863,7 +3187,7 @@ index 6d2eec5..f189a0d 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1383,6 +1454,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1381,6 +1452,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -1948,7 +3272,7 @@ index 6d2eec5..f189a0d 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1614,7 +1763,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1612,7 +1761,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -1957,7 +3281,7 @@ index 6d2eec5..f189a0d 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1623,10 +1772,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1621,10 +1770,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -1970,7 +3294,7 @@ index 6d2eec5..f189a0d 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1652,11 +1801,70 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1650,12 +1799,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2036,13 +3360,14 @@ index 6d2eec5..f189a0d 100644 /* Return the limit of (a pointer to the first character after) the field in LINE specified by KEY. */ + ATTRIBUTE_PURE static char * -limfield (struct line const *line, struct keyfield const *key) -+limfield_uni (const struct line *line, const struct keyfield *key) ++limfield_uni (struct line const *line, struct keyfield const *key) { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1671,10 +1879,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1670,10 +1878,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -2055,7 +3380,7 @@ index 6d2eec5..f189a0d 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1720,10 +1928,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1719,10 +1927,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2068,12 +3393,12 @@ index 6d2eec5..f189a0d 100644 if (newlim) lim = newlim; } -@@ -1754,6 +1962,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1753,6 +1961,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } +#if HAVE_MBRTOWC -+static char * ++static char * _GL_ATTRIBUTE_PURE +limfield_mb (const struct line *line, const struct keyfield *key) +{ + char *ptr = line->text, *lim = ptr + line->length - 1; @@ -2199,7 +3524,7 @@ index 6d2eec5..f189a0d 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1840,8 +2172,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1839,8 +2171,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -2224,16 +3549,32 @@ index 6d2eec5..f189a0d 100644 line->keybeg = line_start; } } -@@ -1991,7 +2337,7 @@ human_numcompare (char const *a, char const *b) - hideously fast. */ +@@ -1976,12 +2322,10 @@ find_unit_order (char const *number) + ATTRIBUTE_PURE + static int +-human_numcompare (char const *a, char const *b) ++human_numcompare (char *a, char *b) + { +- while (blanks[to_uchar (*a)]) +- a++; +- while (blanks[to_uchar (*b)]) +- b++; ++ skipblanks(&a, a + strlen(a)); ++ skipblanks(&b, b + strlen(b)); + + int diff = find_unit_order (a) - find_unit_order (b); + return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); +@@ -1993,7 +2337,7 @@ human_numcompare (char const *a, char const *b) + + ATTRIBUTE_PURE static int -numcompare (char const *a, char const *b) +numcompare_uni (const char *a, const char *b) { while (blanks[to_uchar (*a)]) a++; -@@ -2001,6 +2347,25 @@ numcompare (char const *a, char const *b) +@@ -2003,6 +2347,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2259,7 +3600,7 @@ index 6d2eec5..f189a0d 100644 /* Work around a problem whereby the long double value returned by glibc's strtold ("NaN", ...) contains uninitialized bits: clear all bytes of A and B before calling strtold. FIXME: remove this function if -@@ -2051,7 +2416,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2053,7 +2416,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2268,7 +3609,7 @@ index 6d2eec5..f189a0d 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2327,15 +2692,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2329,15 +2692,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -2286,7 +3627,7 @@ index 6d2eec5..f189a0d 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2469,7 +2833,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2483,7 +2845,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2295,7 +3636,66 @@ index 6d2eec5..f189a0d 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2527,11 +2891,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2531,9 +2893,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) + bool number_locale_warned = false; + if (basic_numeric_field_span) + { +- if (tab == TAB_DEFAULT +- ? thousands_sep != NON_CHAR && (isblank (to_uchar (thousands_sep))) +- : tab == thousands_sep) ++ if (tab_length ++ ? tab[0] == thousands_sep ++ : thousands_sep != NON_CHAR && (isblank (to_uchar (thousands_sep)))) + { + error (0, 0, + _("field separator %s is treated as a " +@@ -2544,9 +2906,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) + } + if (basic_numeric_field_span || general_numeric_field_span) + { +- if (tab == TAB_DEFAULT +- ? thousands_sep != NON_CHAR && (isblank (to_uchar (decimal_point))) +- : tab == decimal_point) ++ if (tab_length ++ ? tab[0] == decimal_point ++ : thousands_sep != NON_CHAR && (isblank (to_uchar (decimal_point)))) + { + error (0, 0, + _("field separator %s is treated as a " +@@ -2554,19 +2916,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) + quote (((char []) {decimal_point, 0}))); + number_locale_warned = true; + } +- else if (tab == '-') ++ else if (tab_length && tab[0] == '-') + { + error (0, 0, + _("field separator %s is treated as a " + "minus sign in numbers"), +- quote (((char []) {tab, 0}))); ++ quote (((char []) {tab[0], 0}))); + } +- else if (general_numeric_field_span && tab == '+') ++ else if (general_numeric_field_span && tab_length && tab[0] == '+') + { + error (0, 0, + _("field separator %s is treated as a " + "plus sign in numbers"), +- quote (((char []) {tab, 0}))); ++ quote (((char []) {tab[0], 0}))); + } + } + +@@ -2577,7 +2939,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) + { + error (0, 0, + _("%snumbers use %s as a decimal point in this locale"), +- tab == decimal_point ? "" : _("note "), ++ (tab_length && tab[0] == decimal_point) ? "" : _("note "), + quote (((char []) {decimal_point, 0}))); + + } +@@ -2610,11 +2972,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -2384,7 +3784,7 @@ index 6d2eec5..f189a0d 100644 { struct keyfield *key = keylist; -@@ -2616,7 +3056,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2699,7 +3137,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -2393,7 +3793,7 @@ index 6d2eec5..f189a0d 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2732,6 +3172,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2815,6 +3253,211 @@ keycompare (struct line const *a, struct line const *b) return key->reverse ? -diff : diff; } @@ -2605,7 +4005,7 @@ index 6d2eec5..f189a0d 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2759,7 +3404,7 @@ compare (struct line const *a, struct line const *b) +@@ -2842,7 +3485,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -2614,7 +4014,7 @@ index 6d2eec5..f189a0d 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4149,6 +4794,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4226,6 +4869,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -2622,7 +4022,7 @@ index 6d2eec5..f189a0d 100644 break; case 'g': key->general_numeric = true; -@@ -4228,7 +4874,7 @@ main (int argc, char **argv) +@@ -4305,7 +4949,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -2631,8 +4031,8 @@ index 6d2eec5..f189a0d 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4249,6 +4895,29 @@ main (int argc, char **argv) - thousands_sep = -1; +@@ -4328,6 +4972,29 @@ main (int argc, char **argv) + thousands_sep = NON_CHAR; } +#if HAVE_MBRTOWC @@ -2661,7 +4061,7 @@ index 6d2eec5..f189a0d 100644 have_read_stdin = false; inittables (); -@@ -4523,13 +5192,34 @@ main (int argc, char **argv) +@@ -4602,13 +5269,34 @@ main (int argc, char **argv) case 't': { @@ -2700,7 +4100,7 @@ index 6d2eec5..f189a0d 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4540,9 +5230,11 @@ main (int argc, char **argv) +@@ -4619,9 +5307,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -2714,21 +4114,214 @@ index 6d2eec5..f189a0d 100644 } break; -@@ -4771,12 +5463,10 @@ main (int argc, char **argv) - sort (files, nfiles, outfile, nthreads); +diff --git a/src/unexpand.c b/src/unexpand.c +index 7d6100f..04cd646 100644 +--- a/src/unexpand.c ++++ b/src/unexpand.c +@@ -38,6 +38,9 @@ + #include + #include + #include ++ ++#include ++ + #include "system.h" + #include "die.h" + +@@ -106,24 +109,47 @@ unexpand (void) + { + /* Input stream. */ + FILE *fp = next_file (NULL); ++ mb_file_t mbf; + + /* The array of pending blanks. In non-POSIX locales, blanks can + include characters other than spaces, so the blanks must be + stored, not merely counted. */ +- char *pending_blank; ++ mbf_char_t *pending_blank; ++ /* True if the starting locale is utf8. */ ++ bool using_utf_locale; ++ ++ /* True if the first file contains BOM header. */ ++ bool found_bom; ++ using_utf_locale=check_utf_locale(); + + if (!fp) + return; ++ mbf_init (mbf, fp); ++ found_bom=check_bom(fp,&mbf); ++ ++ if (using_utf_locale == false && found_bom == true) ++ { ++ /*try using some predefined locale */ + ++ if (set_utf_locale () != 0) ++ { ++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); ++ } ++ } + /* The worst case is a non-blank character, then one blank, then a + tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so + allocate MAX_COLUMN_WIDTH bytes to store the blanks. */ +- pending_blank = xmalloc (max_column_width); ++ pending_blank = xmalloc (max_column_width * sizeof (mbf_char_t)); ++ ++ if (found_bom == true) ++ { ++ print_bom(); ++ } + + while (true) + { + /* Input character, or EOF. */ +- int c; ++ mbf_char_t c; + + /* If true, perform translations. */ + bool convert = true; +@@ -157,12 +183,44 @@ unexpand (void) + + do + { +- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) +- continue; ++ while (true) { ++ mbf_getc (c, mbf); ++ if ((mb_iseof (c)) && (fp = next_file (fp))) ++ { ++ mbf_init (mbf, fp); ++ if (fp!=NULL) ++ { ++ if (check_bom(fp,&mbf)==true) ++ { ++ /*Not the first file - check BOM header*/ ++ if (using_utf_locale==false && found_bom==false) ++ { ++ /*BOM header in subsequent file but not in the first one. */ ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); ++ } ++ } ++ else ++ { ++ if(using_utf_locale==false && found_bom==true) ++ { ++ /*First file conatined BOM header - locale was switched to UTF ++ *all subsequent files should contain BOM. */ ++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); ++ } ++ } ++ } ++ continue; ++ } ++ else ++ { ++ break; ++ } ++ } ++ + + if (convert) + { +- bool blank = !! isblank (c); ++ bool blank = mb_isblank (c); + + if (blank) + { +@@ -179,16 +237,16 @@ unexpand (void) + if (next_tab_column < column) + die (EXIT_FAILURE, 0, _("input line is too long")); + +- if (c == '\t') ++ if (mb_iseq (c, '\t')) + { + column = next_tab_column; + + if (pending) +- pending_blank[0] = '\t'; ++ mb_setascii (&pending_blank[0], '\t'); + } + else + { +- column++; ++ column += mb_width (c); + + if (! (prev_blank && column == next_tab_column)) + { +@@ -196,13 +254,14 @@ unexpand (void) + will be replaced by tabs. */ + if (column == next_tab_column) + one_blank_before_tab_stop = true; +- pending_blank[pending++] = c; ++ mb_copy (&pending_blank[pending++], &c); + prev_blank = true; + continue; + } + + /* Replace the pending blanks by a tab or two. */ +- pending_blank[0] = c = '\t'; ++ mb_setascii (&c, '\t'); ++ mb_setascii (&pending_blank[0], '\t'); + } + + /* Discard pending blanks, unless it was a single +@@ -210,7 +269,7 @@ unexpand (void) + pending = one_blank_before_tab_stop; + } + } +- else if (c == '\b') ++ else if (mb_iseq (c, '\b')) + { + /* Go back one column, and force recalculation of the + next tab stop. */ +@@ -218,9 +277,9 @@ unexpand (void) + next_tab_column = column; + tab_index -= !!tab_index; + } +- else ++ else if (!mb_iseq (c, '\n')) + { +- column++; ++ column += mb_width (c); + if (!column) + die (EXIT_FAILURE, 0, _("input line is too long")); + } +@@ -228,8 +287,11 @@ unexpand (void) + if (pending) + { + if (pending > 1 && one_blank_before_tab_stop) +- pending_blank[0] = '\t'; +- if (fwrite (pending_blank, 1, pending, stdout) != pending) ++ mb_setascii (&pending_blank[0], '\t'); ++ ++ for (int n = 0; n < pending; ++n) ++ mb_putc (pending_blank[n], stdout); ++ if (ferror (stdout)) + die (EXIT_FAILURE, errno, _("write error")); + pending = 0; + one_blank_before_tab_stop = false; +@@ -239,16 +301,17 @@ unexpand (void) + convert &= convert_entire_line || blank; + } + +- if (c < 0) ++ if (mb_iseof (c)) + { + free (pending_blank); + return; + } + +- if (putchar (c) < 0) ++ mb_putc (c, stdout); ++ if (ferror (stdout)) + die (EXIT_FAILURE, errno, _("write error")); + } +- while (c != '\n'); ++ while (!mb_iseq (c, '\n')); } + } --#ifdef lint - if (files_from) - readtokens0_free (&tok); - else - free (files); --#endif - - if (have_read_stdin && fclose (stdin) == EOF) - sort_die (_("close failed"), "-"); diff --git a/src/uniq.c b/src/uniq.c -index 87a0c93..9f755d9 100644 +index e5996f0..871d47c 100644 --- a/src/uniq.c +++ b/src/uniq.c @@ -21,6 +21,17 @@ @@ -2749,12 +4342,8 @@ index 87a0c93..9f755d9 100644 #include "system.h" #include "argmatch.h" #include "linebuffer.h" -@@ -32,9 +43,21 @@ - #include "stdio--.h" - #include "xmemcoll.h" - #include "xstrtol.h" --#include "memcasecmp.h" -+#include "xmemcoll.h" +@@ -33,6 +44,18 @@ + #include "memcasecmp.h" #include "quote.h" +/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC @@ -2772,7 +4361,7 @@ index 87a0c93..9f755d9 100644 /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "uniq" -@@ -144,6 +167,10 @@ enum +@@ -139,6 +162,10 @@ enum GROUP_OPTION = CHAR_MAX + 1 }; @@ -2783,16 +4372,16 @@ index 87a0c93..9f755d9 100644 static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -260,7 +287,7 @@ size_opt (char const *opt, char const *msgid) - return a pointer to the beginning of the line's field to be compared. */ +@@ -254,7 +281,7 @@ size_opt (char const *opt, char const *msgid) - static char * _GL_ATTRIBUTE_PURE + ATTRIBUTE_PURE + static char * -find_field (struct linebuffer const *line) +find_field_uni (struct linebuffer *line) { size_t count; char const *lp = line->buffer; -@@ -280,6 +307,83 @@ find_field (struct linebuffer const *line) +@@ -274,6 +301,83 @@ find_field (struct linebuffer const *line) return line->buffer + i; } @@ -2876,228 +4465,7 @@ index 87a0c93..9f755d9 100644 /* Return false if two strings OLD and NEW match, true if not. OLD and NEW point not to the beginnings of the lines but rather to the beginnings of the fields to compare. -@@ -288,6 +392,8 @@ find_field (struct linebuffer const *line) - static bool - different (char *old, char *new, size_t oldlen, size_t newlen) - { -+ char *copy_old, *copy_new; -+ - if (check_chars < oldlen) - oldlen = check_chars; - if (check_chars < newlen) -@@ -295,15 +401,104 @@ different (char *old, char *new, size_t oldlen, size_t newlen) - - if (ignore_case) - { -- /* FIXME: This should invoke strcoll somehow. */ -- return oldlen != newlen || memcasecmp (old, new, oldlen); -+ size_t i; -+ -+ copy_old = xmalloc (oldlen + 1); -+ copy_new = xmalloc (oldlen + 1); -+ -+ for (i = 0; i < oldlen; i++) -+ { -+ copy_old[i] = toupper (old[i]); -+ copy_new[i] = toupper (new[i]); -+ } -+ bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen); -+ free (copy_old); -+ free (copy_new); -+ return rc; - } -- else if (hard_LC_COLLATE) -- return xmemcoll (old, oldlen, new, newlen) != 0; - else -- return oldlen != newlen || memcmp (old, new, oldlen); -+ { -+ copy_old = (char *)old; -+ copy_new = (char *)new; -+ } -+ -+ return xmemcoll (copy_old, oldlen, copy_new, newlen); -+ - } - -+#if HAVE_MBRTOWC -+static int -+different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) -+{ -+ size_t i, j, chars; -+ const char *str[2]; -+ char *copy[2]; -+ size_t len[2]; -+ mbstate_t state[2]; -+ size_t mblength; -+ wchar_t wc, uwc; -+ mbstate_t state_bak; -+ -+ str[0] = old; -+ str[1] = new; -+ len[0] = oldlen; -+ len[1] = newlen; -+ state[0] = oldstate; -+ state[1] = newstate; -+ -+ for (i = 0; i < 2; i++) -+ { -+ copy[i] = xmalloc (len[i] + 1); -+ memset (copy[i], '\0', len[i] + 1); -+ -+ for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) -+ { -+ state_bak = state[i]; -+ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); -+ -+ switch (mblength) -+ { -+ case (size_t)-1: -+ case (size_t)-2: -+ state[i] = state_bak; -+ /* Fall through */ -+ case 0: -+ mblength = 1; -+ break; -+ -+ default: -+ if (ignore_case) -+ { -+ uwc = towupper (wc); -+ -+ if (uwc != wc) -+ { -+ mbstate_t state_wc; -+ size_t mblen; -+ -+ memset (&state_wc, '\0', sizeof(mbstate_t)); -+ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); -+ assert (mblen != (size_t)-1); -+ } -+ else -+ memcpy (copy[i] + j, str[i] + j, mblength); -+ } -+ else -+ memcpy (copy[i] + j, str[i] + j, mblength); -+ } -+ j += mblength; -+ } -+ copy[i][j] = '\0'; -+ len[i] = j; -+ } -+ int rc = xmemcoll (copy[0], len[0], copy[1], len[1]); -+ free (copy[0]); -+ free (copy[1]); -+ return rc; -+ -+} -+#endif -+ - /* Output the line in linebuffer LINE to standard output - provided that the switches say it should be output. - MATCH is true if the line matches the previous line. -@@ -367,19 +562,38 @@ check_file (const char *infile, const char *outfile, char delimiter) - char *prevfield IF_LINT ( = NULL); - size_t prevlen IF_LINT ( = 0); - bool first_group_printed = false; -+#if HAVE_MBRTOWC -+ mbstate_t prevstate; -+ -+ memset (&prevstate, '\0', sizeof (mbstate_t)); -+#endif - - while (!feof (stdin)) - { - char *thisfield; - size_t thislen; - bool new_group; -+#if HAVE_MBRTOWC -+ mbstate_t thisstate; -+#endif - - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) - break; - - thisfield = find_field (thisline); - thislen = thisline->length - 1 - (thisfield - thisline->buffer); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ thisstate = thisline->state; - -+ new_group = (prevline->length == 0 -+ || different_multi (thisfield, prevfield, -+ thislen, prevlen, -+ thisstate, prevstate)); -+ } -+ else -+#endif - new_group = (prevline->length == 0 - || different (thisfield, prevfield, thislen, prevlen)); - -@@ -397,6 +611,10 @@ check_file (const char *infile, const char *outfile, char delimiter) - SWAP_LINES (prevline, thisline); - prevfield = thisfield; - prevlen = thislen; -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ prevstate = thisstate; -+#endif - first_group_printed = true; - } - } -@@ -409,17 +627,26 @@ check_file (const char *infile, const char *outfile, char delimiter) - size_t prevlen; - uintmax_t match_count = 0; - bool first_delimiter = true; -+#if HAVE_MBRTOWC -+ mbstate_t prevstate; -+#endif - - if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) - goto closefiles; - prevfield = find_field (prevline); - prevlen = prevline->length - 1 - (prevfield - prevline->buffer); -+#if HAVE_MBRTOWC -+ prevstate = prevline->state; -+#endif - - while (!feof (stdin)) - { - bool match; - char *thisfield; - size_t thislen; -+#if HAVE_MBRTOWC -+ mbstate_t thisstate = thisline->state; -+#endif - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) - { - if (ferror (stdin)) -@@ -428,6 +655,14 @@ check_file (const char *infile, const char *outfile, char delimiter) - } - thisfield = find_field (thisline); - thislen = thisline->length - 1 - (thisfield - thisline->buffer); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ match = !different_multi (thisfield, prevfield, -+ thislen, prevlen, thisstate, prevstate); -+ } -+ else -+#endif - match = !different (thisfield, prevfield, thislen, prevlen); - match_count += match; - -@@ -460,6 +695,9 @@ check_file (const char *infile, const char *outfile, char delimiter) - SWAP_LINES (prevline, thisline); - prevfield = thisfield; - prevlen = thislen; -+#if HAVE_MBRTOWC -+ prevstate = thisstate; -+#endif - if (!match) - match_count = 0; - } -@@ -506,6 +744,19 @@ main (int argc, char **argv) +@@ -494,6 +598,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -3117,6 +4485,209 @@ index 87a0c93..9f755d9 100644 skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; +diff --git a/tests/Coreutils.pm b/tests/Coreutils.pm +index fad7ab9..c9021a6 100644 +--- a/tests/Coreutils.pm ++++ b/tests/Coreutils.pm +@@ -264,6 +264,9 @@ sub run_tests ($$$$$) + # Yes, this is an arbitrary limit. If it causes trouble, + # consider removing it. + my $max = 30; ++ # The downstream i18n multi-byte tests have a "-mb" suffix. ++ # Therefore add 3 to the maximum test name length. ++ $max += 3; + if ($max < length $test_name) + { + warn "$program_name: $test_name: test name is too long (> $max)\n"; +diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh +new file mode 100755 +index 0000000..dd6007c +--- /dev/null ++++ b/tests/expand/mb.sh +@@ -0,0 +1,183 @@ ++#!/bin/sh ++ ++# Copyright (C) 2012-2015 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ expand ++ ++export LC_ALL=en_US.UTF-8 ++ ++#input containing multibyte characters ++cat <<\EOF > in || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++EOF ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ ++ ++cat <<\EOF > exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#multiple files as an input ++cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++expand ./in ./in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#test characters with display widths != 1 ++env printf '12345678 ++e\t|ascii(1) ++\u00E9\t|composed(1) ++e\u0301\t|decomposed(1) ++\u3000\t|ideo-space(2) ++\uFF0D\t|full-hypen(2) ++' > in || framework_failure_ ++ ++env printf '12345678 ++e |ascii(1) ++\u00E9 |composed(1) ++e\u0301 |decomposed(1) ++\u3000 |ideo-space(2) ++\uFF0D |full-hypen(2) ++' > exp || framework_failure_ ++ ++expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#shouldn't fail with "input line too long" ++#when a line starts with a control character ++env printf '\n' > in || framework_failure_ ++ ++expand < in > out || fail=1 ++compare in out > /dev/null 2>&1 || fail=1 ++ ++#non-Unicode characters interspersed between Unicode ones ++env printf '12345678 ++\t\xFF| ++\xFF\t| ++\t\xFFä| ++ä\xFF\t| ++\tä\xFF| ++\xFF\tä| ++äbcdef\xFF\t| ++' > in || framework_failure_ ++ ++env printf '12345678 ++ \xFF| ++\xFF | ++ \xFFä| ++ä\xFF | ++ ä\xFF| ++\xFF ä| ++äbcdef\xFF | ++' > exp || framework_failure_ ++ ++expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++ ++ ++#BOM header test 1 ++printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++EOF ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ ++ ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++ ++expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LANG=C expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LC_ALL=C expand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++ ++printf '\xEF\xBB\xBF' > in1; cat <<\EOF >> in1 || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++EOF ++env printf ' äöü\t. öüä. \tä xx\n' >> in1 || framework_failure_ ++ ++ ++printf '\xEF\xBB\xBF' > exp; cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++expand in1 in1 > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LANG=C expand in1 in1 > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LC_ALL=C expand in1 in1 > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++exit $fail diff --git a/tests/i18n/sort.sh b/tests/i18n/sort.sh new file mode 100755 index 0000000..26c95de @@ -3153,10 +4724,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 568944e..192f776 100644 +index 0f77786..dbe1843 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -368,6 +368,8 @@ all_tests = \ +@@ -377,6 +377,8 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -3165,8 +4736,24 @@ index 568944e..192f776 100644 tests/misc/sort-h-thousands-sep.sh \ tests/misc/sort-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ +@@ -576,6 +578,7 @@ all_tests = \ + tests/du/threshold.sh \ + tests/du/trailing-slash.sh \ + tests/du/two-args.sh \ ++ tests/expand/mb.sh \ + tests/id/gnu-zero-uids.sh \ + tests/id/no-context.sh \ + tests/id/context.sh \ +@@ -727,6 +730,7 @@ all_tests = \ + tests/touch/read-only.sh \ + tests/touch/relative.sh \ + tests/touch/trailing-slash.sh \ ++ tests/unexpand/mb.sh \ + $(all_root_tests) + + # See tests/factor/create-test.sh. diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl -index 8a9cad1..9293e39 100755 +index 7a77e6f..27f6652 100755 --- a/tests/misc/expand.pl +++ b/tests/misc/expand.pl @@ -27,6 +27,15 @@ my $prog = 'expand'; @@ -3233,7 +4820,7 @@ index 8a9cad1..9293e39 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index 7b192b4..76f073f 100755 +index 2834f92..bc1616a 100755 --- a/tests/misc/fold.pl +++ b/tests/misc/fold.pl @@ -20,9 +20,18 @@ use strict; @@ -3306,7 +4893,7 @@ index 7b192b4..76f073f 100755 my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); exit $fail; diff --git a/tests/misc/join.pl b/tests/misc/join.pl -index 4d399d8..07f2823 100755 +index 06ad777..be40204 100755 --- a/tests/misc/join.pl +++ b/tests/misc/join.pl @@ -25,6 +25,15 @@ my $limits = getlimits (); @@ -3427,7 +5014,7 @@ index 0000000..11836ba + +Exit $fail diff --git a/tests/misc/sort-merge.pl b/tests/misc/sort-merge.pl -index 23f6ed2..402a987 100755 +index 7eb4574..eda884c 100755 --- a/tests/misc/sort-merge.pl +++ b/tests/misc/sort-merge.pl @@ -26,6 +26,15 @@ my $prog = 'sort'; @@ -3487,7 +5074,7 @@ index 23f6ed2..402a987 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/sort.pl b/tests/misc/sort.pl -index c3e7f8e..6ecd3ff 100755 +index 0b0adca..fd27821 100755 --- a/tests/misc/sort.pl +++ b/tests/misc/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; @@ -3555,7 +5142,7 @@ index c3e7f8e..6ecd3ff 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index 6ba6d40..de86723 100755 +index 2e1906f..fe66012 100755 --- a/tests/misc/unexpand.pl +++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); @@ -3612,7 +5199,7 @@ index 6ba6d40..de86723 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/uniq.pl b/tests/misc/uniq.pl -index f028036..8eaf59a 100755 +index aa163cd..91d617d 100755 --- a/tests/misc/uniq.pl +++ b/tests/misc/uniq.pl @@ -23,9 +23,17 @@ my $limits = getlimits (); @@ -3688,7 +5275,7 @@ index f028036..8eaf59a 100755 @Tests = triple_test \@Tests; diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl -index ec3980a..136657d 100755 +index 7ac6d4c..ae6cc35 100755 --- a/tests/pr/pr-tests.pl +++ b/tests/pr/pr-tests.pl @@ -24,6 +24,15 @@ use strict; @@ -3707,9 +5294,9 @@ index ec3980a..136657d 100755 my @tv = ( # -b option is no longer an official option. But it's still working to -@@ -474,8 +483,48 @@ push @Tests, - {IN=>{2=>"a\n"}}, - {OUT=>"a\t\t\t\t \t\t\ta\n"} ]; +@@ -512,8 +521,48 @@ push @Tests, + {IN=>"x\tx\tx\tx\tx\nx\tx\tx\tx\tx\n"}, + {OUT=>"x\tx\tx\tx\tx\tx\tx\tx\tx\tx\n"} ]; +# Add _POSIX2_VERSION=199209 to the environment of each test +# that uses an old-style option like +1. @@ -3756,6 +5343,184 @@ index ec3980a..136657d 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; +diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh +new file mode 100755 +index 0000000..8a82d74 +--- /dev/null ++++ b/tests/unexpand/mb.sh +@@ -0,0 +1,172 @@ ++#!/bin/sh ++ ++# Copyright (C) 2012-2015 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ unexpand ++ ++export LC_ALL=en_US.UTF-8 ++ ++#input containing multibyte characters ++cat > in <<\EOF ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++cat > exp <<\EOF ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++unexpand -a < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++ ++#multiple files as an input ++cat >> exp <<\EOF ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++ ++unexpand -a ./in ./in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#test characters with a display width larger than 1 ++ ++env printf '12345678 ++e |ascii(1) ++\u00E9 |composed(1) ++e\u0301 |decomposed(1) ++\u3000 |ideo-space(2) ++\uFF0D |full-hypen(2) ++' > in || framework_failure_ ++ ++env printf '12345678 ++e\t|ascii(1) ++\u00E9\t|composed(1) ++e\u0301\t|decomposed(1) ++\u3000\t|ideo-space(2) ++\uFF0D\t|full-hypen(2) ++' > exp || framework_failure_ ++ ++unexpand -a < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#test input where a blank of width > 1 is not being substituted ++in="$(LC_ALL=en_US.UTF-8 printf ' \u3000 ö ü ß')" ++exp='   ö ü ß' ++ ++unexpand -a < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#non-Unicode characters interspersed between Unicode ones ++env printf '12345678 ++ \xFF| ++\xFF | ++ \xFFä| ++ä\xFF | ++ ä\xFF| ++\xFF ä| ++äbcdef\xFF | ++' > in || framework_failure_ ++ ++env printf '12345678 ++\t\xFF| ++\xFF\t| ++\t\xFFä| ++ä\xFF\t| ++\tä\xFF| ++\xFF\tä| ++äbcdef\xFF\t| ++' > exp || framework_failure_ ++ ++unexpand -a < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++#BOM header test 1 ++printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ ++ ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++unexpand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LANG=C unexpand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LC_ALL=C unexpand < in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++ ++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++1234567812345678123456781 ++. . . . ++a b c d ++. . . . ++ä ö ü ß ++. . . . ++ äöü . öüä. ä xx ++EOF ++ ++ ++unexpand in in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LANG=C unexpand in in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 ++ ++LC_ALL=C unexpand in in > out || fail=1 ++compare exp out > /dev/null 2>&1 || fail=1 -- -2.7.4 +2.34.1 diff --git a/coreutils-keyring.gpg b/coreutils-keyring.gpg new file mode 100644 index 0000000..003a885 --- /dev/null +++ b/coreutils-keyring.gpg @@ -0,0 +1,312 @@ +Release GPG keyring of coreutils group. + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +ELphkzjc6eM3CaOZ73u4GVXotheeUabUHQ== +=drvb +-----END PGP PUBLIC KEY BLOCK----- \ No newline at end of file diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 8274a23..1f7f3a3 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,3 +1,32 @@ +From d70ddb3eb845c494280e7365e2b889242e7e1bb9 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Mon, 4 Oct 2021 08:45:53 +0200 +Subject: [PATCH] coreutils-selinux.patch + +--- + doc/coreutils.texi | 5 +++++ + man/chcon.x | 2 +- + man/runcon.x | 2 +- + src/cp.c | 16 +++++++++++++++- + src/install.c | 10 ++++++++-- + 5 files changed, 30 insertions(+), 5 deletions(-) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 6810c15..19b535c 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -8766,6 +8766,11 @@ done + exit $fail + @end example + ++@item -c ++@cindex SELinux security context information, preserving ++Preserve SELinux security context of the original files if possible. ++Some file systems don't support storing of SELinux security context. ++ + @item --copy-contents + @cindex directories, copying recursively + @cindex copying directories recursively diff --git a/man/chcon.x b/man/chcon.x index 8c1ff6f..c84fb96 100644 --- a/man/chcon.x @@ -20,20 +49,20 @@ index d2df13e..5c5f5d8 100644 Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, diff --git a/src/cp.c b/src/cp.c -index 1b528c6..25dbb88 100644 +index c97a675..89fb8ec 100644 --- a/src/cp.c +++ b/src/cp.c -@@ -203,6 +203,9 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ +@@ -191,6 +191,9 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ + additional attributes: context, links, xattr,\ + \n\ all\n\ - "), stdout); - fputs (_("\ -+ -c deprecated, same as --preserve=context\n\ +"), stdout); + fputs (_("\ - --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ - --parents use full source file name under DIRECTORY\n\ ++ -c deprecated, same as --preserve=context\n\ "), stdout); -@@ -929,7 +932,7 @@ main (int argc, char **argv) + fputs (_("\ + --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ +@@ -954,7 +957,7 @@ main (int argc, char **argv) selinux_enabled = (0 < is_selinux_enabled ()); cp_option_init (&x); @@ -42,7 +71,7 @@ index 1b528c6..25dbb88 100644 long_opts, NULL)) != -1) { -@@ -977,6 +980,17 @@ main (int argc, char **argv) +@@ -1002,6 +1005,17 @@ main (int argc, char **argv) copy_contents = true; break; @@ -60,27 +89,11 @@ index 1b528c6..25dbb88 100644 case 'd': x.preserve_links = true; x.dereference = DEREF_NEVER; -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 47e4480..cff2ead 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -8083,6 +8083,11 @@ done - exit $fail - @end example - -+@item -c -+@cindex SELinux security context information, preserving -+Preserve SELinux security context of the original files if possible. -+Some file systems don't support storing of SELinux security context. -+ - @item --copy-contents - @cindex directories, copying recursively - @cindex copying directories recursively diff --git a/src/install.c b/src/install.c -index d79d597..437889a 100644 +index c9456fe..2b1bee9 100644 --- a/src/install.c +++ b/src/install.c -@@ -673,7 +673,7 @@ In the 4th form, create all components of the given DIRECTORY(ies).\n\ +@@ -638,7 +638,7 @@ In the 4th form, create all components of the given DIRECTORY(ies).\n\ -v, --verbose print the name of each directory as it is created\n\ "), stdout); fputs (_("\ @@ -89,7 +102,7 @@ index d79d597..437889a 100644 -Z set SELinux security context of destination\n\ file and each created directory to default type\n\ --context[=CTX] like -Z, or if CTX is specified then set the\n\ -@@ -824,7 +824,7 @@ main (int argc, char **argv) +@@ -790,7 +790,7 @@ main (int argc, char **argv) dir_arg = false; umask (0); @@ -98,7 +111,7 @@ index d79d597..437889a 100644 NULL)) != -1) { switch (optc) -@@ -885,6 +885,8 @@ main (int argc, char **argv) +@@ -851,6 +851,8 @@ main (int argc, char **argv) no_target_directory = true; break; @@ -107,7 +120,7 @@ index d79d597..437889a 100644 case PRESERVE_CONTEXT_OPTION: if (! selinux_enabled) { -@@ -892,6 +894,10 @@ main (int argc, char **argv) +@@ -858,6 +860,10 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); break; } @@ -118,3 +131,6 @@ index d79d597..437889a 100644 x.preserve_security_context = true; use_default_selinux_context = false; break; +-- +2.31.1 + diff --git a/coreutils-ss.tar.xz.sig b/coreutils-ss.tar.xz.sig new file mode 100644 index 0000000..34c9c21 --- /dev/null +++ b/coreutils-ss.tar.xz.sig @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCAAdFiEEbDfcEhIaUAa8HbgE32/ZcTBgN9kFAmJXLFQACgkQ32/ZcTBg +N9nZHA/9FYyhdcGBRb38sXL9H8eDZVgyyU9n0vosx54C4fkZGLb94yJIKTkdtSJC +buBycS5PGBGZwx1TC7U5dYj9I/WB27ZIdrH4qEHnKLtPfGfDy1en0+JpJle4FWWi +uViW5xxqt33ME+bE7DXZUMimvfQR6uEEkL2UU7hJdWDikf3VgSQJllCViS92zDsg +v9Y4Wz2dvctLaGu4jYd+WRKgJ+N1kliJKDaz6KHKrWEjfFH2ECXYttm21y2fZ3Ib +PZZSHKnSzzw4yyrJFDiLELKEILdsqxVr7Bxbv52ZqBTLsSOW0mjR+LMC5yU/gjMT +DstU38k6L0SSSYh+6T0NCeW0Plxq17fLxDmQa8lfrnbW6rhtGu8eW4FdWa7n7qPC +qwsvRCLxc6Kd4Wpw5qOioyzCzV20bpwsJvvylfn2wnln7Pr0Xb2iEyh2Oi/KWWo5 +MiGdW8WR9vLScHSwzMyp8iTnwOZW6IBIfPkq3Nr3ExTz5m4bFPho7tDvHn+/BY3W +XXyJ/QJqyJqtOcC6wR8VK1eWtmgDDBKWDkJn1XTMAVVPmeF7BLH0WLCSpp4vVvQI +U9PKF+y6Gt3yqtoLbFbl5SyAmvH62fyvvoOSozO/evXADTMCZVKUgBywg6zM0yEA +FBM1GTzPoLa9pXStVFmqeT0UKo9YFez5E+m4bGlrbo2VPJh1Zws= +=94MD +-----END PGP SIGNATURE----- diff --git a/coreutils.spec b/coreutils.spec index 11cfbec..8cf4c64 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,10 +1,10 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.31 -Release: 10%{?dist} +Version: 9.0 +Release: 9999.2%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ -Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz +Source0: https://pixelbeat.org/cu/coreutils-ss.tar.xz Source50: supported_utils Source51: coreutils-provides.inc Source105: coreutils-colorls.sh @@ -13,15 +13,6 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ -# md5sum,b2sum,sha*sum: --help: add note about binary/text mode -Patch1: coreutils-8.31-sums-man-pages.patch - -# improve an upstream test that relied on /proc/kallsyms being immutable -Patch2: coreutils-8.31-improve-test-cp-proc-short-read.patch - -# make upstream test-suite work with root privileges (#1800597) -Patch3: coreutils-8.31-root-tests.patch - # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -29,8 +20,8 @@ Patch100: coreutils-8.26-test-lock.patch Patch105: coreutils-8.26-selinuxenable.patch # downstream changes to default DIR_COLORS -Patch102: coreutils-8.25-DIR_COLORS.patch -#do display processor type for uname -p/-i based on uname(2) syscall +Patch102: coreutils-8.32-DIR_COLORS.patch +# to be removed (#548834) Patch103: coreutils-8.2-uname-processortype.patch #df --direct Patch104: coreutils-df-direct.patch @@ -40,24 +31,9 @@ Patch107: coreutils-8.4-mkdir-modenote.patch # sh-utils #add info about TZ envvar to date manpage Patch703: sh-utils-2.0.11-dateman.patch -Patch713: coreutils-4.5.3-langinfo.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch -# (sb) lin18nux/lsb compliance - expand/unexpand -Patch801: coreutils-i18n-expand-unexpand.patch -# i18n patch for cut - old version - used -Patch804: coreutils-i18n-cut-old.patch -# The unexpand patch above is not correct. Sent to the patch authors -Patch803: coreutils-i18n-fix-unexpand.patch -#(un)expand - allow multiple files on input - broken by patch 801 -Patch805: coreutils-i18n-fix2-expand-unexpand.patch -#(un)expand - test BOM headers -Patch806: coreutils-i18n-un-expand-BOM.patch -# make 'sort -h' work for arbitrary column even when using UTF-8 locales -Patch807: coreutils-i18n-sort-human.patch -# fold: preserve new-lines in mutlibyte text (#1418505) -Patch808: coreutils-i18n-fold-newline.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch @@ -82,17 +58,23 @@ BuildRequires: libattr-devel BuildRequires: libcap-devel BuildRequires: libselinux-devel BuildRequires: libselinux-utils +BuildRequires: make BuildRequires: openssl-devel BuildRequires: strace BuildRequires: texinfo + +# test-only dependencies +BuildRequires: perl-interpreter +BuildRequires: perl(FileHandle) %if 23 < 0%{?fedora} || 7 < 0%{?rhel} # needed by i18n test-cases BuildRequires: glibc-langpack-en +BuildRequires: glibc-langpack-fr +BuildRequires: glibc-langpack-ko %endif Requires: %{name}-common = %{version}-%{release} -Requires: ncurses Provides: coreutils-full = %{version}-%{release} %include %{SOURCE51} @@ -123,17 +105,31 @@ packaged as a single multicall binary. # yum obsoleting rules explained at: # https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7 Obsoletes: %{name} < 8.24-100 + +# info doc refers to "Specifying the Time Zone" from glibc-doc (#959597) +Suggests: glibc-doc + Summary: coreutils common optional components %description common Optional though recommended components, including documentation and translations. %prep -%autosetup -N +%autosetup -N -n %{name}-%{version}.209-87d5 -# will be modified by coreutils-8.25-DIR_COLORS.patch -tee DIR_COLORS{,.256color,.lightbgcolor} /dev/null -# git add DIR_COLORS{,.256color,.lightbgcolor} +# will be regenerated in the build directories +rm -f src/fs.h + +# will be further modified by coreutils-8.32-DIR_COLORS.patch +sed src/dircolors.hin \ + -e 's| 00;36$| 01;36|' \ + > DIR_COLORS +sed src/dircolors.hin \ + -e 's| 01;31$| 00;31|' \ + -e 's| 01;35$| 00;35|' \ + > DIR_COLORS.lightbgcolor + +# git add DIR_COLORS{,.lightbgcolor} # git commit -m "clone DIR_COLORS before patching" # apply all patches @@ -147,14 +143,33 @@ autoreconf -fiv %build export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fpic" + +# disable -flto on ppc64le to make test-float pass (#1789115) +%ifarch ppc64le +CFLAGS="$CFLAGS -fno-lto" +%endif + +# Upstream suggests to build with -Dlint for static analyzers: +# https://lists.gnu.org/archive/html/coreutils/2018-06/msg00110.html +# ... and even for production binary RPMs: +# https://lists.gnu.org/archive/html/bug-gnulib/2020-05/msg00130.html +# There is currently no measurable performance drop or other known downside. +CFLAGS="$CFLAGS -Dlint" + +# make mknod work again in chroot without /proc being mounted (#1811038) +export ac_cv_func_lchmod="no" + +# needed for out-of-tree build +%global _configure ../configure + %{expand:%%global optflags %{optflags} -D_GNU_SOURCE=1} for type in separate single; do - mkdir $type && \ - (cd $type && ln -s ../configure || exit 1 + mkdir -p $type && \ + (cd $type || exit $? if test $type = 'single'; then config_single='--enable-single-binary' config_single="$config_single --without-openssl" # smaller/slower sha*sum - config_single="$config_single --without-gmp" # expr/factor machine ints + config_single="$config_single --without-libgmp" # expr/factor machine ints else config_single='--with-openssl' # faster sha*sum fi @@ -164,10 +179,10 @@ for type in separate single; do --enable-no-install-program=kill,uptime \ --with-tty-group \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : - make all %{?_smp_mflags} + %make_build all V=1 # make sure that parse-datetime.{c,y} ends up in debuginfo (#1555079) - ln -v ../lib/parse-datetime.{c,y} . + ln -fv ../lib/parse-datetime.{c,y} . ) done @@ -205,8 +220,7 @@ for type in separate single; do done mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/profile.d -install -p -c -m644 DIR_COLORS{,.256color,.lightbgcolor} \ - $RPM_BUILD_ROOT%{_sysconfdir} +install -p -c -m644 DIR_COLORS{,.lightbgcolor} $RPM_BUILD_ROOT%{_sysconfdir} install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.sh install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh diff --git a/rh_i18n_wip.tar.gz b/rh_i18n_wip.tar.gz deleted file mode 100644 index 24b7cdc..0000000 Binary files a/rh_i18n_wip.tar.gz and /dev/null differ diff --git a/sources b/sources index ca35b8f..04795af 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (coreutils-8.31.tar.xz) = ef8941dae845bbf5ae5838bc49e44554a766302930601aada6fa594e8088f0fbad74e481ee392ff89633e68b99e4da3f761fcb5d31ee3b233d540fe2a2d4e1af +SHA512 (coreutils-ss.tar.xz) = 3d51477d0f5a2082dd723974554185c855eea28189875b9b7ce88605db044897b0b8b0244d06ff6eb9f6fee5c2279437539dd8518d5a30d02e824d3a54b51303 diff --git a/upstream-key.gpg b/upstream-key.gpg deleted file mode 100644 index dc6dc1d..0000000 --- a/upstream-key.gpg +++ /dev/null @@ -1,123 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.6 (GNU/Linux) - -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 -Ke4= -=zRdO ------END PGP PUBLIC KEY BLOCK-----