Index: src/cut.c
===================================================================
--- src/cut.c.orig	2011-09-02 15:47:25.000000000 +0200
+++ src/cut.c	2011-09-02 15:49:06.825116999 +0200
@@ -676,15 +676,19 @@ cut_bytes (FILE *stream)
 static void
 cut_characters_or_cut_bytes_no_split (FILE *stream)
 {
-  int 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. */
-  int convfail;                /* 1, when conversion is failed. Otherwise 0. */
+  int 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. */
+  int convfail;				/* 1, when conversion is failed. Otherwise 0. */
+
+  /* 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;
 
   idx = 0;
   buflen = 0;
@@ -707,12 +711,23 @@ cut_characters_or_cut_bytes_no_split (FI
         {
           putchar ('\n');
           idx = 0;
+          print_delimiter = false;
         }
       else
         {
+          bool range_start;
+          bool *rs = output_delimiter_specified ? &range_start : NULL;
           idx += (operating_mode == byte_mode) ? mblength : 1;
-          if (print_kth (idx, NULL))
-            fwrite (bufpos, mblength, sizeof(char), stdout);
+          if (print_kth (idx, rs))
+            {
+              fwrite (bufpos, mblength, sizeof(char), stdout);
+
+              if (rs && *rs && print_delimiter)
+                {
+                  fwrite (output_delimiter_string, sizeof (char),
+				          output_delimiter_length, stdout);
+				}
+            }
         }
 
       buflen -= mblength;

From: Jim Meyering <meyering@redhat.com>
Date: Thu, 1 Sep 2011 21:30:10 +0200
Subject: [PATCH] tests: exercise distro-added multibyte code paths in cut

* tests/misc/cut: Repeat each test using a multibyte locale,
if the configure-time test found such a locale.
Adjust the tests so that they also accept a slightly
different diagnostic that is specific to the MB-patched cut.
---
 tests/misc/cut |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

--- tests/misc/cut
+++ tests/misc/cut
@@ -23,6 +23,10 @@ use strict;
 # Turn off localization of executable's output.
 @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;

+my $mb_locale = $ENV{LOCALE_FR_UTF8};
+! defined $mb_locale || $mb_locale eq 'none'
+  and $mb_locale = 'C';
+
 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";
@@ -156,6 +160,35 @@ my @Tests =
   ['big-unbounded-f', '--output-d=:', '-f1234567890-', {IN=>''}, {OUT=>''}],
  );

+if ($mb_locale ne 'C')
+  {
+    # Duplicate each test vector, appending "-mb" to the test name and
+    # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
+    # provide coverage for the distro-added multi-byte code paths.
+    my @new;
+    foreach my $t (@Tests)
+      {
+        my @new_t = @$t;
+        my $test_name = shift @new_t;
+
+        # Depending on whether cut is multi-byte-patched,
+        # it emits different diagnostics:
+        #   non-MB: invalid byte or field list
+        #   MB:     invalid byte, character or field list
+        # Adjust the expected error output accordingly.
+        if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
+            (@new_t))
+          {
+            my $sub = {ERR_SUBST => 's/, character//'};
+            push @new_t, $sub;
+            push @$t, $sub;
+          }
+        push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
+      }
+    push @Tests, @new;
+  }
+
+
 @Tests = triple_test \@Tests;

 my $save_temps = $ENV{DEBUG};
