Heya, I added a -L[ongest line] option to wc

I thought that this option was considered and discarded since
it isn't that hard to implement and is a GNU extension. But grep-ing through
the list archives shows no mention of a -L option in relation to wc.

I added the -L option in the below patch, along with a couple of tests for it.
GNU wc -L doesn't count newlines, so it makes sense that toybox's one shouldn't.
the "(signed)" cast is so the output is never "-1"

Also, when I originally tried to implement this option, I appended it
to the end of the option string. Then -l started acting in the same way as -L.
Which made me take a look at generated/flags.h to check if options were being 
parsed
case-sensitively.

Then I realized that option strings are parsed into "FLAG_" macros backwards.
(End -> Start, First options get higher value flags)
Which from my searching isn't mentioned in lib/args.c, nor scripts/make.sh.

- Oliver Webb <[email protected]>
From 7b1107af03f87e210d39a4c592f5ff7eeed2bd12 Mon Sep 17 00:00:00 2001
From: Oliver Webb <[email protected]>
Date: Sat, 4 Nov 2023 11:16:09 -0500
Subject: [PATCH] Added wc -L

---
 tests/wc.test   |  4 ++++
 toys/posix/wc.c | 19 ++++++++++++-------
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/tests/wc.test b/tests/wc.test
index 4ab03868..cd08679b 100755
--- a/tests/wc.test
+++ b/tests/wc.test
@@ -23,6 +23,10 @@ testing "one file" "wc file1" "4 5 26 file1\n" "" ""
 testing "multiple files" "wc input - file1" \
         "      1       2       3 input\n      0       2       3 -\n      4       5      26 file1\n      5       9      32 total\n" "a\nb" "a b"
 
+#Tests for -L
+testing "-L" "wc -L" "4\n" "" "12\n123\n12\n1234\n12"
+testing "-L len 0" "wc -L" "0\n" "" "\n"
+
 #Tests for wc -m
 echo -n " " > file1
 for i in $(seq 1 512); do echo -n "üüüüüüüüüüüüüüüü" >> file1; done
diff --git a/toys/posix/wc.c b/toys/posix/wc.c
index 31df00e5..6cdddb3e 100644
--- a/toys/posix/wc.c
+++ b/toys/posix/wc.c
@@ -4,13 +4,13 @@
  *
  * See http://opengroup.org/onlinepubs/9699919799/utilities/wc.html
 
-USE_WC(NEWTOY(wc, "mcwl", TOYFLAG_USR|TOYFLAG_BIN))
+USE_WC(NEWTOY(wc, "Lmcwl", TOYFLAG_USR|TOYFLAG_BIN))
 
 config WC
   bool "wc"
   default y
   help
-    usage: wc -lwcm [FILE...]
+    usage: wc -lwcmL [FILE...]
 
     Count lines, words, and characters in input.
 
@@ -18,6 +18,7 @@ config WC
     -w	Show words
     -c	Show bytes
     -m	Show characters
+    -L  Show longest Line
 
     By default outputs lines, words, bytes, and filename for each
     argument (or from stdin if none). Displays only either bytes
@@ -28,7 +29,7 @@ config WC
 #include "toys.h"
 
 GLOBALS(
-  unsigned long totals[4];
+  unsigned long totals[5];
 )
 
 static void show_lengths(unsigned long *lengths, char *name)
@@ -45,7 +46,7 @@ static void show_lengths(unsigned long *lengths, char *name)
   if (!(!toys.optc && !(toys.optflags & (toys.optflags-1))) && toys.optc!=1)
     space = 7;
 
-  for (i = 0; i<4; i++) {
+  for (i = 0; i<5; i++) {
     if (toys.optflags&(1<<i)) {
       printf(" %*ld"+first, space, lengths[i]);
       first = 0;
@@ -59,7 +60,7 @@ static void show_lengths(unsigned long *lengths, char *name)
 static void do_wc(int fd, char *name)
 {
   int len = 0, clen = 1, space = 0;
-  unsigned long word = 0, lengths[] = {0,0,0,0};
+  unsigned long word = 0, lengths[] = {0,0,0,0,0};
 
   // Speed up common case: wc -c normalfile is file length.
   if (toys.optflags == FLAG_c) {
@@ -73,7 +74,7 @@ static void do_wc(int fd, char *name)
   }
 
   for (;;) {
-    int pos, done = 0, len2 = read(fd, toybuf+len, sizeof(toybuf)-len);
+    int pos, linelen = 0, done = 0, len2 = read(fd, toybuf+len, sizeof(toybuf)-len);
     unsigned wchar;
 
     if (len2<0) perror_msg_raw(name);
@@ -81,8 +82,12 @@ static void do_wc(int fd, char *name)
     if (len2<1) done++;
 
     for (pos = 0; pos<len; pos++) {
-      if (toybuf[pos]=='\n') lengths[0]++;
+      if (toybuf[pos]=='\n') {
+        lengths[4] = maxof((signed)lengths[4], --linelen);
+        lengths[(linelen = 0)]++;
+      }
       lengths[2]++;
+      linelen++;
       if (FLAG(m)) {
         // If we've consumed next wide char
         if (--clen<1) {
-- 
2.34.1

_______________________________________________
Toybox mailing list
[email protected]
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to