summaryrefslogtreecommitdiff
path: root/Userland/Utilities/comm.cpp
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@serenityos.org>2022-09-20 11:56:33 +0100
committerLinus Groh <mail@linusgroh.de>2022-11-19 17:00:10 +0000
commit6763e1bd60bc0e35feb4c2ae831c017c05e7c811 (patch)
treeaa7648b69b5db1efc809aa526afefe1042429851 /Userland/Utilities/comm.cpp
parent8ed5403d8c673fcdeb13a9b8e365a3f54a24cd49 (diff)
downloadserenity-6763e1bd60bc0e35feb4c2ae831c017c05e7c811.zip
comm: Port to Core::Stream
Diffstat (limited to 'Userland/Utilities/comm.cpp')
-rw-r--r--Userland/Utilities/comm.cpp99
1 files changed, 64 insertions, 35 deletions
diff --git a/Userland/Utilities/comm.cpp b/Userland/Utilities/comm.cpp
index 08142442ec..c77a031482 100644
--- a/Userland/Utilities/comm.cpp
+++ b/Userland/Utilities/comm.cpp
@@ -1,11 +1,13 @@
/*
* Copyright (c) 2021, the SerenityOS developers.
+ * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibCore/ArgsParser.h>
#include <LibCore/File.h>
+#include <LibCore/Stream.h>
#include <LibCore/System.h>
#include <LibMain/Main.h>
#include <string.h>
@@ -20,7 +22,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
{
TRY(Core::System::pledge("stdio rpath"));
- String file1_path, file2_path;
+ String file1_path;
+ String file2_path;
bool suppress_col1 { false };
bool suppress_col2 { false };
bool suppress_col3 { false };
@@ -47,7 +50,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
return 1;
}
- bool print_color = isatty(STDOUT_FILENO);
+ bool print_color = TRY(Core::System::isatty(STDOUT_FILENO));
if (color)
print_color = true;
else if (no_color)
@@ -58,31 +61,38 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
return 1;
}
- auto process_file = [](String const& path, auto& file, int file_number) {
- if (path == "-") {
- file = Core::File::standard_input();
- } else {
- auto file_or_error = Core::File::open(path, Core::OpenMode::ReadOnly);
- if (file_or_error.is_error()) {
- warnln("Failed to open file{} '{}': {}", file_number, path, file_or_error.error());
- return false;
- }
- if (Core::File::is_directory(path)) {
- warnln("Failed to open file{} '{}': is a directory", file_number, path);
- return false;
- }
- file = file_or_error.value();
+ auto open_file = [](String const& path, auto& file, int file_number) {
+ auto file_or_error = Core::Stream::File::open_file_or_standard_stream(path, Core::Stream::OpenMode::Read);
+ if (file_or_error.is_error()) {
+ warnln("Failed to open file{} '{}': {}", file_number, path, file_or_error.error());
+ return false;
+ }
+
+ if (path != "-" && Core::File::is_directory(path)) {
+ warnln("Failed to open file{} '{}': is a directory", file_number, path);
+ return false;
+ }
+
+ auto buffered_file_or_error = Core::Stream::BufferedFile::create(file_or_error.release_value());
+ if (buffered_file_or_error.is_error()) {
+ warnln("Failed to create buffer for file{} '{}': {}", file_number, path, buffered_file_or_error.error());
+ return false;
}
+
+ file = buffered_file_or_error.release_value();
return true;
};
- RefPtr<Core::File> file1, file2;
- if (!(process_file(file1_path, file1, 1) && process_file(file2_path, file2, 2)))
+ OwnPtr<Core::Stream::BufferedFile> file1;
+ OwnPtr<Core::Stream::BufferedFile> file2;
+ if (!(open_file(file1_path, file1, 1) && open_file(file2_path, file2, 2)))
return 1;
char tab { '\t' };
size_t tab_count { 0 };
- String col1_fmt, col2_fmt, col3_fmt;
+ String col1_fmt;
+ String col2_fmt;
+ String col3_fmt;
if (!suppress_col1)
col1_fmt = String::formatted("{}{}", String::repeated(tab, tab_count++), print_color ? COL1_COLOR : "{}");
if (!suppress_col2)
@@ -93,17 +103,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto cmp = [&](String const& str1, String const& str2) {
if (case_insensitive)
return strcasecmp(str1.characters(), str2.characters());
- else
- return strcmp(str1.characters(), str2.characters());
- };
-
- auto process_remaining = [](String const& fmt, auto& file, int& count, bool print) {
- while (file->can_read_line()) {
- ++count;
- auto line = file->read_line();
- if (print)
- outln(fmt, line);
- }
+ return strcmp(str1.characters(), str2.characters());
};
bool read_file1 { true };
@@ -111,17 +111,33 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
int col1_count { 0 };
int col2_count { 0 };
int col3_count { 0 };
- String file1_line, file2_line;
+ String file1_line;
+ String file2_line;
+ Array<u8, PAGE_SIZE> buffer;
+
+ auto should_continue_comparing_files = [&]() {
+ if (read_file1) {
+ auto can_read_file1_line = file1->can_read_line();
+ if (can_read_file1_line.is_error() || !can_read_file1_line.value())
+ return false;
+ }
+ if (read_file2) {
+ auto can_read_file2_line = file2->can_read_line();
+ if (can_read_file2_line.is_error() || !can_read_file2_line.value())
+ return false;
+ }
+ return true;
+ };
- while (file1->can_read_line() && file2->can_read_line()) {
+ while (should_continue_comparing_files()) {
if (read_file1)
- file1_line = file1->read_line();
+ file1_line = TRY(file1->read_line(buffer));
if (read_file2)
- file2_line = file2->read_line();
+ file2_line = TRY(file2->read_line(buffer));
int cmp_result = cmp(file1_line, file2_line);
- if (!cmp_result) {
+ if (cmp_result == 0) {
++col3_count;
read_file1 = read_file2 = true;
if (!suppress_col3)
@@ -151,6 +167,19 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
outln(col2_fmt, file2_line);
}
+ auto process_remaining = [&](String const& fmt, auto& file, int& count, bool print) {
+ while (true) {
+ auto can_read_result = file->can_read_line();
+ if (can_read_result.is_error() || !can_read_result.value())
+ break;
+ ++count;
+ auto line = file->read_line(buffer);
+ if (line.is_error())
+ break;
+ if (print)
+ outln(fmt, line.value());
+ }
+ };
process_remaining(col1_fmt, file1, col1_count, !suppress_col1);
process_remaining(col2_fmt, file2, col2_count, !suppress_col2);