Refactor catv. Move visible() from stty to libbb.
No binary (build failed)
—
(log yok)
| @@ -128,10 +128,6 @@ patch | |
| And while we're at it, a new patch filename quoting format is apparently | |
| coming soon: http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2 | |
| --- | |
| - | stty / catv |
| - | stty's visible() function and catv's guts are identical. Merge them into |
| - | an appropriate libbb function. |
| - | --- |
| tail | |
| ./busybox tail -f foo.c~ TODO | |
| should not print fmt=header_fmt for subsequent date >> TODO; i.e. only | |
| @@ -25,14 +25,20 @@ int catv_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| int retval = EXIT_SUCCESS; | |
| int fd; | |
| - | unsigned flags; |
| + | unsigned opts; |
| + | int flags = 0; |
| - | flags = getopt32(argv, "etv"); |
| + | opts = getopt32(argv, "etv"); |
| #define CATV_OPT_e (1<<0) | |
| #define CATV_OPT_t (1<<1) | |
| #define CATV_OPT_v (1<<2) | |
| - | flags ^= CATV_OPT_v; |
| argv += optind; | |
| + | if (opts & (CATV_OPT_e | CATV_OPT_t)) |
| + | opts &= ~CATV_OPT_v; |
| + | if (opts & CATV_OPT_e) |
| + | flags |= VISIBLE_ENDLINE; |
| + | if (opts & CATV_OPT_t) |
| + | flags |= VISIBLE_SHOW_TABS; |
| /* Read from stdin if there's nothing else to do. */ | |
| if (!argv[0]) | |
| @@ -50,29 +56,17 @@ int catv_main(int argc UNUSED_PARAM, char **argv) | |
| res = read(fd, read_buf, COMMON_BUFSIZE); | |
| if (res < 0) | |
| retval = EXIT_FAILURE; | |
| - | if (res < 1) |
| + | if (res <= 0) |
| break; | |
| for (i = 0; i < res; i++) { | |
| unsigned char c = read_buf[i]; | |
| - | |
| - | if (c > 126 && (flags & CATV_OPT_v)) { |
| - | if (c == 127) { |
| - | printf("^?"); |
| - | continue; |
| - | } |
| - | printf("M-"); |
| - | c -= 128; |
| - | } |
| - | if (c < 32) { |
| - | if (c == 10) { |
| - | if (flags & CATV_OPT_e) |
| - | bb_putchar('$'); |
| - | } else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) { |
| - | printf("^%c", c+'@'); |
| - | continue; |
| - | } |
| + | if (opts & CATV_OPT_v) { |
| + | putchar(c); |
| + | } else { |
| + | char buf[sizeof("M-^c")]; |
| + | visible(c, buf, flags); |
| + | fputs(buf, stdout); |
| } | |
| - | bb_putchar(c); |
| } | |
| } | |
| if (ENABLE_FEATURE_CLEAN_UP && fd) | |
| @@ -781,36 +781,6 @@ struct globals { | |
| G.max_col = 80; \ | |
| } while (0) | |
| - | |
| - | /* Return a string that is the printable representation of character CH */ |
| - | /* Adapted from 'cat' by Torbjorn Granlund */ |
| - | static const char *visible(unsigned ch) |
| - | { |
| - | char *bpout = G.buf; |
| - | |
| - | if (ch == _POSIX_VDISABLE) |
| - | return "<undef>"; |
| - | |
| - | if (ch >= 128) { |
| - | ch -= 128; |
| - | *bpout++ = 'M'; |
| - | *bpout++ = '-'; |
| - | } |
| - | |
| - | if (ch < 32) { |
| - | *bpout++ = '^'; |
| - | *bpout++ = ch + 64; |
| - | } else if (ch < 127) { |
| - | *bpout++ = ch; |
| - | } else { |
| - | *bpout++ = '^'; |
| - | *bpout++ = '?'; |
| - | } |
| - | |
| - | *bpout = '\0'; |
| - | return G.buf; |
| - | } |
| - | |
| static void set_speed_or_die(enum speed_setting type, const char *arg, | |
| struct termios *mode) | |
| { | |
| @@ -1038,6 +1008,7 @@ static void do_display(const struct termios *mode, int all) | |
| #endif | |
| for (i = 0; i != CIDX_min; ++i) { | |
| + | char ch; |
| /* If swtch is the same as susp, don't print both */ | |
| #if VSWTCH == VSUSP | |
| if (i == CIDX_swtch) | |
| @@ -1051,8 +1022,12 @@ static void do_display(const struct termios *mode, int all) | |
| continue; | |
| } | |
| #endif | |
| - | wrapf("%s = %s;", nth_string(control_name, i), |
| - | visible(mode->c_cc[control_info[i].offset])); |
| + | ch = mode->c_cc[control_info[i].offset]; |
| + | if (ch == _POSIX_VDISABLE) |
| + | strcpy(G.buf, "<undef>"); |
| + | else |
| + | visible(ch, G.buf, 0); |
| + | wrapf("%s = %s;", nth_string(control_name, i), G.buf); |
| } | |
| #if VEOF == VMIN | |
| if ((mode->c_lflag & ICANON) == 0) | |
| @@ -678,6 +678,10 @@ const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str); | |
| * else it is printed as-is (except for ch = 0x9b) */ | |
| enum { PRINTABLE_META = 0x100 }; | |
| void fputc_printable(int ch, FILE *file) FAST_FUNC; | |
| + | /* Return a string that is the printable representation of character ch. |
| + | * Buffer must hold at least four characters. */ |
| + | enum { VISIBLE_SHOW_TABS = 1, VISIBLE_ENDLINE = 2 }; |
| + | void visible(unsigned ch, char *buf, int flags) FAST_FUNC; |
| /* dmalloc will redefine these to it's own implementation. It is safe | |
| * to have the prototypes here unconditionally. */ | |
| @@ -32,3 +32,27 @@ void FAST_FUNC fputc_printable(int ch, FILE *file) | |
| } | |
| fputc(ch, file); | |
| } | |
| + | |
| + | void FAST_FUNC visible(unsigned ch, char *buf, int flags) |
| + | { |
| + | if (ch == '\t' && !(flags & VISIBLE_SHOW_TABS)) { |
| + | goto raw; |
| + | } |
| + | if (ch == '\n') { |
| + | if (flags & VISIBLE_ENDLINE) |
| + | *buf++ = '$'; |
| + | } else { |
| + | if (ch >= 128) { |
| + | ch -= 128; |
| + | *buf++ = 'M'; |
| + | *buf++ = '-'; |
| + | } |
| + | if (ch < 32 || ch == 127) { |
| + | *buf++ = '^'; |
| + | ch ^= 0x40; |
| + | } |
| + | } |
| + | raw: |
| + | *buf++ = ch; |
| + | *buf = '\0'; |
| + | } |