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
{
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])
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)
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)
{
#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)
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)
* 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. */
}
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';
+}