mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 02:17:35 +00:00
comm: Port to Core::Stream
This commit is contained in:
parent
8ed5403d8c
commit
6763e1bd60
1 changed files with 64 additions and 35 deletions
|
@ -1,11 +1,13 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, the SerenityOS developers.
|
* Copyright (c) 2021, the SerenityOS developers.
|
||||||
|
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <LibCore/ArgsParser.h>
|
#include <LibCore/ArgsParser.h>
|
||||||
#include <LibCore/File.h>
|
#include <LibCore/File.h>
|
||||||
|
#include <LibCore/Stream.h>
|
||||||
#include <LibCore/System.h>
|
#include <LibCore/System.h>
|
||||||
#include <LibMain/Main.h>
|
#include <LibMain/Main.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -20,7 +22,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
{
|
{
|
||||||
TRY(Core::System::pledge("stdio rpath"));
|
TRY(Core::System::pledge("stdio rpath"));
|
||||||
|
|
||||||
String file1_path, file2_path;
|
String file1_path;
|
||||||
|
String file2_path;
|
||||||
bool suppress_col1 { false };
|
bool suppress_col1 { false };
|
||||||
bool suppress_col2 { false };
|
bool suppress_col2 { false };
|
||||||
bool suppress_col3 { false };
|
bool suppress_col3 { false };
|
||||||
|
@ -47,7 +50,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool print_color = isatty(STDOUT_FILENO);
|
bool print_color = TRY(Core::System::isatty(STDOUT_FILENO));
|
||||||
if (color)
|
if (color)
|
||||||
print_color = true;
|
print_color = true;
|
||||||
else if (no_color)
|
else if (no_color)
|
||||||
|
@ -58,31 +61,38 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto process_file = [](String const& path, auto& file, int file_number) {
|
auto open_file = [](String const& path, auto& file, int file_number) {
|
||||||
if (path == "-") {
|
auto file_or_error = Core::Stream::File::open_file_or_standard_stream(path, Core::Stream::OpenMode::Read);
|
||||||
file = Core::File::standard_input();
|
if (file_or_error.is_error()) {
|
||||||
} else {
|
warnln("Failed to open file{} '{}': {}", file_number, path, file_or_error.error());
|
||||||
auto file_or_error = Core::File::open(path, Core::OpenMode::ReadOnly);
|
return false;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
RefPtr<Core::File> file1, file2;
|
OwnPtr<Core::Stream::BufferedFile> file1;
|
||||||
if (!(process_file(file1_path, file1, 1) && process_file(file2_path, file2, 2)))
|
OwnPtr<Core::Stream::BufferedFile> file2;
|
||||||
|
if (!(open_file(file1_path, file1, 1) && open_file(file2_path, file2, 2)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
char tab { '\t' };
|
char tab { '\t' };
|
||||||
size_t tab_count { 0 };
|
size_t tab_count { 0 };
|
||||||
String col1_fmt, col2_fmt, col3_fmt;
|
String col1_fmt;
|
||||||
|
String col2_fmt;
|
||||||
|
String col3_fmt;
|
||||||
if (!suppress_col1)
|
if (!suppress_col1)
|
||||||
col1_fmt = String::formatted("{}{}", String::repeated(tab, tab_count++), print_color ? COL1_COLOR : "{}");
|
col1_fmt = String::formatted("{}{}", String::repeated(tab, tab_count++), print_color ? COL1_COLOR : "{}");
|
||||||
if (!suppress_col2)
|
if (!suppress_col2)
|
||||||
|
@ -93,17 +103,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
auto cmp = [&](String const& str1, String const& str2) {
|
auto cmp = [&](String const& str1, String const& str2) {
|
||||||
if (case_insensitive)
|
if (case_insensitive)
|
||||||
return strcasecmp(str1.characters(), str2.characters());
|
return strcasecmp(str1.characters(), str2.characters());
|
||||||
else
|
return strcmp(str1.characters(), str2.characters());
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool read_file1 { true };
|
bool read_file1 { true };
|
||||||
|
@ -111,17 +111,33 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
int col1_count { 0 };
|
int col1_count { 0 };
|
||||||
int col2_count { 0 };
|
int col2_count { 0 };
|
||||||
int col3_count { 0 };
|
int col3_count { 0 };
|
||||||
String file1_line, file2_line;
|
String file1_line;
|
||||||
|
String file2_line;
|
||||||
|
Array<u8, PAGE_SIZE> buffer;
|
||||||
|
|
||||||
while (file1->can_read_line() && file2->can_read_line()) {
|
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 (should_continue_comparing_files()) {
|
||||||
if (read_file1)
|
if (read_file1)
|
||||||
file1_line = file1->read_line();
|
file1_line = TRY(file1->read_line(buffer));
|
||||||
if (read_file2)
|
if (read_file2)
|
||||||
file2_line = file2->read_line();
|
file2_line = TRY(file2->read_line(buffer));
|
||||||
|
|
||||||
int cmp_result = cmp(file1_line, file2_line);
|
int cmp_result = cmp(file1_line, file2_line);
|
||||||
|
|
||||||
if (!cmp_result) {
|
if (cmp_result == 0) {
|
||||||
++col3_count;
|
++col3_count;
|
||||||
read_file1 = read_file2 = true;
|
read_file1 = read_file2 = true;
|
||||||
if (!suppress_col3)
|
if (!suppress_col3)
|
||||||
|
@ -151,6 +167,19 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
outln(col2_fmt, file2_line);
|
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(col1_fmt, file1, col1_count, !suppress_col1);
|
||||||
process_remaining(col2_fmt, file2, col2_count, !suppress_col2);
|
process_remaining(col2_fmt, file2, col2_count, !suppress_col2);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue