aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-12-14 15:45:25 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-12-14 15:45:25 +0000
commit3139ea7f1567723e200d29e46e78953ea5fe4d5b (patch)
tree2ceaaa2b1b636c348140c42ab1c5beb2f44ad089
parent005ff882ba2760f5e85a521ed41360f58163f14c (diff)
downloadbusybox-w32-3139ea7f1567723e200d29e46e78953ea5fe4d5b.tar.gz
busybox-w32-3139ea7f1567723e200d29e46e78953ea5fe4d5b.tar.bz2
busybox-w32-3139ea7f1567723e200d29e46e78953ea5fe4d5b.zip
expand: fix incorrect expansion exactly on tab boundary; shrink the code
function old new delta expand_main 698 676 -22 xputchar 53 - -53
-rw-r--r--coreutils/expand.c60
-rwxr-xr-xtestsuite/expand.tests15
2 files changed, 41 insertions, 34 deletions
diff --git a/coreutils/expand.c b/coreutils/expand.c
index ee51c032f..3ca7e5c29 100644
--- a/coreutils/expand.c
+++ b/coreutils/expand.c
@@ -29,51 +29,43 @@ enum {
29 OPT_ALL = 1 << 2, 29 OPT_ALL = 1 << 2,
30}; 30};
31 31
32static void xputchar(char c)
33{
34 if (putchar(c) < 0)
35 bb_error_msg_and_die(bb_msg_write_error);
36}
37
38#if ENABLE_EXPAND 32#if ENABLE_EXPAND
39static void expand(FILE *file, unsigned tab_size, unsigned opt) 33static void expand(FILE *file, int tab_size, unsigned opt)
40{ 34{
41 char *line; 35 char *line;
42 char *ptr;
43 int convert;
44 unsigned pos;
45 36
46 /* Increment tab_size by 1 locally.*/ 37 tab_size = -tab_size;
47 tab_size++;
48 38
49 while ((line = xmalloc_fgets(file)) != NULL) { 39 while ((line = xmalloc_fgets(file)) != NULL) {
50 convert = 1; 40 int pos;
51 pos = 0; 41 unsigned char c;
52 ptr = line; 42 char *ptr = line;
53 while (*line) { 43
54 pos++; 44 goto start;
55 if (*line == '\t' && convert) { 45 while ((c = *ptr) != '\0') {
56 for (; pos < tab_size; pos++) { 46 if ((opt & OPT_INITIAL) && !isblank(c)) {
57 xputchar(' '); 47 fputs(ptr, stdout);
58 } 48 break;
59 } else {
60 if ((opt & OPT_INITIAL) && !isblank(*line)) {
61 convert = 0;
62 }
63 xputchar(*line);
64 } 49 }
65 if (pos == tab_size) { 50 ptr++;
66 pos = 0; 51 if (c == '\t') {
52 c = ' ';
53 while (++pos < 0)
54 bb_putchar(c);
55 }
56 bb_putchar(c);
57 if (++pos >= 0) {
58 start:
59 pos = tab_size;
67 } 60 }
68 line++;
69 } 61 }
70 free(ptr); 62 free(line);
71 } 63 }
72} 64}
73#endif 65#endif
74 66
75#if ENABLE_UNEXPAND 67#if ENABLE_UNEXPAND
76static void unexpand(FILE *file, unsigned int tab_size, unsigned opt) 68static void unexpand(FILE *file, unsigned tab_size, unsigned opt)
77{ 69{
78 char *line; 70 char *line;
79 char *ptr; 71 char *ptr;
@@ -101,11 +93,11 @@ static void unexpand(FILE *file, unsigned int tab_size, unsigned opt)
101 if (i) { 93 if (i) {
102 for (; i > 0; i--) { 94 for (; i > 0; i--) {
103 put_tab: 95 put_tab:
104 xputchar('\t'); 96 bb_putchar('\t');
105 } 97 }
106 } else { 98 } else {
107 for (i = pos % tab_size; i > 0; i--) { 99 for (i = pos % tab_size; i > 0; i--) {
108 xputchar(' '); 100 bb_putchar(' ');
109 } 101 }
110 } 102 }
111 pos = 0; 103 pos = 0;
@@ -116,7 +108,7 @@ static void unexpand(FILE *file, unsigned int tab_size, unsigned opt)
116 if (opt & OPT_ALL) { 108 if (opt & OPT_ALL) {
117 column++; 109 column++;
118 } 110 }
119 xputchar(*line); 111 bb_putchar(*line);
120 line++; 112 line++;
121 } 113 }
122 } 114 }
diff --git a/testsuite/expand.tests b/testsuite/expand.tests
new file mode 100755
index 000000000..3f4cda3f8
--- /dev/null
+++ b/testsuite/expand.tests
@@ -0,0 +1,15 @@
1#!/bin/sh
2# Copyright 2008 by Denys Vlasenko
3# Licensed under GPL v2, see file LICENSE for details.
4
5. testing.sh
6
7# testing "test name" "options" "expected result" "file input" "stdin"
8
9testing "expand" \
10 "expand" \
11 " 12345678 12345678\n" \
12 "" \
13 "\t12345678\t12345678\n" \
14
15exit $FAILCOUNT