Utilities: Replace fgrep with grep --fixed-strings

This commit is contained in:
Peter Elliott 2022-10-25 22:11:34 -06:00 committed by Jelle Raaijmakers
parent d844829de4
commit d50de8e4ef
4 changed files with 28 additions and 34 deletions

View file

@ -5,13 +5,14 @@ grep
## Synopsis
```sh
$ grep [--recursive] [--extended-regexp] [--regexp Pattern] [-i] [--line-numbers] [--invert-match] [--quiet] [--no-messages] [--binary-mode ] [--text] [-I] [--color WHEN] [--count] [file...]
$ grep [--recursive] [--extended-regexp] [--fixed-strings] [--regexp Pattern] [-i] [--line-numbers] [--invert-match] [--quiet] [--no-messages] [--binary-mode ] [--text] [-I] [--color WHEN] [--count] [file...]
```
## Options:
* `-r`, `--recursive`: Recursively scan files
* `-E`, `--extended-regexp`: Extended regular expressions
* `-F`, `--fixed-strings`: Treat pattern as a string, not a regexp
* `-e Pattern`, `--regexp Pattern`: Pattern
* `-i`: Make matches case-insensitive
* `-n`, `--line-numbers`: Output line-numbers

View file

@ -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 diff 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
file find grep groups head host hostname id ifconfig kill killall ln logout ls mkdir mount mv nproc
pgrep pidof ping pkill pmap ps readlink realpath reboot rm rmdir route seq shutdown sleep sort stat stty su tail test
touch tr true umount uname uniq uptime w wc which whoami xargs yes
@ -65,6 +65,7 @@ if (ENABLE_JAKT)
endif()
install(CODE "file(CREATE_LINK grep ${CMAKE_INSTALL_PREFIX}/bin/egrep SYMBOLIC)")
install(CODE "file(CREATE_LINK grep ${CMAKE_INSTALL_PREFIX}/bin/fgrep SYMBOLIC)")
install(CODE "file(CREATE_LINK grep ${CMAKE_INSTALL_PREFIX}/bin/rgrep SYMBOLIC)")
target_link_libraries(abench PRIVATE LibAudio)

View file

@ -1,30 +0,0 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Assertions.h>
#include <AK/DeprecatedString.h>
#include <AK/Format.h>
#include <LibCore/System.h>
#include <LibMain/Main.h>
#include <stdio.h>
ErrorOr<int> serenity_main(Main::Arguments arguments)
{
if (arguments.strings.size() < 2) {
warnln("usage: fgrep <str>");
return 1;
}
for (;;) {
char buffer[4096];
fgets(buffer, sizeof(buffer), stdin);
auto str = StringView { buffer, strlen(buffer) };
if (str.contains(arguments.strings[1]))
TRY(Core::System::write(1, str.bytes()));
if (feof(stdin))
return 0;
VERIFY(str.to_deprecated_string().characters());
}
}

View file

@ -8,6 +8,7 @@
#include <AK/DeprecatedString.h>
#include <AK/LexicalPath.h>
#include <AK/ScopeGuard.h>
#include <AK/StringBuilder.h>
#include <AK/Vector.h>
#include <LibCore/ArgsParser.h>
#include <LibCore/DirIterator.h>
@ -33,6 +34,21 @@ void fail(StringView format, Ts... args)
abort();
}
constexpr StringView ere_special_characters = ".^$*+?()[{\\|"sv;
constexpr StringView basic_special_characters = ".^$*[\\"sv;
static DeprecatedString escape_characters(StringView string, StringView characters)
{
StringBuilder builder;
for (auto ch : string) {
if (characters.contains(ch))
builder.append('\\');
builder.append(ch);
}
return builder.to_deprecated_string();
}
ErrorOr<int> serenity_main(Main::Arguments args)
{
TRY(Core::System::pledge("stdio rpath"));
@ -43,6 +59,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
bool recursive = (program_name == "rgrep"sv);
bool use_ere = (program_name == "egrep"sv);
bool fixed_strings = (program_name == "fgrep"sv);
Vector<DeprecatedString> patterns;
BinaryFileMode binary_mode { BinaryFileMode::Binary };
bool case_insensitive = false;
@ -58,6 +75,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
Core::ArgsParser args_parser;
args_parser.add_option(recursive, "Recursively scan files", "recursive", 'r');
args_parser.add_option(use_ere, "Extended regular expressions", "extended-regexp", 'E');
args_parser.add_option(fixed_strings, "Treat pattern as a string, not a regexp", "fixed-strings", 'F');
args_parser.add_option(Core::ArgsParser::Option {
.argument_mode = Core::ArgsParser::OptionArgumentMode::Required,
.help_string = "Pattern",
@ -144,6 +162,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
auto grep_logic = [&](auto&& regular_expressions) {
for (auto& re : regular_expressions) {
if (re.parser_result.error != regex::Error::NoError) {
warnln("regex parse error: {}", regex::get_error_string(re.parser_result.error));
return 1;
}
}
@ -296,14 +315,17 @@ ErrorOr<int> serenity_main(Main::Arguments args)
if (use_ere) {
Vector<Regex<PosixExtended>> regular_expressions;
for (auto pattern : patterns) {
regular_expressions.append(Regex<PosixExtended>(pattern, options));
auto escaped_pattern = (fixed_strings) ? escape_characters(pattern, ere_special_characters) : pattern;
regular_expressions.append(Regex<PosixExtended>(escaped_pattern, options));
}
return grep_logic(regular_expressions);
}
Vector<Regex<PosixBasic>> regular_expressions;
for (auto pattern : patterns) {
regular_expressions.append(Regex<PosixBasic>(pattern, options));
auto escaped_pattern = (fixed_strings) ? escape_characters(pattern, basic_special_characters) : pattern;
dbgln("'{}'", escaped_pattern);
regular_expressions.append(Regex<PosixBasic>(escaped_pattern, options));
}
return grep_logic(regular_expressions);
}