Compare commits

...

2 Commits

Author SHA1 Message Date
d5026e5b76 readme tweaks 2023-09-15 12:20:44 +03:00
c3ac29d887 tweak: use else if instead of wrapped else, if
+formatting
2023-09-15 12:19:40 +03:00
5 changed files with 17 additions and 19 deletions

View File

@ -1,6 +1,6 @@
# wc: count words in <50 lines of C # wc: count words in <50 lines of C
The Unix utility wc counts words. You can make simple, non-POSIX compatible version of it that solely counts words in [158 words and 44 lines of C](https://git.nunosempere.com/personal/wc/src/branch/master/src/wc.c). Or you can be like GNU and take 3615 words and 1034 lines to do something more complex. The Unix utility wc counts words. You can make simple, non-POSIX compatible version of it that solely counts words in [159 words and 42 lines of C](https://git.nunosempere.com/personal/wc/src/branch/master/src/wc.c). Or you can be like GNU and take 3615 words and 1034 lines to do something more complex.
## Desiderata ## Desiderata
@ -23,7 +23,7 @@ The [plan9](https://9p.io/sources/plan9/sys/src/cmd/wc.c) version implements som
The plan9port version of wc ([github](https://github.com/9fans/plan9port/blob/master/src/cmd/wc.c)) also implements some sort of table method, in 352 lines. It reads from stdin if the number of args is 0, and uses the Linux `read` function to read character by character. The plan9port version of wc ([github](https://github.com/9fans/plan9port/blob/master/src/cmd/wc.c)) also implements some sort of table method, in 352 lines. It reads from stdin if the number of args is 0, and uses the Linux `read` function to read character by character.
The [OpenBSD](https://github.com/openbsd/src/blob/master/usr.bin/wc/wc.c) version is just *nice*. It reads from stdin by default, and uses a bit of buffering using read to speed things up. It defaults to using fstat when counting characters. It is generally pleasantly understandable, nice to read. The [OpenBSD](https://github.com/openbsd/src/blob/master/usr.bin/wc/wc.c) version is just *nice*. It reads from stdin by default, and uses a bit of buffering using read to speed things up. It defaults to using fstat when counting characters. It is generally pleasantly understandable, nice to read. I'm actually surprised at how pleasant it is to read.
The [FreeBSD version](https://cgit.freebsd.org/src/tree/usr.bin/wc/wc.c) sits at 367 lines. It has enough new things that I can't parse all that it's doing: in lines 137-143, what is capabilities mode? what is casper?, but otherwise it decides whether to read from stdin by the number of arguments, in line 157. It uses a combination of fstat and read, depending on the type of file. The [FreeBSD version](https://cgit.freebsd.org/src/tree/usr.bin/wc/wc.c) sits at 367 lines. It has enough new things that I can't parse all that it's doing: in lines 137-143, what is capabilities mode? what is casper?, but otherwise it decides whether to read from stdin by the number of arguments, in line 157. It uses a combination of fstat and read, depending on the type of file.

View File

@ -6,7 +6,7 @@ int chc(FILE* fp)
register int c; register int c;
int num_chars = 0; int num_chars = 0;
while ((c = getc(fp)) != EOF) { while ((c = getc(fp)) != EOF) {
num_chars ++; num_chars++;
} }
printf("%i\n", num_chars); printf("%i\n", num_chars);
return 0; return 0;
@ -22,7 +22,7 @@ int main(int argc, char** argv)
perror("Could not open file"); perror("Could not open file");
return 1; return 1;
} }
return chc(fp) && fclose(fp); return chc(fp) && fclose(fp);
} else { } else {
printf("Usage: chc file.txt\n"); printf("Usage: chc file.txt\n");
printf(" or: cat file.txt | chc\n"); printf(" or: cat file.txt | chc\n");

View File

@ -6,11 +6,11 @@ int lc(FILE* fp)
int num_lines = 0; int num_lines = 0;
register int c; register int c;
while ((c = getc(fp)) != EOF) { while ((c = getc(fp)) != EOF) {
if (c == '\n' ) { if (c == '\n') {
num_lines ++; num_lines++;
} }
} }
// num_lines += (c != '\n'); // < judgment call, adds a line if the last line isn't followed by a newline. // num_lines += (c != '\n'); // < judgment call, adds a line if the last line isn't followed by a newline.
printf("%i\n", num_lines); printf("%i\n", num_lines);
return 0; return 0;
} }
@ -25,7 +25,7 @@ int main(int argc, char** argv)
perror("Could not open file"); perror("Could not open file");
return 1; return 1;
} }
return lc(fp) && fclose(fp); return lc(fp) && fclose(fp);
} else { } else {
printf("Usage: lc file.txt\n"); printf("Usage: lc file.txt\n");
printf(" or: cat file.txt | lc\n"); printf(" or: cat file.txt | lc\n");

BIN
src/wc

Binary file not shown.

View File

@ -8,14 +8,12 @@ int wc(FILE* fp)
while ((c = getc(fp)) != EOF) { while ((c = getc(fp)) != EOF) {
if (c != ' ' && c != '\n' && c != '\t') { if (c != ' ' && c != '\n' && c != '\t') {
word = 1; word = 1;
} else { } else if (word) {
if (word) { num_words++;
num_words++; word = 0;
word = 0;
}
} }
} }
num_words+=word; num_words += word;
printf("%i\n", num_words); printf("%i\n", num_words);
return 0; return 0;
} }
@ -30,11 +28,11 @@ int main(int argc, char** argv)
perror("Could not open file"); perror("Could not open file");
return 1; return 1;
} }
int wc_status = wc(fp); int wc_status = wc(fp);
int fclose_status = fclose(fp); int fclose_status = fclose(fp);
return (wc_status == 0) && (fclose_status ==0); return (wc_status == 0) && (fclose_status == 0);
// can't do return wc_status == 0 && fclose_status == 0; // can't do return wc_status == 0 && fclose_status == 0;
// because then if wc returns with -1, fclose is not called. // because then if wc returns with -1, fclose is not called.
} else { } else {
printf("Usage: wc file.txt\n"); printf("Usage: wc file.txt\n");
printf(" or: cat file.txt | wc\n"); printf(" or: cat file.txt | wc\n");