From c63f340d90800895f007de64b7d2d14624263331 Mon Sep 17 00:00:00 2001 From: nthnluu Date: Sun, 28 Jan 2024 21:20:27 -0500 Subject: Created student weenix repository --- user/usr/bin/wc.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 user/usr/bin/wc.c (limited to 'user/usr/bin/wc.c') diff --git a/user/usr/bin/wc.c b/user/usr/bin/wc.c new file mode 100644 index 0000000..f622614 --- /dev/null +++ b/user/usr/bin/wc.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include + +#define BUFFER_SIZE 1024 + +typedef struct count_results +{ + unsigned long long n_chars; + unsigned long long n_words; + unsigned long long n_lines; +} count_results_t; + +char buf[BUFFER_SIZE]; + +void print_counts(count_results_t *results, char *name) +{ + if (name) + { + printf("%10llu %10llu %10llu %10s\n", results->n_lines, + results->n_words, results->n_chars, name); + } + else + { + printf("%10llu %10llu %10llu\n", results->n_lines, results->n_words, + results->n_chars); + } +} + +void count(int fd, char *name, count_results_t *results) +{ + size_t bytes_read; + unsigned int in_word, i; + + in_word = 0; + while ((bytes_read = read(fd, buf, BUFFER_SIZE)) > 0) + { + for (i = 0; i < bytes_read; ++i) + { + if (isspace(buf[i])) + { + if (in_word) + { + results->n_words++; + in_word = 0; + } + } + else + { + in_word = 1; + } + + if (buf[i] == '\n') + { + results->n_lines++; + } + } + + results->n_chars += bytes_read; + } + + print_counts(results, name); +} + +int main(int argc, char **argv) +{ + int f, fd; + count_results_t total_counts = {.n_chars = 0, .n_words = 0, .n_lines = 0}; + count_results_t local_counts = {.n_chars = 0, .n_words = 0, .n_lines = 0}; + + if (argc == 1) + { + /* Reading from standard input. */ + count(0, 0, &total_counts); + } + else + { + /* Reading files, not standard input. */ + for (f = 1; f < argc; ++f) + { + fd = open(argv[f], O_RDONLY, 0); + if (fd < 0) + { + /* Error opening file. */ + fprintf(stderr, "wc: %s: open: %s\n", argv[f], strerror(errno)); + } + else + { + /* Opened the file. */ + count(fd, argv[f], &local_counts); + + total_counts.n_chars += local_counts.n_chars; + total_counts.n_words += local_counts.n_words; + total_counts.n_lines += local_counts.n_lines; + + /* Reset the local counts. */ + local_counts.n_chars = local_counts.n_words = + local_counts.n_lines = 0; + + close(fd); + } + } + + if (argc > 2) + { + /* They provided multiple files. We should print the total too. */ + print_counts(&total_counts, "total"); + } + } + + return 0; +} -- cgit v1.2.3-70-g09d2