diff options
Diffstat (limited to 'toys/posix/cat.c')
-rw-r--r-- | toys/posix/cat.c | 85 |
1 files changed, 79 insertions, 6 deletions
diff --git a/toys/posix/cat.c b/toys/posix/cat.c index 3644c4f9..5b4ab71a 100644 --- a/toys/posix/cat.c +++ b/toys/posix/cat.c @@ -3,8 +3,12 @@ * Copyright 2006 Rob Landley <rob@landley.net> * * See http://opengroup.org/onlinepubs/9699919799/utilities/cat.html + * + * And "Cat -v considered harmful" at + * http://cm.bell-labs.com/cm/cs/doc/84/kp.ps.gz -USE_CAT(NEWTOY(cat, "u", TOYFLAG_BIN)) +USE_CAT(NEWTOY(cat, "u"USE_CAT_V("vte"), TOYFLAG_BIN)) +#USE_CATV(NEWTOY(catv, USE_CATV("vte"), TOYFLAG_USR|TOYFLAG_BIN)) config CAT bool "cat" @@ -16,19 +20,76 @@ config CAT Filename "-" is a synonym for stdin. -u Copy one byte at a time (slow). + +config CAT_V + bool "cat -etv" + default y + depends on CAT + help + usage: cat [-evt] + + Display nonprinting characters as escape sequences. Use M-x for + + -e Mark each newline with $ + -t Show tabs as ^I + -v Display nonprinting characters as escape sequences. Use M-x for + high ascii characters (>127), and ^x for other nonprinting chars. +*/ + +/* +todo: + +config CATV + bool "catv" + default y + depends on !CAT_V + help + usage: catv [-evt] [filename...] + + Display nonprinting characters as escape sequences. Use M-x for + high ascii characters (>127), and ^x for other nonprinting chars. + + -e Mark each newline with $ + -t Show tabs as ^I + -v Don't use ^x or M-x escapes. */ +#define FOR_cat #include "toys.h" static void do_cat(int fd, char *name) { - int len, size=toys.optflags ? 1 : sizeof(toybuf); + int i, len, size=(toys.optflags & FLAG_u) ? 1 : sizeof(toybuf); - for (;;) { + for(;;) { len = read(fd, toybuf, size); - if (len<0) perror_msg("%s",name); - if (len<1) break; - xwrite(1, toybuf, len); + if (len < 0) toys.exitval = EXIT_FAILURE; + if (len < 1) break; + if (CFG_CAT_V && (toys.optflags&~FLAG_u)) { + for (i=0; i<len; i++) { + char c=toybuf[i]; + + if (c > 126 && (toys.optflags & FLAG_v)) { + if (c > 127) { + printf("M-"); + c -= 128; + } + if (c == 127) { + printf("^?"); + continue; + } + } + if (c < 32) { + if (c == 10) { + if (toys.optflags & FLAG_e) xputc('$'); + } else if (toys.optflags & (c==9 ? FLAG_t : FLAG_v)) { + printf("^%c", c+'@'); + continue; + } + } + xputc(c); + } + } else xwrite(1, toybuf, len); } } @@ -36,3 +97,15 @@ void cat_main(void) { loopfiles(toys.optargs, do_cat); } + +//todo: +//void catv_main(void) +//{ +// toys.optflags ^= FLAG_v; +// loopfiles(toys.optargs, do_catv); +//} + +// The common infrastructure is testing FLAG_h which is only defined in cat +// context (not catv), but catv can't use cat's flag context if cat is disabled +// and its flags are zero. Need to upgrade flag parsing infrastructure so +// defining FORCE_FLAGS along with FOR_command doesn't zero unused flag macros. |