Skip to content

Commit

Permalink
wc: Seek the input file(s) if only -c is passed
Browse files Browse the repository at this point in the history
If the user only wants to get the byte count of a set of files, then for
each file we can simply seek it to get the byte count instead of
iterating over all the bytes.
  • Loading branch information
Mango0x45 authored and supercomputer7 committed May 31, 2024
1 parent 925bea4 commit 99e9120
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions Userland/Utilities/wc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static void wc_out(Count const& count)
outln("{:>14}", count.name);
}

static ErrorOr<Count> get_count(StringView file_specifier)
static ErrorOr<Count> get_count(StringView file_specifier, bool only_bytes)
{
Count count;

Expand All @@ -58,9 +58,21 @@ static ErrorOr<Count> get_count(StringView file_specifier)
}

auto file = TRY(Core::InputBufferedFile::create(maybe_file.release_value()));

count.name = file_specifier;

if (only_bytes) {
auto seek_or_error = file->seek(0, SeekMode::FromEndPosition);
if (!seek_or_error.is_error()) {
count.bytes = seek_or_error.release_value();
return count;
}

// NOTE: If the error is not ESPIPE, then return an error, or otherwise
// just handle the input as a non-seekable stream.
if (seek_or_error.error().code() != ESPIPE)
return seek_or_error.release_error();
}

bool start_a_new_word = true;
unsigned current_line_length = 0;

Expand Down Expand Up @@ -118,14 +130,16 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
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;

bool only_bytes = !g_output_line && !g_output_word && !g_output_max_line_length;

Vector<Count> counts;
for (auto const& file_specifier : file_specifiers)
counts.append(TRY(get_count(file_specifier)));
counts.append(TRY(get_count(file_specifier, only_bytes)));

TRY(Core::System::pledge("stdio"));

if (file_specifiers.is_empty())
counts.append(TRY(get_count(""sv)));
counts.append(TRY(get_count(""sv, only_bytes)));
else if (file_specifiers.size() > 1)
counts.append(get_total_count(counts));

Expand Down

0 comments on commit 99e9120

Please sign in to comment.