diff --git a/Userland/Utilities/nl.cpp b/Userland/Utilities/nl.cpp index 7118e17b99..71f5cfd998 100644 --- a/Userland/Utilities/nl.cpp +++ b/Userland/Utilities/nl.cpp @@ -7,10 +7,8 @@ #include #include #include +#include #include -#include -#include -#include enum NumberStyle { NumberAllLines, @@ -25,7 +23,7 @@ ErrorOr serenity_main(Main::Arguments arguments) StringView separator = " "sv; int start_number = 1; int number_width = 6; - Vector files; + Vector filenames; Core::ArgsParser args_parser; @@ -54,28 +52,25 @@ ErrorOr serenity_main(Main::Arguments arguments) args_parser.add_option(separator, "Separator between line numbers and lines", "separator", 's', "string"); args_parser.add_option(start_number, "Initial line number", "startnum", 'v', "number"); args_parser.add_option(number_width, "Number width", "width", 'w', "number"); - args_parser.add_positional_argument(files, "Files to process", "file", Core::ArgsParser::Required::No); + args_parser.add_positional_argument(filenames, "Files to process", "file", Core::ArgsParser::Required::No); args_parser.parse(arguments); - Vector file_pointers; - if (!files.is_empty()) { - for (auto& file : files) { - FILE* file_pointer = fopen(file.characters(), "r"); - if (!file_pointer) { - warnln("Failed to open {}: {}", file, strerror(errno)); - continue; - } - file_pointers.append(file_pointer); - } - } else { - file_pointers.append(stdin); - } + if (filenames.is_empty()) + filenames.append(""sv); + + for (auto const filename : filenames) { + auto maybe_file = Core::File::open_file_or_standard_stream(filename, Core::File::OpenMode::Read); + if (maybe_file.is_error()) { + warnln("Failed to open {}: {}", filename, maybe_file.release_error()); + continue; + } + + auto file = maybe_file.release_value(); - for (auto& file_pointer : file_pointers) { int line_number = start_number - increment; // so the line number can start at 1 when added below int previous_character = 0; - int next_character = 0; - while ((next_character = fgetc(file_pointer)) != EOF) { + u8 next_character; + for (Bytes bytes = TRY(file->read_some({ &next_character, 1 })); bytes.size() != 0; bytes = TRY(file->read_some(bytes))) { if (previous_character == 0 || previous_character == '\n') { if (next_character == '\n' && number_style != NumberAllLines) { // Skip printing line count on empty lines. @@ -90,7 +85,7 @@ ErrorOr serenity_main(Main::Arguments arguments) putchar(next_character); previous_character = next_character; } - fclose(file_pointer); + if (previous_character != '\n') outln(); // for cases where files have no trailing newline }