123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- #include <AK/String.h>
- #include <AK/Vector.h>
- #include <LibCore/CArgsParser.h>
- #include <ctype.h>
- #include <stdio.h>
- static bool output_chars = false;
- static bool output_words = false;
- static bool output_lines = false;
- struct Count {
- String file;
- unsigned long chars = 0;
- unsigned long words = 0;
- unsigned long lines = 0;
- };
- int wc(const String& filename, Vector<Count>& counts);
- void report(const Count& count)
- {
- if (output_lines) {
- printf("%lu ", count.lines);
- }
- if (output_words) {
- printf("%lu ", count.words);
- }
- if (output_chars) {
- printf("%lu ", count.chars);
- }
- printf("%s\n", count.file.characters());
- }
- void report(const Vector<Count>& counts)
- {
- Count total { "total" };
- for (const auto& c : counts) {
- report(c);
- total.lines += c.lines;
- total.words += c.words;
- total.chars += c.chars;
- }
- if (counts.size() > 1) {
- report(total);
- }
- fflush(stdout);
- }
- int count_words(const char* s)
- {
- int n = 0;
- bool in_word = false;
- for (; *s; ++s) {
- if (!isspace(*s)) {
- if (!in_word) {
- in_word = true;
- ++n;
- }
- } else if (in_word) {
- in_word = false;
- }
- }
- return n;
- }
- int main(int argc, char** argv)
- {
- if (argc < 2) {
- printf("usage: wc [-c|-m] [-lw] [file...]\n");
- return 0;
- }
- CArgsParser args_parser("wc");
- args_parser.add_arg("l", "Include lines in count");
- args_parser.add_arg("c", "Include bytes in count");
- args_parser.add_arg("m", "Include chars in count");
- args_parser.add_arg("w", "Include words in count");
- CArgsParserResult args = args_parser.parse(argc, (char**)argv);
- if (args.is_present("l")) {
- output_lines = true;
- }
- if (args.is_present("c")) {
- output_chars = true;
- }
- if (args.is_present("m")) {
- output_chars = true;
- }
- if (args.is_present("w")) {
- output_words = true;
- }
- if (!output_lines && !output_words && !output_chars) {
- output_lines = output_chars = output_words = true;
- }
- Vector<String> files = args.get_single_values();
- Vector<Count> counts;
- int status;
- if (files.is_empty()) {
- status = wc("", counts);
- if (status != 0)
- return status;
- } else {
- for (const auto& f : files) {
- status = wc(f, counts);
- if (status != 0)
- return status;
- }
- }
- report(counts);
- return 0;
- }
- int wc(const String& filename, Vector<Count>& counts)
- {
- FILE* fp = nullptr;
- if (filename == "" || filename == "-") {
- fp = stdin;
- } else {
- fp = fopen(filename.characters(), "r");
- if (fp == nullptr) {
- fprintf(stderr, "wc: Could not open file '%s'\n", filename.characters());
- return 1;
- }
- }
- Count count { filename };
- char* line = nullptr;
- size_t len = 0;
- ssize_t n_read = 0;
- while ((n_read = getline(&line, &len, fp)) != -1) {
- count.lines++;
- count.words += count_words(line);
- count.chars += n_read;
- }
- counts.append(count);
- fclose(fp);
- if (line) {
- free(line);
- }
- return 0;
- }
|