Skip to content

Commit

Permalink
wc: Add -L option to show the length of the longest line
Browse files Browse the repository at this point in the history
If more than one file is specified on the command line and the `-L`
option is used, the totals field will show the longest line
encountered; it is not a sum like the other values.
  • Loading branch information
tcl3 authored and awesomekling committed Jun 23, 2023
1 parent 8e52d11 commit 702054d
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
3 changes: 2 additions & 1 deletion Base/usr/share/man/man1/wc.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ wc - word, line, character, and byte count
## Synopsis

```sh
$ wc [--lines] [--bytes] [--words] [file...]
$ wc [--lines] [--bytes] [--words] [--max-line-length] [file...]
```

## Options
Expand All @@ -15,6 +15,7 @@ $ wc [--lines] [--bytes] [--words] [file...]
* `-l`, `--lines`: Output line count
* `-c`, `--bytes`: Output byte count
* `-w`, `--words`: Output word count
* `-L`, `--max-line-length`: Output byte count of the longest line

## Arguments

Expand Down
19 changes: 17 additions & 2 deletions Userland/Utilities/wc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ struct Count {
unsigned lines { 0 };
unsigned characters { 0 };
unsigned words { 0 };
unsigned max_line_length { 0 };
size_t bytes { 0 };
};

bool g_output_line = false;
bool g_output_byte = false;
bool g_output_word = false;
bool g_output_max_line_length = false;

static void wc_out(Count const& count)
{
Expand All @@ -37,6 +39,8 @@ static void wc_out(Count const& count)
out("{:7} ", count.words);
if (g_output_byte)
out("{:7} ", count.bytes);
if (g_output_max_line_length)
out("{:7} ", count.max_line_length);

outln("{:>14}", count.name);
}
Expand All @@ -58,14 +62,22 @@ static ErrorOr<Count> get_count(StringView file_specifier)
count.name = file_specifier;

bool start_a_new_word = true;
unsigned current_line_length = 0;

u8 ch;
for (Bytes bytes = TRY(file->read_some({ &ch, 1 })); bytes.size() != 0; bytes = TRY(file->read_some(bytes))) {
count.bytes++;
if (ch != '\n')
current_line_length++;
if (is_ascii_space(ch)) {
start_a_new_word = true;
if (ch == '\n')
if (ch == '\n') {
count.lines++;
if (current_line_length > count.max_line_length)
count.max_line_length = current_line_length;

current_line_length = 0;
}
} else if (start_a_new_word) {
start_a_new_word = false;
count.words++;
Expand All @@ -83,6 +95,8 @@ static Count get_total_count(Vector<Count> const& counts)
total_count.words += count.words;
total_count.characters += count.characters;
total_count.bytes += count.bytes;
if (count.max_line_length > total_count.max_line_length)
total_count.max_line_length = count.max_line_length;
}
return total_count;
}
Expand All @@ -97,10 +111,11 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
args_parser.add_option(g_output_line, "Output line count", "lines", 'l');
args_parser.add_option(g_output_byte, "Output byte count", "bytes", 'c');
args_parser.add_option(g_output_word, "Output word count", "words", 'w');
args_parser.add_option(g_output_max_line_length, "Output byte count of the longest line", "max-line-length", 'L');
args_parser.add_positional_argument(file_specifiers, "File to process", "file", Core::ArgsParser::Required::No);
args_parser.parse(arguments);

if (!g_output_line && !g_output_byte && !g_output_word)
if (!g_output_line && !g_output_byte && !g_output_word && !g_output_max_line_length)
g_output_line = g_output_byte = g_output_word = true;

Vector<Count> counts;
Expand Down

0 comments on commit 702054d

Please sign in to comment.