aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartosz Golaszewski <bartekgola@gmail.com>2013-07-30 06:29:42 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2013-07-30 06:29:42 +0200
commit79c618c41193eaaa092cb977f06fc112155ba92b (patch)
tree369938db46d4691ebbcc476386c7dafdac827887
parentd0bc708cb52693b9ed1dab495e5f99fb8e1122f7 (diff)
downloadbusybox-w32-79c618c41193eaaa092cb977f06fc112155ba92b.tar.gz
busybox-w32-79c618c41193eaaa092cb977f06fc112155ba92b.tar.bz2
busybox-w32-79c618c41193eaaa092cb977f06fc112155ba92b.zip
Refactor catv. Move visible() from stty to libbb.
Fixes the following TODO: stty's visible() function and catv's guts are identical. Merge them into an appropriate libbb function. Also makes catv behave exactly like coreutils' cat -v e.g. it'll print 'M-^I' instead of 'M- '. function old new delta visible - 70 +70 do_display 431 379 -52 catv_main 306 250 -56 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 0/2 up/down: 70/-108) Total: -38 bytes Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--TODO4
-rw-r--r--coreutils/catv.c38
-rw-r--r--coreutils/stty.c39
-rw-r--r--include/libbb.h4
-rw-r--r--libbb/printable.c24
5 files changed, 51 insertions, 58 deletions
diff --git a/TODO b/TODO
index 8d0850cd7..d2a085ede 100644
--- a/TODO
+++ b/TODO
@@ -128,10 +128,6 @@ patch
128 And while we're at it, a new patch filename quoting format is apparently 128 And while we're at it, a new patch filename quoting format is apparently
129 coming soon: http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2 129 coming soon: http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2
130--- 130---
131stty / catv
132 stty's visible() function and catv's guts are identical. Merge them into
133 an appropriate libbb function.
134---
135tail 131tail
136 ./busybox tail -f foo.c~ TODO 132 ./busybox tail -f foo.c~ TODO
137 should not print fmt=header_fmt for subsequent date >> TODO; i.e. only 133 should not print fmt=header_fmt for subsequent date >> TODO; i.e. only
diff --git a/coreutils/catv.c b/coreutils/catv.c
index 214b4311a..18b18104e 100644
--- a/coreutils/catv.c
+++ b/coreutils/catv.c
@@ -25,14 +25,20 @@ int catv_main(int argc UNUSED_PARAM, char **argv)
25{ 25{
26 int retval = EXIT_SUCCESS; 26 int retval = EXIT_SUCCESS;
27 int fd; 27 int fd;
28 unsigned flags; 28 unsigned opts;
29 int flags = 0;
29 30
30 flags = getopt32(argv, "etv"); 31 opts = getopt32(argv, "etv");
31#define CATV_OPT_e (1<<0) 32#define CATV_OPT_e (1<<0)
32#define CATV_OPT_t (1<<1) 33#define CATV_OPT_t (1<<1)
33#define CATV_OPT_v (1<<2) 34#define CATV_OPT_v (1<<2)
34 flags ^= CATV_OPT_v;
35 argv += optind; 35 argv += optind;
36 if (opts & (CATV_OPT_e | CATV_OPT_t))
37 opts &= ~CATV_OPT_v;
38 if (opts & CATV_OPT_e)
39 flags |= VISIBLE_ENDLINE;
40 if (opts & CATV_OPT_t)
41 flags |= VISIBLE_SHOW_TABS;
36 42
37 /* Read from stdin if there's nothing else to do. */ 43 /* Read from stdin if there's nothing else to do. */
38 if (!argv[0]) 44 if (!argv[0])
@@ -50,29 +56,17 @@ int catv_main(int argc UNUSED_PARAM, char **argv)
50 res = read(fd, read_buf, COMMON_BUFSIZE); 56 res = read(fd, read_buf, COMMON_BUFSIZE);
51 if (res < 0) 57 if (res < 0)
52 retval = EXIT_FAILURE; 58 retval = EXIT_FAILURE;
53 if (res < 1) 59 if (res <= 0)
54 break; 60 break;
55 for (i = 0; i < res; i++) { 61 for (i = 0; i < res; i++) {
56 unsigned char c = read_buf[i]; 62 unsigned char c = read_buf[i];
57 63 if (opts & CATV_OPT_v) {
58 if (c > 126 && (flags & CATV_OPT_v)) { 64 putchar(c);
59 if (c == 127) { 65 } else {
60 printf("^?"); 66 char buf[sizeof("M-^c")];
61 continue; 67 visible(c, buf, flags);
62 } 68 fputs(buf, stdout);
63 printf("M-");
64 c -= 128;
65 }
66 if (c < 32) {
67 if (c == 10) {
68 if (flags & CATV_OPT_e)
69 bb_putchar('$');
70 } else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) {
71 printf("^%c", c+'@');
72 continue;
73 }
74 } 69 }
75 bb_putchar(c);
76 } 70 }
77 } 71 }
78 if (ENABLE_FEATURE_CLEAN_UP && fd) 72 if (ENABLE_FEATURE_CLEAN_UP && fd)
diff --git a/coreutils/stty.c b/coreutils/stty.c
index d1e74f437..378a848e7 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -781,36 +781,6 @@ struct globals {
781 G.max_col = 80; \ 781 G.max_col = 80; \
782} while (0) 782} while (0)
783 783
784
785/* Return a string that is the printable representation of character CH */
786/* Adapted from 'cat' by Torbjorn Granlund */
787static const char *visible(unsigned ch)
788{
789 char *bpout = G.buf;
790
791 if (ch == _POSIX_VDISABLE)
792 return "<undef>";
793
794 if (ch >= 128) {
795 ch -= 128;
796 *bpout++ = 'M';
797 *bpout++ = '-';
798 }
799
800 if (ch < 32) {
801 *bpout++ = '^';
802 *bpout++ = ch + 64;
803 } else if (ch < 127) {
804 *bpout++ = ch;
805 } else {
806 *bpout++ = '^';
807 *bpout++ = '?';
808 }
809
810 *bpout = '\0';
811 return G.buf;
812}
813
814static void set_speed_or_die(enum speed_setting type, const char *arg, 784static void set_speed_or_die(enum speed_setting type, const char *arg,
815 struct termios *mode) 785 struct termios *mode)
816{ 786{
@@ -1038,6 +1008,7 @@ static void do_display(const struct termios *mode, int all)
1038#endif 1008#endif
1039 1009
1040 for (i = 0; i != CIDX_min; ++i) { 1010 for (i = 0; i != CIDX_min; ++i) {
1011 char ch;
1041 /* If swtch is the same as susp, don't print both */ 1012 /* If swtch is the same as susp, don't print both */
1042#if VSWTCH == VSUSP 1013#if VSWTCH == VSUSP
1043 if (i == CIDX_swtch) 1014 if (i == CIDX_swtch)
@@ -1051,8 +1022,12 @@ static void do_display(const struct termios *mode, int all)
1051 continue; 1022 continue;
1052 } 1023 }
1053#endif 1024#endif
1054 wrapf("%s = %s;", nth_string(control_name, i), 1025 ch = mode->c_cc[control_info[i].offset];
1055 visible(mode->c_cc[control_info[i].offset])); 1026 if (ch == _POSIX_VDISABLE)
1027 strcpy(G.buf, "<undef>");
1028 else
1029 visible(ch, G.buf, 0);
1030 wrapf("%s = %s;", nth_string(control_name, i), G.buf);
1056 } 1031 }
1057#if VEOF == VMIN 1032#if VEOF == VMIN
1058 if ((mode->c_lflag & ICANON) == 0) 1033 if ((mode->c_lflag & ICANON) == 0)
diff --git a/include/libbb.h b/include/libbb.h
index 83e9b5fb9..0c3734cdb 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -678,6 +678,10 @@ const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str);
678 * else it is printed as-is (except for ch = 0x9b) */ 678 * else it is printed as-is (except for ch = 0x9b) */
679enum { PRINTABLE_META = 0x100 }; 679enum { PRINTABLE_META = 0x100 };
680void fputc_printable(int ch, FILE *file) FAST_FUNC; 680void fputc_printable(int ch, FILE *file) FAST_FUNC;
681/* Return a string that is the printable representation of character ch.
682 * Buffer must hold at least four characters. */
683enum { VISIBLE_SHOW_TABS = 1, VISIBLE_ENDLINE = 2 };
684void visible(unsigned ch, char *buf, int flags) FAST_FUNC;
681 685
682/* dmalloc will redefine these to it's own implementation. It is safe 686/* dmalloc will redefine these to it's own implementation. It is safe
683 * to have the prototypes here unconditionally. */ 687 * to have the prototypes here unconditionally. */
diff --git a/libbb/printable.c b/libbb/printable.c
index f6ada4904..9a423431e 100644
--- a/libbb/printable.c
+++ b/libbb/printable.c
@@ -32,3 +32,27 @@ void FAST_FUNC fputc_printable(int ch, FILE *file)
32 } 32 }
33 fputc(ch, file); 33 fputc(ch, file);
34} 34}
35
36void FAST_FUNC visible(unsigned ch, char *buf, int flags)
37{
38 if (ch == '\t' && !(flags & VISIBLE_SHOW_TABS)) {
39 goto raw;
40 }
41 if (ch == '\n') {
42 if (flags & VISIBLE_ENDLINE)
43 *buf++ = '$';
44 } else {
45 if (ch >= 128) {
46 ch -= 128;
47 *buf++ = 'M';
48 *buf++ = '-';
49 }
50 if (ch < 32 || ch == 127) {
51 *buf++ = '^';
52 ch ^= 0x40;
53 }
54 }
55 raw:
56 *buf++ = ch;
57 *buf = '\0';
58}