commit aec062db2e9525927fb8690a21fbf16ef53488c5
parent 0b01807f10760f40e4196b83763d45523b65b239
Author: NunoSempere <nuno.sempere@protonmail.com>
Date: Sat, 9 Sep 2023 11:22:41 +0200
small simplification.
Diffstat:
3 files changed, 18 insertions(+), 21 deletions(-)
diff --git a/README.md b/README.md
@@ -11,7 +11,7 @@
## Comparison with wc.
-The GNU utils version ([github](https://github.com/coreutils/coreutils/tree/master/src/wc), [savannah](http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=blob;f=src/wc.c;hb=HEAD)) is a bit over 1K lines of C. It does many things and checks many possible failure modes.
+The GNU utils version ([github](https://github.com/coreutils/coreutils/tree/master/src/wc.c), [savannah](http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=blob;f=src/wc.c;hb=HEAD)) is a bit over 1K lines of C. It does many things and checks many possible failure modes.
The busybox version ([git.busybox.net](https://git.busybox.net/busybox/tree/coreutils/wc.c)) of wc is much shorter, at 257 lines, while striving to be [POSIX-compliant](https://pubs.opengroup.org/onlinepubs/9699919799/), meaning it has flags.
@@ -35,4 +35,4 @@ The plan9port version of wc ([github](https://github.com/9fans/plan9port/blob/ma
- If it doesn't have arguments, read from stdin.
- [ ] Open files, read characters.
- [ ] Write version that counts lines
-- [ ]
+- [ ] Document reading from user-inputed stdin (end with Ctrl+D)
diff --git a/ww b/ww
Binary files differ.
diff --git a/ww.c b/ww.c
@@ -1,50 +1,47 @@
#include <stdio.h>
#include <unistd.h>
-int process_fn(int fn)
+int wc(FILE* fp)
{
char c[1];
- int seen_word = 0;
- int seen_sep_after_word = 0;
- int num_words = 0;
+ int seen_word = 0, seen_sep_after_word = 0, num_words = 0;
+ int fn = fileno(fp);
while (read(fn, c, sizeof(c)) > 0) {
- if (*c != '\n' && *c != ' ' && *c != '\t') {
- seen_word = 1;
- } else if (seen_word) {
- seen_sep_after_word = 1;
+ if (*c == '\n' || *c == ' ' || *c == '\t') {
+ if (seen_word) {
+ seen_sep_after_word = 1;
+ }
} else {
- // see a separator, but haven't seen a word: do nothing
- // exercise: what happens if you only track seen_sep,
- // instead of seen_sep_after_word?
- // test with: $ echo " x x" | ./wc
+ seen_word = 1;
}
+ // exercise: what happens if you only track seen_sep,
+ // instead of seen_sep_after_word?
+ // test with: $ echo " hello world" | ./wc
if (seen_word && seen_sep_after_word) {
num_words++;
seen_sep_after_word = seen_word = 0;
}
}
- if (seen_word) {
- num_words++;
- }
+ num_words+=seen_word;
printf("%i\n", num_words);
return 0;
}
int main(int argc, char** argv)
{
- if (!isatty(STDIN_FILENO)) {
- return process_fn(STDIN_FILENO);
+ if (argc == 1) {
+ return wc(stdin);
} else if (argc > 1) {
FILE* fp = fopen(argv[1], "r");
if (!fp) {
perror("Could not open file");
return 1;
}
- fclose(fp);
- return process_fn(fileno(fp));
+ return wc(fp) && fclose(fp);
} else {
printf("Usage: ww file.txt\n");
printf(" or: cat file.txt | ww\n");
+ printf(" or: ww # read from user-inputted stdin\n");
}
return 0;
}