diff --git a/coreutils/expand.c b/coreutils/expand.c index 3ca7e5c29..0967e2534 100644 --- a/coreutils/expand.c +++ b/coreutils/expand.c @@ -68,51 +68,39 @@ static void expand(FILE *file, int tab_size, unsigned opt) static void unexpand(FILE *file, unsigned tab_size, unsigned opt) { char *line; - char *ptr; - int convert; - int pos; - int i = 0; - unsigned column = 0; while ((line = xmalloc_fgets(file)) != NULL) { - convert = 1; - pos = 0; - ptr = line; - while (*line) { - while ((*line == ' ' || *line == '\t') && convert) { - pos += (*line == ' ') ? 1 : tab_size; - line++; + char *ptr = line; + unsigned column = 0; + + while (*ptr) { + unsigned n; + + while (*ptr == ' ') { column++; - if ((opt & OPT_ALL) && column == tab_size) { - column = 0; - goto put_tab; - } + ptr++; } - if (pos) { - i = pos / tab_size; - if (i) { - for (; i > 0; i--) { - put_tab: - bb_putchar('\t'); - } - } else { - for (i = pos % tab_size; i > 0; i--) { - bb_putchar(' '); - } - } - pos = 0; - } else { - if (opt & OPT_INITIAL) { - convert = 0; - } - if (opt & OPT_ALL) { - column++; - } - bb_putchar(*line); - line++; + if (*ptr == '\t') { + column += tab_size - (column % tab_size); + ptr++; + continue; } + + n = column / tab_size; + column = column % tab_size; + while (n--) + putchar('\t'); + + if ((opt & OPT_INITIAL) && ptr != line) { + printf("%*s%s", column, "", ptr); + break; + } + n = strcspn(ptr, "\t "); + printf("%*s%.*s", column, "", n, ptr); + ptr += n; + column = (column + n) % tab_size; } - free(ptr); + free(line); } } #endif diff --git a/testsuite/unexpand.tests b/testsuite/unexpand.tests new file mode 100755 index 000000000..e7f42c5fd --- /dev/null +++ b/testsuite/unexpand.tests @@ -0,0 +1,30 @@ +#!/bin/sh +# Copyright 2008 by Denys Vlasenko +# Licensed under GPL v2, see file LICENSE for details. + +. testing.sh + +# testing "test name" "options" "expected result" "file input" "stdin" + +testing "unexpand case 1" "unexpand" \ + "\t12345678\n" "" " 12345678\n" \ + +testing "unexpand case 2" "unexpand" \ + "\t 12345678\n" "" " 12345678\n" \ + +testing "unexpand case 3" "unexpand" \ + "\t 12345678\n" "" " 12345678\n" \ + +testing "unexpand case 4" "unexpand" \ + "\t12345678\n" "" " \t12345678\n" \ + +testing "unexpand case 5" "unexpand" \ + "\t12345678\n" "" " \t12345678\n" \ + +testing "unexpand case 6" "unexpand" \ + "\t12345678\n" "" " \t12345678\n" \ + +testing "unexpand case 7" "unexpand" \ + "123\t 45678\n" "" "123 \t 45678\n" \ + +exit $FAILCOUNT