]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
unexpand: fix misalignment when spaces span a tabstop
authorPádraig Brady <P@draigBrady.com>
Tue, 19 Jul 2011 08:06:37 +0000 (09:06 +0100)
committerPádraig Brady <P@draigBrady.com>
Wed, 20 Jul 2011 09:38:46 +0000 (10:38 +0100)
The following dropped the space from the first field
  printf "1234567  \t1\n" | unexpand -a
Note POSIX says that spaces should not precede tabs.
Also a single trailing space should not be converted
if the next field starts with non blank characters.
So we enforce those rules too, with this change.

* src/unexpand.c (unexpand): Implement as per POSIX rules.
* tests/misc/unexpand: Add tests, and adjust existing
tests as per POSIX rules.
* NEWS: Mention the fix.
Reported by Hallvard B Furuseth

NEWS
src/unexpand.c
tests/misc/unexpand

diff --git a/NEWS b/NEWS
index 61e6e63814bad4de38e6c69b151e4357082a2f6e..2952dc9a761592a65a11376d330191911969f531 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,11 @@ GNU coreutils NEWS                                    -*- outline -*-
   timeout is no longer confused when starting off with a child process.
   [bugs introduced in coreutils-7.0]
 
+  unexpand -a now aligns correctly when there are spaces spanning a tabstop,
+  followed by a tab.  In that case a space was dropped, causing misalignment.
+  We also now ensure that a space never precedes a tab.
+  [bug introduced in coreutils-5.3.0]
+
 ** Changes in behavior
 
   chmod, chown and chgrp now output the original attributes in messages,
index 001437504814238e619dd0281da57b9a5fdceb67..e8bf3f0b70265a96130c5f8056e7382db7e55478 100644 (file)
@@ -379,13 +379,8 @@ unexpand (void)
                         {
                           column = next_tab_column;
 
-                          /* Discard pending blanks, unless it was a single
-                             blank just before the previous tab stop.  */
-                          if (! (pending == 1 && one_blank_before_tab_stop))
-                            {
-                              pending = 0;
-                              one_blank_before_tab_stop = false;
-                            }
+                          if (pending)
+                            pending_blank[0] = '\t';
                         }
                       else
                         {
@@ -404,8 +399,11 @@ unexpand (void)
 
                           /* Replace the pending blanks by a tab or two.  */
                           pending_blank[0] = c = '\t';
-                          pending = one_blank_before_tab_stop;
                         }
+
+                      /* Discard pending blanks, unless it was a single
+                         blank just before the previous tab stop.  */
+                      pending = one_blank_before_tab_stop;
                     }
                 }
               else if (c == '\b')
@@ -425,6 +423,8 @@ unexpand (void)
 
               if (pending)
                 {
+                  if (pending > 1 && one_blank_before_tab_stop)
+                    pending_blank[0] = '\t';
                   if (fwrite (pending_blank, 1, pending, stdout) != pending)
                     error (EXIT_FAILURE, errno, _("write error"));
                   pending = 0;
index 81c3bcd85090e90d449c6062f853ede444f45bad..c56b059ac7069fa1037b5e65246d8df9245977f4 100755 (executable)
@@ -52,7 +52,7 @@ my @Tests =
 
      ['infloop-1', '-t', '1,2', {IN=> " \t\t .\n"}, {OUT=>"\t\t\t .\n"}],
      ['infloop-2', '-t', '4,5', {IN=> ' 'x4 . "\t\t \n"}, {OUT=>"\t\t\t \n"}],
-     ['infloop-3', '-t', '2,3', {IN=> "x \t\t \n"}, {OUT=>"x \t\t \n"}],
+     ['infloop-3', '-t', '2,3', {IN=> "x \t\t \n"}, {OUT=>"x\t\t\t \n"}],
      ['infloop-4', '-t', '1,2', {IN=> " \t\t   \n"}, {OUT=>"\t\t\t   \n"}],
      ['c-1', '-t', '1,2', {IN=> "x\t\t .\n"}, {OUT=>"x\t\t .\n"}],
 
@@ -70,12 +70,22 @@ my @Tests =
      ['blanks-6', qw(-t 1), {IN=> "a  "}, {OUT=> "a\t\t"}],
      ['blanks-7', qw(-t 1), {IN=> "a   "}, {OUT=> "a\t\t\t"}],
      ['blanks-8', qw(-t 1), {IN=> " a a  a\n"}, {OUT=> "\ta a\t\ta\n"}],
-     ['blanks-9', qw(-t 2), {IN=> "   a  a  a\n"}, {OUT=> "\t a\ta  a\n"}],
+     ['blanks-9', qw(-t 2), {IN=> "   a  a  a\n"}, {OUT=> "\t a\ta\t a\n"}],
      ['blanks-10', '-t', '3,4', {IN=> "0 2 4 6\t8\n"}, {OUT=> "0 2 4 6\t8\n"}],
      ['blanks-11', '-t', '3,4', {IN=> "    4\n"}, {OUT=> "\t\t4\n"}],
      ['blanks-12', '-t', '3,4', {IN=> "01  4\n"}, {OUT=> "01\t\t4\n"}],
      ['blanks-13', '-t', '3,4', {IN=> "0   4\n"}, {OUT=> "0\t\t4\n"}],
 
+     # POSIX says spaces should only follow tabs. Also a single
+     # trailing space is not converted to a tab, when before
+     # a field starting with non blanks
+     ['posix-1', '-a', {IN=> "1234567   \t1\n"}, {OUT=>"1234567\t\t1\n"}],
+     ['posix-2', '-a', {IN=> "1234567  \t1\n"},  {OUT=>"1234567\t\t1\n"}],
+     ['posix-3', '-a', {IN=> "1234567 \t1\n"},   {OUT=>"1234567\t\t1\n"}],
+     ['posix-4', '-a', {IN=> "1234567\t1\n"},    {OUT=>"1234567\t1\n"}],
+     ['posix-5', '-a', {IN=> "1234567  1\n"},    {OUT=>"1234567\t 1\n"}],
+     ['posix-6', '-a', {IN=> "1234567 1\n"},     {OUT=>"1234567 1\n"}],
+
      # It is debatable whether this test should require an environment
      # setting of e.g., _POSIX2_VERSION=1.
      ['obs-ovflo', "-$limits->{UINTMAX_OFLOW}", {IN=>''}, {OUT=>''},