From f30dc92a1e7ba27c285e3551271ae984e683b2de Mon Sep 17 00:00:00 2001 From: PerrinJS Date: Sat, 20 Apr 2024 20:01:58 +0800 Subject: [PATCH] cat: Add the -n line numbering feature Adds the -n line numbering feature with the same formatting as gnu's cat function. --- Userland/Utilities/cat.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Userland/Utilities/cat.cpp b/Userland/Utilities/cat.cpp index 237ba67f1482aa..57aa74420ee30e 100644 --- a/Userland/Utilities/cat.cpp +++ b/Userland/Utilities/cat.cpp @@ -11,15 +11,36 @@ #include #include +struct LineTracker { + size_t line_count = 1; + bool display_line_number = true; +}; + +static void output_buffer_with_line_numbers(LineTracker& line_tracker, ReadonlyBytes buffer_span) +{ + for (auto const curr_value : buffer_span) { + if (line_tracker.display_line_number) { + out("{: >6}\t", line_tracker.line_count); + line_tracker.line_count++; + line_tracker.display_line_number = false; + } + if (curr_value == '\n') + line_tracker.display_line_number = true; + out("{:c}", curr_value); + } +} + ErrorOr serenity_main(Main::Arguments arguments) { TRY(Core::System::pledge("stdio rpath")); Vector paths; + bool show_lines = false; Core::ArgsParser args_parser; args_parser.set_general_help("Concatenate files or pipes to stdout."); args_parser.add_positional_argument(paths, "File path", "path", Core::ArgsParser::Required::No); + args_parser.add_option(show_lines, "Number all output lines", "number", 'n'); args_parser.parse(arguments); if (paths.is_empty()) @@ -37,11 +58,18 @@ ErrorOr serenity_main(Main::Arguments arguments) TRY(Core::System::pledge("stdio")); + // used only if we are using the -n option + LineTracker line_tracker; + Array buffer; for (auto const& file : files) { while (!file->is_eof()) { auto const buffer_span = TRY(file->read_some(buffer)); - out("{:s}", buffer_span); + if (show_lines) { + output_buffer_with_line_numbers(line_tracker, buffer_span); + } else { + out("{:s}", buffer_span); + } } }