From f552c26c793a4d8dca6af6a6d07f080da0949aa8 Mon Sep 17 00:00:00 2001 From: Mustafa Quraish Date: Wed, 15 Sep 2021 22:28:04 -0400 Subject: [PATCH] Utilities: Add a basic `diff` utility --- Userland/Utilities/CMakeLists.txt | 3 +- Userland/Utilities/diff.cpp | 51 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 Userland/Utilities/diff.cpp diff --git a/Userland/Utilities/CMakeLists.txt b/Userland/Utilities/CMakeLists.txt index 20e7a0b20c..82c2f340c8 100644 --- a/Userland/Utilities/CMakeLists.txt +++ b/Userland/Utilities/CMakeLists.txt @@ -1,7 +1,7 @@ file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp") list(APPEND SPECIAL_TARGETS test install) list(APPEND REQUIRED_TARGETS - arp base64 basename cat chmod chown clear comm cp cut date dd df dirname dmesg du echo env expr false fgrep + arp base64 basename cat chmod chown clear comm cp cut date dd df diff dirname dmesg du echo env expr false fgrep file find grep groups head host hostname id ifconfig kill killall ln ls mkdir mount mv nproc pgrep pidof ping pmap ps readlink realpath reboot rm rmdir seq shutdown sleep sort stat stty su tail test touch tr true umount uname uniq uptime w wc which whoami xargs yes less @@ -59,6 +59,7 @@ target_link_libraries(chres LibGUI) target_link_libraries(cksum LibCrypto) target_link_libraries(config LibConfig) target_link_libraries(copy LibGUI) +target_link_libraries(diff LibDiff) target_link_libraries(disasm LibX86) target_link_libraries(expr LibRegex) target_link_libraries(file LibGfx LibIPC LibCompress) diff --git a/Userland/Utilities/diff.cpp b/Userland/Utilities/diff.cpp new file mode 100644 index 0000000000..d6fa356bf1 --- /dev/null +++ b/Userland/Utilities/diff.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021, Mustafa Quraish + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + if (pledge("stdio rpath", nullptr) < 0) { + perror("pledge"); + return 1; + } + + Core::ArgsParser parser; + char const* filename1; + char const* filename2; + + parser.add_positional_argument(filename1, "First file to compare", "file1", Core::ArgsParser::Required::Yes); + parser.add_positional_argument(filename2, "Second file to compare", "file2", Core::ArgsParser::Required::Yes); + parser.parse(argc, argv, Core::ArgsParser::FailureBehavior::PrintUsageAndExit); + + auto file1 = Core::File::construct(filename1); + if (!file1->open(Core::OpenMode::ReadOnly)) { + warnln("Error: Cannot open {}: {}", filename1, file1->error_string()); + return 1; + } + auto file2 = Core::File::construct(filename2); + if (!file2->open(Core::OpenMode::ReadOnly)) { + warnln("Error: Cannot open {}: {}", filename2, file2->error_string()); + return 1; + } + + auto hunks = Diff::from_text(file1->read_all(), file2->read_all()); + for (const auto& hunk : hunks) { + outln("Hunk: {}, {}", hunk.original_start_line, hunk.target_start_line); + for (const auto& line : hunk.removed_lines) { + outln("\033[31;1m< {}\033[0m", line); + } + if (hunk.added_lines.size() > 0 && hunk.removed_lines.size() > 0) + outln("---"); + for (const auto& line : hunk.added_lines) + outln("\033[32;1m> {}\033[0m", line); + } + + return hunks.is_empty() ? 0 : 1; +}