-diff -urNp coreutils-8.19-orig/lib/linebuffer.h coreutils-8.19/lib/linebuffer.h
---- coreutils-8.19-orig/lib/linebuffer.h 2012-01-06 10:14:31.000000000 +0100
-+++ coreutils-8.19/lib/linebuffer.h 2012-08-20 13:52:04.061593006 +0200
+diff -urNp coreutils-8.21-orig/lib/linebuffer.h coreutils-8.21/lib/linebuffer.h
+--- coreutils-8.21-orig/lib/linebuffer.h 2013-01-02 13:34:46.000000000 +0100
++++ coreutils-8.21/lib/linebuffer.h 2013-02-15 14:25:07.758469108 +0100
@@ -21,6 +21,11 @@
# include <stdio.h>
};
/* Initialize linebuffer LINEBUFFER for use. */
-diff -urNp coreutils-8.19-orig/src/cut.c coreutils-8.19/src/cut.c
---- coreutils-8.19-orig/src/cut.c 2012-07-21 16:54:31.000000000 +0200
-+++ coreutils-8.19/src/cut.c 2012-08-20 13:52:52.299593173 +0200
+diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c
+--- coreutils-8.21-orig/src/cut.c 2013-02-05 00:40:31.000000000 +0100
++++ coreutils-8.21/src/cut.c 2013-02-15 14:25:07.760467982 +0100
@@ -28,6 +28,11 @@
#include <assert.h>
#include <getopt.h>
/* True if the --output-delimiter=STRING option was specified. */
static bool output_delimiter_specified;
-@@ -206,7 +283,7 @@ Mandatory arguments to long options are
+@@ -205,7 +282,7 @@ Print selected parts of lines from each
-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\
"), stdout);
fputs (_("\
--complement complement the set of selected bytes, characters\n\
-@@ -365,7 +442,7 @@ set_fields (const char *fieldstr)
- in_digits = false;
- /* Starting a range. */
- if (dash_found)
-- FATAL_ERROR (_("invalid byte or field list"));
-+ FATAL_ERROR (_("invalid byte, character or field list"));
- dash_found = true;
- fieldstr++;
-
-@@ -389,14 +466,16 @@ set_fields (const char *fieldstr)
- if (!rhs_specified)
- {
- /* 'n-'. From 'initial' to end of line. */
-- eol_range_start = initial;
-+ if (eol_range_start == 0 ||
-+ (eol_range_start != 0 && eol_range_start > initial))
-+ eol_range_start = initial;
- field_found = true;
- }
- else
- {
- /* 'm-n' or '-n' (1-n). */
- if (value < initial)
-- FATAL_ERROR (_("invalid decreasing range"));
-+ FATAL_ERROR (_("invalid byte, character or field list"));
-
- /* Is there already a range going to end of line? */
- if (eol_range_start != 0)
-@@ -476,6 +555,9 @@ set_fields (const char *fieldstr)
+@@ -480,6 +557,9 @@ set_fields (const char *fieldstr)
if (operating_mode == byte_mode)
error (0, 0,
_("byte offset %s is too large"), quote (bad_num));
else
error (0, 0,
_("field number %s is too large"), quote (bad_num));
-@@ -486,7 +568,7 @@ set_fields (const char *fieldstr)
- fieldstr++;
- }
- else
-- FATAL_ERROR (_("invalid byte or field list"));
-+ FATAL_ERROR (_("invalid byte, character or field list"));
- }
-
- max_range_endpoint = 0;
-@@ -581,6 +663,77 @@ cut_bytes (FILE *stream)
+@@ -588,6 +668,77 @@ cut_bytes (FILE *stream)
}
}
/* Read from stream STREAM, printing to standard output any selected fields. */
static void
-@@ -703,13 +856,195 @@ cut_fields (FILE *stream)
+@@ -709,13 +860,195 @@ cut_fields (FILE *stream)
}
}
}
/* Process file FILE to standard output.
-@@ -761,6 +1096,8 @@ main (int argc, char **argv)
+@@ -767,6 +1100,8 @@ main (int argc, char **argv)
bool ok;
bool delim_specified = false;
char *spec_list_string IF_LINT ( = NULL);
initialize_main (&argc, &argv);
set_program_name (argv[0]);
-@@ -783,7 +1120,6 @@ main (int argc, char **argv)
+@@ -789,7 +1124,6 @@ main (int argc, char **argv)
switch (optc)
{
case 'b':
/* Build the byte list. */
if (operating_mode != undefined_mode)
FATAL_ERROR (_("only one type of list may be specified"));
-@@ -791,6 +1127,14 @@ main (int argc, char **argv)
+@@ -797,6 +1131,14 @@ main (int argc, char **argv)
spec_list_string = optarg;
break;
case 'f':
/* Build the field list. */
if (operating_mode != undefined_mode)
-@@ -802,10 +1146,35 @@ main (int argc, char **argv)
+@@ -808,10 +1150,36 @@ main (int argc, char **argv)
case 'd':
/* New delimiter. */
/* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */
+ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0')
+ FATAL_ERROR (_("the delimiter must be a single character"));
+ memcpy (mbdelim, optarg, delimlen);
++ mbdelim[delimlen] = '\0';
+ }
+ }
+
break;
case OUTPUT_DELIMITER_OPTION:
-@@ -818,6 +1187,7 @@ main (int argc, char **argv)
+@@ -824,6 +1191,7 @@ main (int argc, char **argv)
break;
case 'n':
break;
case 's':
-@@ -840,7 +1210,7 @@ main (int argc, char **argv)
- if (operating_mode == undefined_mode)
- FATAL_ERROR (_("you must specify a list of bytes, characters, or fields"));
-
-- if (delim != '\0' && operating_mode != field_mode)
-+ if (delim_specified && operating_mode != field_mode)
- FATAL_ERROR (_("an input delimiter may be specified only\
- when operating on fields"));
-
-@@ -867,15 +1237,34 @@ main (int argc, char **argv)
+@@ -873,15 +1241,34 @@ main (int argc, char **argv)
}
if (!delim_specified)
}
if (optind == argc)
-diff -urNp coreutils-8.19-orig/src/expand.c coreutils-8.19/src/expand.c
---- coreutils-8.19-orig/src/expand.c 2012-07-21 16:54:31.000000000 +0200
-+++ coreutils-8.19/src/expand.c 2012-08-20 13:54:02.974621693 +0200
+Binary files coreutils-8.21-orig/src/.cut.c.swp and coreutils-8.21/src/.cut.c.swp differ
+diff -urNp coreutils-8.21-orig/src/expand.c coreutils-8.21/src/expand.c
+--- coreutils-8.21-orig/src/expand.c 2013-01-31 01:46:24.000000000 +0100
++++ coreutils-8.21/src/expand.c 2013-02-15 14:25:07.774467536 +0100
@@ -37,12 +37,29 @@
#include <stdio.h>
#include <getopt.h>
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "expand"
-@@ -358,6 +375,142 @@ expand (void)
+@@ -357,6 +374,142 @@ expand (void)
}
}
int
main (int argc, char **argv)
{
-@@ -422,7 +575,12 @@ main (int argc, char **argv)
+@@ -421,7 +574,12 @@ main (int argc, char **argv)
file_list = (optind < argc ? &argv[optind] : stdin_argv);
if (have_read_stdin && fclose (stdin) != 0)
error (EXIT_FAILURE, errno, "-");
-diff -urNp coreutils-8.19-orig/src/fold.c coreutils-8.19/src/fold.c
---- coreutils-8.19-orig/src/fold.c 2012-07-21 16:54:31.000000000 +0200
-+++ coreutils-8.19/src/fold.c 2012-08-20 13:52:04.066592980 +0200
+diff -urNp coreutils-8.21-orig/src/fold.c coreutils-8.21/src/fold.c
+--- coreutils-8.21-orig/src/fold.c 2013-01-31 01:46:24.000000000 +0100
++++ coreutils-8.21/src/fold.c 2013-02-15 14:25:07.789467891 +0100
@@ -22,12 +22,34 @@
#include <getopt.h>
#include <sys/types.h>
{"spaces", no_argument, NULL, 's'},
{"width", required_argument, NULL, 'w'},
{GETOPT_HELP_OPTION_DECL},
-@@ -77,6 +120,7 @@ Mandatory arguments to long options are
- "), stdout);
+@@ -76,6 +119,7 @@ standard output.\n\
+
fputs (_("\
-b, --bytes count bytes rather than columns\n\
+ -c, --characters count characters rather than columns\n\
-s, --spaces break at spaces\n\
-w, --width=WIDTH use WIDTH columns instead of 80\n\
"), stdout);
-@@ -94,7 +138,7 @@ Mandatory arguments to long options are
+@@ -93,7 +137,7 @@ standard output.\n\
static size_t
adjust_column (size_t column, char c)
{
{
if (c == '\b')
{
-@@ -117,30 +161,14 @@ adjust_column (size_t column, char c)
+@@ -116,30 +160,14 @@ adjust_column (size_t column, char c)
to stdout, with maximum line length WIDTH.
Return true if successful. */
fadvise (istream, FADVISE_SEQUENTIAL);
-@@ -170,6 +198,15 @@ fold_file (char const *filename, size_t
+@@ -169,6 +197,15 @@ fold_file (char const *filename, size_t
bool found_blank = false;
size_t logical_end = offset_out;
/* Look for the last blank. */
while (logical_end)
{
-@@ -216,11 +253,221 @@ fold_file (char const *filename, size_t
+@@ -215,11 +252,221 @@ fold_file (char const *filename, size_t
line_out[offset_out++] = c;
}
if (ferror (istream))
{
error (0, saved_errno, "%s", filename);
-@@ -253,7 +500,8 @@ main (int argc, char **argv)
+@@ -252,7 +499,8 @@ main (int argc, char **argv)
atexit (close_stdout);
while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
{
-@@ -262,7 +510,15 @@ main (int argc, char **argv)
+@@ -261,7 +509,15 @@ main (int argc, char **argv)
switch (optc)
{
case 'b': /* Count bytes rather than columns. */
break;
case 's': /* Break at word boundaries. */
-diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c
---- coreutils-8.19-orig/src/join.c 2012-07-21 16:54:31.000000000 +0200
-+++ coreutils-8.19/src/join.c 2012-08-20 13:52:04.069594876 +0200
+diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c
+--- coreutils-8.21-orig/src/join.c 2013-01-31 01:46:24.000000000 +0100
++++ coreutils-8.21/src/join.c 2013-02-15 14:25:07.804467922 +0100
@@ -22,18 +22,32 @@
#include <sys/types.h>
#include <getopt.h>
static void
freeline (struct line *line)
{
-@@ -313,56 +472,115 @@ keycmp (struct line const *line1, struct
+@@ -313,56 +472,130 @@ keycmp (struct line const *line1, struct
size_t jf_1, size_t jf_2)
{
/* Start of field to compare in each file. */
+ size_t len[2]; /* Length of fields to compare. */
int diff;
+ int i, j;
++ int mallocd = 0;
if (jf_1 < line1->nfields)
{
+
+ for (i = 0; i < 2; i++)
+ {
-+ copy[i] = alloca (len[i] + 1);
++ mallocd = 1;
++ copy[i] = xmalloc (len[i] + 1);
+
+ for (j = 0; j < MIN (len[0], len[1]);)
+ {
+ {
+ for (i = 0; i < 2; i++)
+ {
-+ copy[i] = alloca (len[i] + 1);
++ mallocd = 1;
++ copy[i] = xmalloc (len[i] + 1);
+
+ for (j = 0; j < MIN (len[0], len[1]); j++)
+ copy[i][j] = toupper (beg[i][j]);
}
+ if (hard_LC_COLLATE)
-+ return xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]);
++ {
++ diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]);
++
++ if (mallocd)
++ for (i = 0; i < 2; i++)
++ free (copy[i]);
++
++ return diff;
++ }
+ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1]));
+
++ if (mallocd)
++ for (i = 0; i < 2; i++)
++ free (copy[i]);
++
+
if (diff)
return diff;
}
/* Check that successive input lines PREV and CURRENT from input file
-@@ -454,6 +672,11 @@ get_line (FILE *fp, struct line **linep,
+@@ -454,6 +687,11 @@ get_line (FILE *fp, struct line **linep,
}
++line_no[which - 1];
xfields (line);
if (prevline[which - 1])
-@@ -553,21 +776,28 @@ prfield (size_t n, struct line const *li
+@@ -553,21 +791,28 @@ prfield (size_t n, struct line const *li
/* Output all the fields in line, other than the join field. */
prfield (i, line);
}
}
-@@ -578,7 +808,6 @@ static void
+@@ -578,7 +823,6 @@ static void
prjoin (struct line const *line1, struct line const *line2)
{
const struct outlist *outlist;
size_t field;
struct line const *line;
-@@ -612,7 +841,7 @@ prjoin (struct line const *line1, struct
+@@ -612,7 +856,7 @@ prjoin (struct line const *line1, struct
o = o->next;
if (o == NULL)
break;
}
putchar ('\n');
}
-@@ -1090,21 +1319,46 @@ main (int argc, char **argv)
+@@ -1090,21 +1334,46 @@ main (int argc, char **argv)
case 't':
{
break;
case NOCHECK_ORDER_OPTION:
-diff -urNp coreutils-8.19-orig/src/pr.c coreutils-8.19/src/pr.c
---- coreutils-8.19-orig/src/pr.c 2012-07-21 16:54:31.000000000 +0200
-+++ coreutils-8.19/src/pr.c 2012-08-20 13:52:04.074593445 +0200
+diff -urNp coreutils-8.21-orig/src/pr.c coreutils-8.21/src/pr.c
+--- coreutils-8.21-orig/src/pr.c 2013-01-31 01:46:24.000000000 +0100
++++ coreutils-8.21/src/pr.c 2013-02-15 14:25:07.819467936 +0100
@@ -312,6 +312,32 @@
#include <getopt.h>
/* (-i) The width of the output tab. */
static int chars_per_output_tab = 8;
-@@ -638,7 +692,13 @@ static int power_10;
+@@ -634,7 +688,13 @@ static int line_number;
static bool numbered_lines = false;
/* (-n) Character which follows each line number. */
/* (-n) line counting starts with 1st line of input file (not with 1st
line of 1st page printed). */
-@@ -691,6 +751,7 @@ static bool use_col_separator = false;
+@@ -687,6 +747,7 @@ static bool use_col_separator = false;
-a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */
static char *col_sep_string = (char *) "";
static int col_sep_length = 0;
static char *column_separator = (char *) " ";
static char *line_separator = (char *) "\t";
-@@ -847,6 +908,13 @@ separator_string (const char *optarg_S)
+@@ -843,6 +904,13 @@ separator_string (const char *optarg_S)
col_sep_length = (int) strlen (optarg_S);
col_sep_string = xmalloc (col_sep_length + 1);
strcpy (col_sep_string, optarg_S);
}
int
-@@ -871,6 +939,21 @@ main (int argc, char **argv)
+@@ -867,6 +935,21 @@ main (int argc, char **argv)
atexit (close_stdout);
n_files = 0;
file_names = (argc > 1
? xmalloc ((argc - 1) * sizeof (char *))
-@@ -947,8 +1030,12 @@ main (int argc, char **argv)
+@@ -943,8 +1026,12 @@ main (int argc, char **argv)
break;
case 'e':
if (optarg)
/* Could check tab width > 0. */
untabify_input = true;
break;
-@@ -961,8 +1048,12 @@ main (int argc, char **argv)
+@@ -957,8 +1044,12 @@ main (int argc, char **argv)
break;
case 'i':
if (optarg)
/* Could check tab width > 0. */
tabify_output = true;
break;
-@@ -989,8 +1080,8 @@ main (int argc, char **argv)
+@@ -985,8 +1076,8 @@ main (int argc, char **argv)
case 'n':
numbered_lines = true;
if (optarg)
break;
case 'N':
skip_count = false;
-@@ -1029,7 +1120,7 @@ main (int argc, char **argv)
+@@ -1025,7 +1116,7 @@ main (int argc, char **argv)
old_s = false;
/* Reset an additional input of -s, -S dominates -s */
col_sep_string = bad_cast ("");
use_col_separator = true;
if (optarg)
separator_string (optarg);
-@@ -1186,10 +1277,45 @@ main (int argc, char **argv)
+@@ -1182,10 +1273,45 @@ main (int argc, char **argv)
a number. */
static void
if (*arg)
{
long int tmp_long;
-@@ -1211,6 +1337,11 @@ static void
+@@ -1207,6 +1333,11 @@ static void
init_parameters (int number_of_files)
{
int chars_used_by_number = 0;
lines_per_body = lines_per_page - lines_per_header - lines_per_footer;
if (lines_per_body <= 0)
-@@ -1248,7 +1379,7 @@ init_parameters (int number_of_files)
+@@ -1244,7 +1375,7 @@ init_parameters (int number_of_files)
else
col_sep_string = column_separator;
use_col_separator = true;
}
/* It's rather pointless to define a TAB separator with column
-@@ -1279,11 +1410,11 @@ init_parameters (int number_of_files)
+@@ -1274,11 +1405,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. */
/* The number is part of the column width unless we are
printing files in parallel. */
-@@ -1298,7 +1429,7 @@ init_parameters (int number_of_files)
+@@ -1287,7 +1418,7 @@ init_parameters (int number_of_files)
}
chars_per_column = (chars_per_line - chars_used_by_number
if (chars_per_column < 1)
error (EXIT_FAILURE, 0, _("page width too narrow"));
-@@ -1315,7 +1446,7 @@ init_parameters (int number_of_files)
+@@ -1305,7 +1436,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);
}
\f
/* Open the necessary files,
-@@ -1423,7 +1554,7 @@ init_funcs (void)
+@@ -1413,7 +1544,7 @@ init_funcs (void)
/* Enlarge p->start_position of first column to use the same form of
padding_not_printed with all columns. */
/* This loop takes care of all but the rightmost column. */
-@@ -1457,7 +1588,7 @@ init_funcs (void)
+@@ -1447,7 +1578,7 @@ init_funcs (void)
}
else
{
h_next = h + chars_per_column;
}
}
-@@ -1748,9 +1879,9 @@ static void
+@@ -1738,9 +1869,9 @@ static void
align_column (COLUMN *p)
{
padding_not_printed = p->start_position;
padding_not_printed = ANYWHERE;
}
-@@ -2021,13 +2152,13 @@ store_char (char c)
+@@ -2011,13 +2142,13 @@ store_char (char c)
/* May be too generous. */
buff = X2REALLOC (buff, &buff_allocated);
}
- int i;
+ int i, j;
char *s;
- int left_cut;
+ int num_width;
-@@ -2050,22 +2181,24 @@ add_line_number (COLUMN *p)
+@@ -2034,22 +2165,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. */
output_position = POS_AFTER_TAB (chars_per_output_tab,
output_position);
}
-@@ -2226,7 +2359,7 @@ print_white_space (void)
+@@ -2210,7 +2343,7 @@ print_white_space (void)
while (goal - h_old > 1
&& (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal)
{
h_old = h_new;
}
while (++h_old <= goal)
-@@ -2246,6 +2379,7 @@ print_sep_string (void)
+@@ -2230,6 +2363,7 @@ print_sep_string (void)
{
char *s;
int l = col_sep_length;
s = col_sep_string;
-@@ -2259,6 +2393,7 @@ print_sep_string (void)
+@@ -2243,6 +2377,7 @@ print_sep_string (void)
{
for (; separators_not_printed > 0; --separators_not_printed)
{
while (l-- > 0)
{
/* 3 types of sep_strings: spaces only, spaces and chars,
-@@ -2272,12 +2407,15 @@ print_sep_string (void)
+@@ -2256,12 +2391,15 @@ print_sep_string (void)
}
else
{
/* sep_string ends with some spaces */
if (spaces_not_printed > 0)
print_white_space ();
-@@ -2305,7 +2443,7 @@ print_clump (COLUMN *p, int n, char *clu
+@@ -2289,7 +2427,7 @@ print_clump (COLUMN *p, int n, char *clu
required number of tabs and spaces. */
static void
{
if (tabify_output)
{
-@@ -2329,6 +2467,74 @@ print_char (char c)
+@@ -2313,6 +2451,74 @@ print_char (char c)
putchar (c);
}
/* Skip to page PAGE before printing.
PAGE may be larger than total number of pages. */
-@@ -2508,9 +2714,9 @@ read_line (COLUMN *p)
+@@ -2492,9 +2698,9 @@ read_line (COLUMN *p)
align_empty_cols = false;
}
padding_not_printed = ANYWHERE;
}
-@@ -2611,9 +2817,9 @@ print_stored (COLUMN *p)
+@@ -2595,9 +2801,9 @@ print_stored (COLUMN *p)
}
}
padding_not_printed = ANYWHERE;
}
-@@ -2626,8 +2832,8 @@ print_stored (COLUMN *p)
+@@ -2610,8 +2816,8 @@ print_stored (COLUMN *p)
if (spaces_not_printed == 0)
{
output_position = p->start_position + end_vector[line];
}
return true;
-@@ -2646,7 +2852,7 @@ print_stored (COLUMN *p)
+@@ -2630,7 +2836,7 @@ print_stored (COLUMN *p)
number of characters is 1.) */
static int
{
unsigned char uc = c;
char *s = clump_buff;
-@@ -2656,10 +2862,10 @@ char_to_clump (char c)
+@@ -2640,10 +2846,10 @@ char_to_clump (char c)
int chars;
int chars_per_c = 8;
{
width = TAB_WIDTH (chars_per_c, input_position);
-@@ -2740,6 +2946,154 @@ char_to_clump (char c)
+@@ -2724,6 +2930,154 @@ char_to_clump (char c)
return chars;
}
/* We've just printed some files and need to clean up things before
looking for more options and printing the next batch of files.
-diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c
---- coreutils-8.19-orig/src/sort.c 2012-08-18 07:39:29.000000000 +0200
-+++ coreutils-8.19/src/sort.c 2012-08-20 13:52:04.079596072 +0200
+diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c
+--- coreutils-8.21-orig/src/sort.c 2013-01-31 01:46:24.000000000 +0100
++++ coreutils-8.21/src/sort.c 2013-02-15 14:25:07.828467769 +0100
@@ -29,6 +29,14 @@
#include <sys/wait.h>
#include <signal.h>
/* Flag to remove consecutive duplicate lines from the output.
Only the last of a sequence of equal lines will be output. */
-@@ -784,6 +812,46 @@ reap_all (void)
+@@ -783,6 +811,46 @@ reap_all (void)
reap (-1);
}
/* Clean up any remaining temporary files. */
static void
-@@ -1224,7 +1292,7 @@ zaptemp (char const *name)
+@@ -1223,7 +1291,7 @@ zaptemp (char const *name)
free (node);
}
static int
struct_month_cmp (void const *m1, void const *m2)
-@@ -1239,7 +1307,7 @@ struct_month_cmp (void const *m1, void c
+@@ -1238,7 +1306,7 @@ struct_month_cmp (void const *m1, void c
/* Initialize the character class tables. */
static void
{
size_t i;
-@@ -1251,7 +1319,7 @@ inittables (void)
+@@ -1250,7 +1318,7 @@ inittables (void)
fold_toupper[i] = toupper (i);
}
/* If we're not in the "C" locale, read different names for months. */
if (hard_LC_TIME)
{
-@@ -1333,6 +1401,84 @@ specify_nmerge (int oi, char c, char con
+@@ -1332,6 +1400,84 @@ specify_nmerge (int oi, char c, char con
xstrtol_fatal (e, oi, c, long_options, s);
}
/* Specify the amount of main memory to use when sorting. */
static void
specify_sort_size (int oi, char c, char const *s)
-@@ -1565,7 +1711,7 @@ buffer_linelim (struct buffer const *buf
+@@ -1564,7 +1710,7 @@ buffer_linelim (struct buffer const *buf
by KEY in LINE. */
static char *
{
char *ptr = line->text, *lim = ptr + line->length - 1;
size_t sword = key->sword;
-@@ -1574,10 +1720,10 @@ begfield (struct line const *line, struc
+@@ -1573,10 +1719,10 @@ begfield (struct line const *line, struc
/* The leading field separator itself is included in a field when -t
is absent. */
++ptr;
if (ptr < lim)
++ptr;
-@@ -1603,11 +1749,70 @@ begfield (struct line const *line, struc
+@@ -1602,11 +1748,70 @@ begfield (struct line const *line, struc
return ptr;
}
{
char *ptr = line->text, *lim = ptr + line->length - 1;
size_t eword = key->eword, echar = key->echar;
-@@ -1622,10 +1827,10 @@ limfield (struct line const *line, struc
+@@ -1621,10 +1826,10 @@ limfield (struct line const *line, struc
'beginning' is the first character following the delimiting TAB.
Otherwise, leave PTR pointing at the first 'blank' character after
the preceding field. */
++ptr;
if (ptr < lim && (eword || echar))
++ptr;
-@@ -1671,10 +1876,10 @@ limfield (struct line const *line, struc
+@@ -1670,10 +1875,10 @@ limfield (struct line const *line, struc
*/
/* Make LIM point to the end of (one byte past) the current field. */
if (newlim)
lim = newlim;
}
-@@ -1705,6 +1910,130 @@ limfield (struct line const *line, struc
+@@ -1704,6 +1909,130 @@ limfield (struct line const *line, struc
return ptr;
}
/* 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
-@@ -1791,8 +2120,22 @@ fillbuf (struct buffer *buf, FILE *fp, c
+@@ -1790,8 +2119,22 @@ fillbuf (struct buffer *buf, FILE *fp, c
else
{
if (key->skipsblanks)
line->keybeg = line_start;
}
}
-@@ -1913,7 +2256,7 @@ human_numcompare (char const *a, char co
+@@ -1912,7 +2255,7 @@ human_numcompare (char const *a, char co
hideously fast. */
static int
{
while (blanks[to_uchar (*a)])
a++;
-@@ -1923,6 +2266,25 @@ numcompare (char const *a, char const *b
+@@ -1922,6 +2265,25 @@ numcompare (char const *a, char const *b
return strnumcmp (a, b, decimal_point, thousands_sep);
}
/* 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 once
-@@ -1973,7 +2335,7 @@ general_numcompare (char const *sa, char
+@@ -1972,7 +2334,7 @@ general_numcompare (char const *sa, char
Return 0 if the name in S is not recognized. */
static int
{
size_t lo = 0;
size_t hi = MONTHS_PER_YEAR;
-@@ -2248,15 +2610,14 @@ debug_key (struct line const *line, stru
+@@ -2247,15 +2609,14 @@ debug_key (struct line const *line, stru
char saved = *lim;
*lim = '\0';
else if (key->general_numeric)
ignore_value (strtold (beg, &tighter_lim));
else if (key->numeric || key->human_numeric)
-@@ -2400,7 +2761,7 @@ key_warnings (struct keyfield const *gke
+@@ -2399,7 +2760,7 @@ key_warnings (struct keyfield const *gke
bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key)
&& !(key->schar || key->echar);
bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */
&& ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned))
|| (!key->skipsblanks && key->schar)
|| (!key->skipeblanks && key->echar)))
-@@ -2458,11 +2819,83 @@ key_warnings (struct keyfield const *gke
+@@ -2457,11 +2818,87 @@ key_warnings (struct keyfield const *gke
error (0, 0, _("option '-r' only applies to last-resort comparison"));
}
+ if (len == 0)
+ return 0;
+
-+ month = (char *) alloca (len + 1);
++ month = (char *) xmalloc (len + 1);
+
-+ tmp = (char *) alloca (len + 1);
++ tmp = (char *) xmalloc (len + 1);
+ memcpy (tmp, s, len);
+ tmp[len] = '\0';
+ pp = (const char **)&tmp;
-+ month_wcs = (wchar_t *) alloca ((len + 1) * sizeof (wchar_t));
++ month_wcs = (wchar_t *) xmalloc ((len + 1) * sizeof (wchar_t));
+ memset (&state, '\0', sizeof(mbstate_t));
+
+ wclength = mbsrtowcs (month_wcs, pp, len + 1, &state);
+ if (ea && result)
+ *ea = s + strlen (monthtab[lo].name);
+
++ free (month);
++ free (tmp);
++ free (month_wcs);
++
+ return result;
+}
+#endif
{
struct keyfield *key = keylist;
-@@ -2547,7 +2980,7 @@ keycompare (struct line const *a, struct
+@@ -2546,7 +2983,7 @@ keycompare (struct line const *a, struct
else if (key->human_numeric)
diff = human_numcompare (ta, tb);
else if (key->month)
else if (key->random)
diff = compare_random (ta, tlena, tb, tlenb);
else if (key->version)
-@@ -2663,6 +3096,180 @@ keycompare (struct line const *a, struct
+@@ -2662,6 +3099,181 @@ keycompare (struct line const *a, struct
return key->reverse ? -diff : diff;
}
+ {
+ if (ignore || translate)
+ {
-+ char *copy_a = (char *) alloca (lena + 1 + lenb + 1);
++ char *copy_a = (char *) xmalloc (lena + 1 + lenb + 1);
+ char *copy_b = copy_a + lena + 1;
+ size_t new_len_a, new_len_b;
+ size_t i, j;
+ IGNORE_CHARS (new_len_b, lenb, textb, copy_b,
+ wc_b, mblength_b, state_b);
+ diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b);
++ free(copy_a);
+ }
+ else if (lena == 0)
+ diff = - NONZERO (lenb);
/* Compare two lines A and B, returning negative, zero, or positive
depending on whether A compares less than, equal to, or greater than B. */
-@@ -4158,7 +4765,7 @@ main (int argc, char **argv)
+@@ -4157,7 +4769,7 @@ main (int argc, char **argv)
initialize_exit_failure (SORT_FAILURE);
hard_LC_COLLATE = hard_locale (LC_COLLATE);
hard_LC_TIME = hard_locale (LC_TIME);
#endif
-@@ -4179,6 +4786,29 @@ main (int argc, char **argv)
+@@ -4178,6 +4790,29 @@ main (int argc, char **argv)
thousands_sep = -1;
}
have_read_stdin = false;
inittables ();
-@@ -4453,13 +5083,34 @@ main (int argc, char **argv)
+@@ -4452,13 +5087,34 @@ main (int argc, char **argv)
case 't':
{
else
{
/* Provoke with 'sort -txx'. Complain about
-@@ -4470,9 +5121,12 @@ main (int argc, char **argv)
+@@ -4469,9 +5125,12 @@ main (int argc, char **argv)
quote (optarg));
}
}
}
break;
-diff -urNp coreutils-8.19-orig/src/unexpand.c coreutils-8.19/src/unexpand.c
---- coreutils-8.19-orig/src/unexpand.c 2012-07-21 16:54:31.000000000 +0200
-+++ coreutils-8.19/src/unexpand.c 2012-08-20 13:52:04.081596774 +0200
+diff -urNp coreutils-8.21-orig/src/unexpand.c coreutils-8.21/src/unexpand.c
+--- coreutils-8.21-orig/src/unexpand.c 2013-01-31 01:46:24.000000000 +0100
++++ coreutils-8.21/src/unexpand.c 2013-02-15 14:25:07.834467715 +0100
@@ -38,12 +38,29 @@
#include <stdio.h>
#include <getopt.h>
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "unexpand"
-@@ -103,6 +120,208 @@ static struct option const longopts[] =
+@@ -103,6 +120,210 @@ static struct option const longopts[] =
{NULL, 0, NULL, 0}
};
+ wint_t wc; /* A gotten wide character. */
+ size_t mblength; /* The byte size of a multibyte character
+ which shows as same character as WC. */
++ bool prev_tab = false;
+
+ /* Index in `tab_list' of next tabstop: */
+ int tab_index = 0; /* For calculating width of pending tabs. */
+flush_pend_mb:
+ /* Flush pending spaces. Print as many tabs as possible,
+ then print the rest as spaces. */
-+ if (pending == 1)
++ if (pending == 1 && column != 1 && !prev_tab)
+ {
+ putchar (' ');
+ pending = 0;
+ fwrite (bufpos, sizeof(char), mblength, stdout);
+ }
+ }
++ prev_tab = wc == L'\t';
+ buflen -= mblength;
+ bufpos += mblength;
+ }
void
usage (int status)
{
-@@ -524,7 +743,12 @@ main (int argc, char **argv)
+@@ -523,7 +742,12 @@ main (int argc, char **argv)
file_list = (optind < argc ? &argv[optind] : stdin_argv);
if (have_read_stdin && fclose (stdin) != 0)
error (EXIT_FAILURE, errno, "-");
-diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c
---- coreutils-8.19-orig/src/uniq.c 2012-07-21 16:54:31.000000000 +0200
-+++ coreutils-8.19/src/uniq.c 2012-08-20 13:52:04.083502506 +0200
+diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c
+--- coreutils-8.21-orig/src/uniq.c 2013-01-31 01:46:24.000000000 +0100
++++ coreutils-8.21/src/uniq.c 2013-02-15 14:25:07.839467991 +0100
@@ -21,6 +21,16 @@
#include <getopt.h>
#include <sys/types.h>
static struct option const longopts[] =
{
{"count", no_argument, NULL, 'c'},
-@@ -206,7 +232,7 @@ size_opt (char const *opt, char const *m
+@@ -205,7 +231,7 @@ size_opt (char const *opt, char const *m
return a pointer to the beginning of the line's field to be compared. */
static char * _GL_ATTRIBUTE_PURE
{
size_t count;
char const *lp = line->buffer;
-@@ -226,6 +252,83 @@ find_field (struct linebuffer const *lin
+@@ -225,6 +251,83 @@ find_field (struct linebuffer const *lin
return line->buffer + i;
}
/* 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.
-@@ -234,6 +337,8 @@ find_field (struct linebuffer const *lin
+@@ -233,6 +336,8 @@ find_field (struct linebuffer const *lin
static bool
different (char *old, char *new, size_t oldlen, size_t newlen)
{
if (check_chars < oldlen)
oldlen = check_chars;
if (check_chars < newlen)
-@@ -241,14 +346,92 @@ different (char *old, char *new, size_t
+@@ -240,14 +345,100 @@ different (char *old, char *new, size_t
if (ignore_case)
{
- return oldlen != newlen || memcasecmp (old, new, oldlen);
+ size_t i;
+
-+ copy_old = alloca (oldlen + 1);
-+ copy_new = alloca (oldlen + 1);
++ 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;
+ }
+
+ return xmemcoll (copy_old, oldlen, copy_new, newlen);
++
+}
+
+#if HAVE_MBRTOWC
+
+ for (i = 0; i < 2; i++)
+ {
-+ copy[i] = alloca (len[i] + 1);
++ copy[i] = xmalloc (len[i] + 1);
+
+ for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++)
+ {
+ 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;
+
-+ return xmemcoll (copy[0], len[0], copy[1], len[1]);
}
+#endif
/* Output the line in linebuffer LINE to standard output
provided that the switches say it should be output.
-@@ -304,15 +487,43 @@ check_file (const char *infile, const ch
+@@ -303,15 +494,43 @@ check_file (const char *infile, const ch
{
char *prevfield IF_LINT ( = NULL);
size_t prevlen IF_LINT ( = 0);
if (prevline->length == 0
|| different (thisfield, prevfield, thislen, prevlen))
{
-@@ -331,17 +542,26 @@ check_file (const char *infile, const ch
+@@ -330,17 +549,26 @@ check_file (const char *infile, const ch
size_t prevlen;
uintmax_t match_count = 0;
bool first_delimiter = true;
if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
{
if (ferror (stdin))
-@@ -350,6 +570,14 @@ check_file (const char *infile, const ch
+@@ -349,6 +577,14 @@ check_file (const char *infile, const ch
}
thisfield = find_field (thisline);
thislen = thisline->length - 1 - (thisfield - thisline->buffer);
match = !different (thisfield, prevfield, thislen, prevlen);
match_count += match;
-@@ -382,6 +610,9 @@ check_file (const char *infile, const ch
+@@ -381,6 +617,9 @@ check_file (const char *infile, const ch
SWAP_LINES (prevline, thisline);
prevfield = thisfield;
prevlen = thislen;
if (!match)
match_count = 0;
}
-@@ -427,6 +658,19 @@ main (int argc, char **argv)
+@@ -426,6 +665,19 @@ main (int argc, char **argv)
atexit (close_stdout);
skip_chars = 0;
skip_fields = 0;
check_chars = SIZE_MAX;
-diff -urNp coreutils-8.19-orig/tests/Makefile.am coreutils-8.19/tests/Makefile.am
---- coreutils-8.19-orig/tests/Makefile.am 2012-08-20 13:51:39.856841699 +0200
-+++ coreutils-8.19/tests/Makefile.am 2012-08-20 13:52:04.085491266 +0200
-@@ -247,6 +247,7 @@ TESTS = \
- misc/sort-debug-warn \
- misc/sort-discrim \
- misc/sort-files0-from \
-+ misc/sort-mb-tests \
- misc/sort-float \
- misc/sort-merge \
- misc/sort-merge-fdlimit \
-@@ -551,6 +552,10 @@ TESTS = \
- $(root_tests)
-
- pr_data = \
-+ misc/mb1.X \
-+ misc/mb1.I \
-+ misc/mb2.X \
-+ misc/mb2.I \
- pr/0F \
- pr/0FF \
- pr/0FFnt \
-diff -urNp coreutils-8.19-orig/tests/misc/cut coreutils-8.19/tests/misc/cut
---- coreutils-8.19-orig/tests/misc/cut 2012-07-21 16:54:31.000000000 +0200
-+++ coreutils-8.19/tests/misc/cut 2012-08-20 13:52:04.086593767 +0200
-@@ -23,14 +23,15 @@ use strict;
+diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk
+--- coreutils-8.21-orig/tests/local.mk 2013-02-15 14:24:32.645654553 +0100
++++ coreutils-8.21/tests/local.mk 2013-02-15 14:25:07.873467648 +0100
+@@ -325,6 +325,7 @@ all_tests = \
+ tests/misc/sort-discrim.sh \
+ tests/misc/sort-files0-from.pl \
+ tests/misc/sort-float.sh \
++ tests/misc/sort-mb-tests.sh \
+ tests/misc/sort-merge.pl \
+ tests/misc/sort-merge-fdlimit.sh \
+ tests/misc/sort-month.sh \
+diff -urNp coreutils-8.21-orig/tests/misc/cut.pl coreutils-8.21/tests/misc/cut.pl
+--- coreutils-8.21-orig/tests/misc/cut.pl 2013-02-05 00:40:31.000000000 +0100
++++ coreutils-8.21/tests/misc/cut.pl 2013-02-15 14:27:18.974468564 +0100
+@@ -23,9 +23,10 @@ use strict;
# Turn off localization of executable's output.
@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
my $prog = 'cut';
my $try = "Try '$prog --help' for more information.\n";
- my $from_1 = "$prog: fields and positions are numbered from 1\n$try";
--my $inval = "$prog: invalid byte or field list\n$try";
-+my $inval = "$prog: invalid byte, character or field list\n$try";
- my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try";
-
- my @Tests =
-@@ -147,7 +148,7 @@ my @Tests =
-
- # None of the following invalid ranges provoked an error up to coreutils-6.9.
- ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1},
-- {ERR=>"$prog: invalid decreasing range\n$try"}],
-+ {ERR=>"$prog: invalid byte, character or field list\n$try"}],
- ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
- ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
- ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1},
-diff -urNp coreutils-8.19-orig/tests/misc/expand coreutils-8.19/tests/misc/expand
---- coreutils-8.19-orig/tests/misc/expand 2012-07-21 16:54:31.000000000 +0200
-+++ coreutils-8.19/tests/misc/expand 2012-08-20 13:55:44.188467648 +0200
+diff -urNp coreutils-8.21-orig/tests/misc/expand.pl coreutils-8.21/tests/misc/expand.pl
+--- coreutils-8.21-orig/tests/misc/expand.pl 2013-01-31 01:46:24.000000000 +0100
++++ coreutils-8.21/tests/misc/expand.pl 2013-02-15 14:25:07.891468472 +0100
@@ -23,6 +23,15 @@ use strict;
# Turn off localization of executable's output.
@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
my $save_temps = $ENV{DEBUG};
my $verbose = $ENV{VERBOSE};
-diff -urNp coreutils-8.19-orig/tests/misc/mb1.I coreutils-8.19/tests/misc/mb1.I
---- coreutils-8.19-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.19/tests/misc/mb1.I 2012-08-20 13:52:04.086593767 +0200
+diff -urNp coreutils-8.21-orig/tests/misc/mb1.I coreutils-8.21/tests/misc/mb1.I
+--- coreutils-8.21-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100
++++ coreutils-8.21/tests/misc/mb1.I 2013-02-15 14:25:07.902467891 +0100
@@ -0,0 +1,4 @@
+Apple@10
+Banana@5
+Citrus@20
+Cherry@30
-diff -urNp coreutils-8.19-orig/tests/misc/mb1.X coreutils-8.19/tests/misc/mb1.X
---- coreutils-8.19-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.19/tests/misc/mb1.X 2012-08-20 13:52:04.087526516 +0200
+diff -urNp coreutils-8.21-orig/tests/misc/mb1.X coreutils-8.21/tests/misc/mb1.X
+--- coreutils-8.21-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100
++++ coreutils-8.21/tests/misc/mb1.X 2013-02-15 14:25:07.917467426 +0100
@@ -0,0 +1,4 @@
+Banana@5
+Apple@10
+Citrus@20
+Cherry@30
-diff -urNp coreutils-8.19-orig/tests/misc/mb2.I coreutils-8.19/tests/misc/mb2.I
---- coreutils-8.19-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.19/tests/misc/mb2.I 2012-08-20 13:52:04.088593815 +0200
+diff -urNp coreutils-8.21-orig/tests/misc/mb2.I coreutils-8.21/tests/misc/mb2.I
+--- coreutils-8.21-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100
++++ coreutils-8.21/tests/misc/mb2.I 2013-02-15 14:25:07.933467390 +0100
@@ -0,0 +1,4 @@
+Apple@AA10@@20
+Banana@AA5@@30
+Citrus@AA20@@5
+Cherry@AA30@@10
-diff -urNp coreutils-8.19-orig/tests/misc/mb2.X coreutils-8.19/tests/misc/mb2.X
---- coreutils-8.19-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.19/tests/misc/mb2.X 2012-08-20 13:52:04.088593815 +0200
+diff -urNp coreutils-8.21-orig/tests/misc/mb2.X coreutils-8.21/tests/misc/mb2.X
+--- coreutils-8.21-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100
++++ coreutils-8.21/tests/misc/mb2.X 2013-02-15 14:25:08.002467808 +0100
@@ -0,0 +1,4 @@
+Citrus@AA20@@5
+Cherry@AA30@@10
+Apple@AA10@@20
+Banana@AA5@@30
-diff -urNp coreutils-8.19-orig/tests/misc/sort-mb-tests coreutils-8.19/tests/misc/sort-mb-tests
---- coreutils-8.19-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.19/tests/misc/sort-mb-tests 2012-08-20 13:52:04.089593318 +0200
-@@ -0,0 +1,58 @@
-+#! /bin/sh
-+case $# in
-+ 0) xx='../src/sort';;
-+ *) xx="$1";;
-+esac
-+test "$VERBOSE" && echo=echo || echo=:
-+$echo testing program: $xx
-+errors=0
-+test "$srcdir" || srcdir=.
-+test "$VERBOSE" && $xx --version 2> /dev/null
+diff -urNp coreutils-8.21-orig/tests/misc/sort-mb-tests.sh coreutils-8.21/tests/misc/sort-mb-tests.sh
+--- coreutils-8.21-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100
++++ coreutils-8.21/tests/misc/sort-mb-tests.sh 2013-02-18 17:44:03.852275681 +0100
+@@ -0,0 +1,45 @@
++#!/bin/sh
++# Verify sort's multi-byte support.
++
++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
++print_ver_ sort
+
+export LC_ALL=en_US.UTF-8
-+locale -k LC_CTYPE 2>&1 | grep -q charmap.*UTF-8 || exit 77
-+errors=0
-+
-+$xx -t @ -k2 -n misc/mb1.I > misc/mb1.O
-+code=$?
-+if test $code != 0; then
-+ $echo "Test mb1 failed: $xx return code $code differs from expected value 0"
-+ errors=`expr $errors + 1`
-+else
-+ cmp misc/mb1.O $srcdir/misc/mb1.X > /dev/null 2>&1
-+ case $? in
-+ 0) if test "$VERBOSE"; then $echo "passed mb1"; fi;;
-+ 1) $echo "Test mb1 failed: files misc/mb1.O and $srcdir/misc/mb1.X differ" 1>&2
-+ (diff -c misc/mb1.O $srcdir/misc/mb1.X) 2> /dev/null
-+ errors=`expr $errors + 1`;;
-+ 2) $echo "Test mb1 may have failed." 1>&2
-+ $echo The command "cmp misc/mb1.O $srcdir/misc/mb1.X" failed. 1>&2
-+ errors=`expr $errors + 1`;;
-+ esac
-+fi
-+
-+$xx -t @ -k4 -n misc/mb2.I > misc/mb2.O
-+code=$?
-+if test $code != 0; then
-+ $echo "Test mb2 failed: $xx return code $code differs from expected value 0" 1>&2
-+ errors=`expr $errors + 1`
-+else
-+ cmp misc/mb2.O $srcdir/misc/mb2.X > /dev/null 2>&1
-+ case $? in
-+ 0) if test "$VERBOSE"; then $echo "passed mb2"; fi;;
-+ 1) $echo "Test mb2 failed: files misc/mb2.O and $srcdir/misc/mb2.X differ" 1>&2
-+ (diff -c misc/mb2.O $srcdir/misc/mb2.X) 2> /dev/null
-+ errors=`expr $errors + 1`;;
-+ 2) $echo "Test mb2 may have failed." 1>&2
-+ $echo The command "cmp misc/mb2.O $srcdir/misc/mb2.X" failed. 1>&2
-+ errors=`expr $errors + 1`;;
-+ esac
-+fi
-+
-+if test $errors = 0; then
-+ $echo Passed all 113 tests. 1>&2
-+else
-+ $echo Failed $errors tests. 1>&2
-+fi
-+test $errors = 0 || errors=1
-+exit $errors
++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \
++ || skip_ "No UTF-8 locale available"
++
++
++cat <<EOF > exp
++Banana@5
++Apple@10
++Citrus@20
++Cherry@30
++EOF
++
++cat <<EOF | sort -t @ -k2 -n > out || fail=1
++Apple@10
++Banana@5
++Citrus@20
++Cherry@30
++EOF
++
++compare exp out || { fail=1; cat out; }
++
++
++cat <<EOF > exp
++Citrus@AA20@@5
++Cherry@AA30@@10
++Apple@AA10@@20
++Banana@AA5@@30
++EOF
++
++cat <<EOF | sort -t @ -k4 -n > out || fail=1
++Apple@AA10@@20
++Banana@AA5@@30
++Citrus@AA20@@5
++Cherry@AA30@@10
++EOF
++
++compare exp out || { fail=1; cat out; }
++
++Exit $fail