summaryrefslogtreecommitdiff
path: root/userland/minibox/utilities/wc.c
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-10-22 19:50:38 +0200
committerAnton Kling <anton@kling.gg>2023-10-22 19:50:38 +0200
commit4e09bca9e34c226b6d7e34b4fa11248405fd988e (patch)
tree80f156b7940d9d19971395f335530170c69516c7 /userland/minibox/utilities/wc.c
Move everything into a new repo.
Diffstat (limited to 'userland/minibox/utilities/wc.c')
-rw-r--r--userland/minibox/utilities/wc.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/userland/minibox/utilities/wc.c b/userland/minibox/utilities/wc.c
new file mode 100644
index 0000000..886eb9e
--- /dev/null
+++ b/userland/minibox/utilities/wc.c
@@ -0,0 +1,106 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include "include.h"
+
+int cmode, wmode, lmode;
+
+void output(const char * str, size_t lines, size_t words, size_t chars)
+{
+ if(lmode)
+ printf("%d", lines);
+
+ if(wmode)
+ {
+ if(lmode) putchar(' ');
+
+ printf("%d", words);
+ }
+
+ if(cmode)
+ {
+ if(lmode) putchar(' ');
+
+ printf("%d", chars);
+ }
+
+ if(str) printf(" %s", str);
+
+ putchar('\n');
+}
+
+void wc(int argc, char ** argv)
+{
+ int fd = fd_stdin;
+ size_t total_chars, total_words, total_lines;
+ total_chars = total_words = total_lines = 0;
+
+ if(NULL == *argv)
+ goto read_stdin;
+
+
+ for(;*argv;argv++)
+ {
+ int new_word = 1;
+ size_t chars = 0,
+ words = chars,
+ lines = chars;
+
+ fd = open(*argv, O_RDONLY, 0);
+read_stdin:
+ for(char c;read(fd, &c, 1);)
+ {
+ if(cmode)
+ chars++;
+
+ if(wmode)
+ {
+ if(isspace(c)) {
+ new_word = 1;
+ } else if(new_word) {
+ words++;
+ new_word = 0;
+ }
+ }
+
+ if(lmode)
+ if('\n' == c)
+ lines++;
+ }
+ close(fd);
+ if(lmode) total_lines += lines;
+ if(wmode) total_words += words;
+ if(cmode) total_chars += chars;
+
+ output(*argv, lines, words, chars);
+ if(NULL == *argv) return; // We read from stdin
+ }
+
+ if(argc > 1) output("total", total_lines, total_words, total_chars);
+}
+
+int wc_main(int argc, char ** argv)
+{
+ cmode = wmode = lmode = 0;
+ for(argc--;*++argv && '-' == **argv;argc--)
+ switch(*(*argv+1))
+ {
+ case 'l':
+ lmode = 1;
+ break;
+ case 'w':
+ wmode = 1;
+ break;
+ case 'c':
+ cmode = 1;
+ break;
+ }
+
+ if(!(lmode || cmode || wmode))
+ cmode = wmode = lmode = 1;
+
+ wc(argc, argv);
+ return 0;
+}