This basically brings the catv code into cat (but optionally enabled,
like the 'big' variant of sort) and adds the missing-from-both -n
option. There are a couple of options in coreutils cat still missing,
and a few more still in BSD's cat, but they're pretty useless. (I've
commented the missing coreutils options on the assumption that someone
might care, but haven't even done that for the missing BSD options.)

diff --git a/toys/posix/cat.c b/toys/posix/cat.c
index 3644c4f..758248a 100644
--- a/toys/posix/cat.c
+++ b/toys/posix/cat.c
@@ -4,7 +4,7 @@
  *
  * See http://opengroup.org/onlinepubs/9699919799/utilities/cat.html

-USE_CAT(NEWTOY(cat, "u", TOYFLAG_BIN))
+USE_CAT(NEWTOY(cat, USE_CAT_FAT("AETentv")"u", TOYFLAG_BIN))

 config CAT
   bool "cat"
@@ -16,10 +16,33 @@ config CAT
     Filename "-" is a synonym for stdin.

     -u Copy one byte at a time (slow).
+
+config CAT_FAT
+  bool "cat [-AETentv]"
+  default y
+  depends on CAT
+  help
+    usage: cat [-AETentv] [file...]
+
+    Display nonprinting characters as escape sequences. Use M-x for
+    high ascii characters (>127), and ^x for other nonprinting chars.
+
+    -A Show all non-printable (same as -vET).
+    -E Show $ at line ends.
+    -T Show ^I for tabs.
+    -e Show non-printable and line ends (same as -vE).
+    -n Number all lines.
+    -t Show non-printable and tabs (same as -vT).
+    -v Show non-printable with ^x or M-x, except for line ends and tabs.
 */

+#define FOR_cat
 #include "toys.h"

+// Still missing:
+// -b (number non-blank lines only)
+// -s (suppress repeated blank lines)
+
 static void do_cat(int fd, char *name)
 {
   int len, size=toys.optflags ? 1 : sizeof(toybuf);
@@ -32,7 +55,58 @@ static void do_cat(int fd, char *name)
   }
 }

+#if CFG_CAT_FAT
+static void do_fat_cat(int fd, char *name)
+{
+  int line = 1, at_line_start = 1;
+  for (;;) {
+    int i, len;
+
+    len = read(fd, toybuf, sizeof(toybuf));
+    if (len < 0) toys.exitval = EXIT_FAILURE;
+    if (len < 1) break;
+    for (i=0; i<len; i++) {
+      char c=toybuf[i];
+
+      if (at_line_start && toys.optflags & FLAG_n) {
+        printf("% 6d  ", line++);
+        at_line_start = 0;
+      }
+      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('$');
+          at_line_start = 1;
+        } else if (toys.optflags & (c==9 ? FLAG_T : FLAG_v)) {
+          printf("^%c", c+'@');
+          continue;
+        }
+      }
+      xputc(c);
+    }
+  }
+}
+#endif
+
 void cat_main(void)
 {
-  loopfiles(toys.optargs, do_cat);
+  if ((toys.optflags & ~FLAG_u) == 0) {
+    loopfiles(toys.optargs, do_cat);
+  } else {
+#if CFG_CAT_FAT
+    if (toys.optflags & FLAG_A) toys.optflags |= FLAG_v|FLAG_E|FLAG_T;
+    if (toys.optflags & FLAG_e) toys.optflags |= FLAG_v|FLAG_E;
+    if (toys.optflags & FLAG_t) toys.optflags |= FLAG_v|FLAG_T;
+    loopfiles(toys.optargs, do_fat_cat);
+#endif
+  }
 }
_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to