Skip to content

Commit

Permalink
released 4.0.3
Browse files Browse the repository at this point in the history
add --delay=DELAY option to specify a default query TUI delay e.g. in the .ugrep config file with delay=DELAY; fix a GNU grep option -m compatibility issue
  • Loading branch information
genivia-inc committed Aug 24, 2023
1 parent 196320f commit 15a1b15
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 76 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,8 @@ The configuration is written to standard output when `FILE` is a `-`.
--heading. See also options --confirm and --view.
--no-confirm
Do not confirm actions in -Q query mode. The default is confirm.
--delay=DELAY
Set the default -Q response delay (nonzero). Default is 5.
--view[=COMMAND]
Use COMMAND to view/edit a file in query mode when pressing CTRL-Y.

Expand Down Expand Up @@ -4147,6 +4149,9 @@ in markdown:
under each directory, recursively, following symbolic links. This
is equivalent to the -R option.

--delay=DELAY
Set the default -Q response delay (nonzero). Default is 5.

--depth=[MIN,][MAX], -1, -2, -3, ... -9, --10, --11, --12, ...
Restrict recursive searches from MIN to MAX directory levels deep,
where -1 (--depth=1) searches the specified path without recursing
Expand Down Expand Up @@ -5354,7 +5359,7 @@ in markdown:



ugrep 4.0.2 August 22, 2023 UGREP(1)
ugrep 4.0.3 August 24, 2023 UGREP(1)

🔝 [Back to table of contents](#toc)

Expand Down
Binary file modified bin/win32/ugrep.exe
Binary file not shown.
Binary file modified bin/win64/ugrep.exe
Binary file not shown.
22 changes: 19 additions & 3 deletions include/reflex/linematcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ class LineMatcher : public AbstractMatcher {
const Input& input = Input(), ///< input character sequence for this matcher
const char *opt = NULL) ///< option string of the form `(A|N|T(=[[:digit:]])?|;)*`
:
AbstractMatcher(input, opt)
AbstractMatcher(input, opt),
inc_(false)
{ }
/// Copy constructor.
LineMatcher(const LineMatcher& matcher) ///< matcher to copy
:
AbstractMatcher(matcher.in, matcher.opt_)
AbstractMatcher(matcher.in, matcher.opt_),
inc_(false)
{ }
/// Delete matcher.
virtual ~LineMatcher()
Expand All @@ -63,6 +65,7 @@ class LineMatcher : public AbstractMatcher {
LineMatcher& operator=(const LineMatcher& matcher) ///< matcher to copy
{
AbstractMatcher::operator=(matcher);
inc_ = matcher.inc_;
return *this;
}
/// Polymorphic cloning.
Expand All @@ -71,7 +74,12 @@ class LineMatcher : public AbstractMatcher {
return new LineMatcher(*this);
}
/// Reset this matcher's state to the initial state and when assigned new input.
using AbstractMatcher::reset;
virtual void reset(const char *opt = NULL)
{
DBGLOG("LineMatcher::reset()");
AbstractMatcher::reset(opt);
inc_ = false;
}
/// Returns a pair <text(),size() for any n
virtual std::pair<const char*,size_t> operator[](size_t) ///< ignored
/// @returns pair.
Expand All @@ -98,13 +106,16 @@ class LineMatcher : public AbstractMatcher {
{
DBGLOG("BEGIN LineMatcher::match(%d)", method);
reset_text();
got_ = '\n';
find:
pos_ += inc_;
txt_ = buf_ + pos_;
cur_ = txt_ - buf_;
len_ = 0;
cap_ = !at_end();
if (cap_)
{
inc_ = false;
const char *end = eol(true);
if (end == txt_)
return cap_ = 0;
Expand All @@ -119,7 +130,11 @@ class LineMatcher : public AbstractMatcher {
n = len_ - (*--end == '\n');
// option A includes the terminating \n in the match, when present
if (!opt_.A)
{
inc_ = (len_ > n);
len_ = n;
pos_ = cur_ + n;
}
// option N also finds empty lines
if (n == 0 && !opt_.N)
goto find;
Expand All @@ -139,6 +154,7 @@ class LineMatcher : public AbstractMatcher {
}
return cap_;
}
bool inc_; ///< true if next find() should skip over \n
};

} // namespace reflex
Expand Down
5 changes: 4 additions & 1 deletion man/ugrep.1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.TH UGREP "1" "August 22, 2023" "ugrep 4.0.2" "User Commands"
.TH UGREP "1" "August 24, 2023" "ugrep 4.0.3" "User Commands"
.SH NAME
\fBugrep\fR, \fBug\fR -- file pattern searcher
.SH SYNOPSIS
Expand Down Expand Up @@ -271,6 +271,9 @@ option. If ACTION is `dereference\-recurse', read all files under
each directory, recursively, following symbolic links. This is
equivalent to the \fB\-R\fR option.
.TP
\fB\-\-delay\fR=\fIDELAY\fR
Set the default \fB\-Q\fR response delay (nonzero). Default is 5.
.TP
\fB\-\-depth\fR=[\fIMIN\fR,][\fIMAX\fR], \fB\-1\fR, \fB\-2\fR, \fB\-3\fR, ... \fB\-9\fR, \fB\-\-10\fR, \fB\-\-11\fR, \fB\-\-12\fR, ...
Restrict recursive searches from MIN to MAX directory levels deep,
where \fB\-1\fR (\fB\-\-depth\fR=1) searches the specified path without recursing
Expand Down
1 change: 1 addition & 0 deletions src/flag.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ extern Action flag_devices_action;
extern Action flag_directories_action;
extern size_t flag_after_context;
extern size_t flag_before_context;
extern size_t flag_delay;
extern size_t flag_exclude_iglob_size;
extern size_t flag_exclude_iglob_dir_size;
extern size_t flag_fuzzy;
Expand Down
2 changes: 1 addition & 1 deletion src/query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
#define QUERY_BUFFER_SIZE 16384
#endif

// default -Q response to keyboard input delay is 0.5s, in steps of 100ms
// default -Q response to keyboard input delay is ~0.5s, in steps of 100ms
#ifndef DEFAULT_QUERY_DELAY
#define DEFAULT_QUERY_DELAY 5
#endif
Expand Down
118 changes: 49 additions & 69 deletions src/ugrep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ Action flag_devices_action = Action::UNSP;
Action flag_directories_action = Action::UNSP;
size_t flag_after_context = 0;
size_t flag_before_context = 0;
size_t flag_delay = DEFAULT_QUERY_DELAY;
size_t flag_exclude_iglob_size = 0;
size_t flag_exclude_iglob_dir_size = 0;
size_t flag_fuzzy = 0;
Expand Down Expand Up @@ -2506,7 +2507,7 @@ struct Grep {
}
};

// extend event AnyLineGrepHandler to output specific context lines for -ABC
// extend event AnyLineGrepHandler to output specific context lines for -ABC without -v
struct ContextGrepHandler : public AnyLineGrepHandler {

// context state to track context lines before and after a match
Expand Down Expand Up @@ -2628,7 +2629,7 @@ struct Grep {
{
if (binary)
{
grep.out.dump.hex(flag_invert_match ? Output::Dump::HEX_CONTEXT_LINE : Output::Dump::HEX_LINE, grep.restline_last, grep.restline_data, grep.restline_size);
grep.out.dump.hex(Output::Dump::HEX_LINE, grep.restline_last, grep.restline_data, grep.restline_size);
}
else
{
Expand All @@ -2639,7 +2640,7 @@ struct Grep {
grep.restline_size -= lf_only;
if (grep.restline_size > 0)
{
grep.out.str(flag_invert_match ? color_cx : color_sl);
grep.out.str(color_sl);
grep.out.str(grep.restline_data, grep.restline_size);
grep.out.str(color_off);
}
Expand All @@ -2661,30 +2662,10 @@ struct Grep {
if (flag_max_line > 0 && lineno > flag_max_line)
break;

if (matches == 0 && flag_invert_match)
{
// --max-files: max reached?
if (!Stats::found_part())
{
stop = true;
break;
}
}

// --max-count: max number of matches reached?
if (flag_invert_match && flag_max_count > 0 && matches >= flag_max_count)
{
stop = true;
break;
}

// output blocked?
if (grep.out.eof)
break;

if (flag_invert_match)
++matches;

if (flag_with_hex)
binary = false;

Expand Down Expand Up @@ -2993,11 +2974,8 @@ struct Grep {
}

// --max-count: max number of matches reached?
if (flag_invert_match && flag_max_count > 0 && matches >= flag_max_count)
{
stop = true;
if (flag_max_count > 0 && matches >= flag_max_count)
break;
}

// output blocked?
if (grep.out.eof)
Expand Down Expand Up @@ -4457,9 +4435,14 @@ static void save_config()
fprintf(file, "# Enable hyperlinks in color output\nhyperlink\n\n");
else if (flag_hyperlink != NULL)
fprintf(file, "# Enable hyperlinks in color output\nhyperlink=%s\n\n", flag_hyperlink);
fprintf(file, "# Enable query UI confirmation prompts, default: confirm\n%s\n\n", flag_confirm ? "confirm" : "no-confirm");
fprintf(file, "# Enable query TUI confirmation prompts, default: confirm\n%s\n\n", flag_confirm ? "confirm" : "no-confirm");
fprintf(file, "# Default query TUI response delay (nonzero) in units of 100ms, default: delay=5\n");
if (flag_delay == DEFAULT_QUERY_DELAY)
fprintf(file, "# delay=5\n\n");
else
fprintf(file, "delay=%zu\n\n", flag_delay);

fprintf(file, "# Enable query UI file viewing command with CTRL-Y or F2, default: view\n");
fprintf(file, "# Enable query TUI file viewing command with CTRL-Y or F2, default: view\n");
if (flag_view != NULL && *flag_view == '\0')
fprintf(file, "view\n\n");
else if (flag_view != NULL)
Expand Down Expand Up @@ -4529,7 +4512,11 @@ static void save_config()
fprintf(file, "# Enable case-insensitive search, default: no-ignore-case\n%s\n\n", flag_ignore_case.is_undefined() ? "# no-ignore-case" : flag_ignore_case ? "ignore-case" : "no-ignore-case");
fprintf(file, "# Enable smart case, default: no-smart-case\n%s\n\n", flag_smart_case.is_undefined() ? "# no-smart-case" : flag_smart_case ? "smart-case" : "no-smart-case");
fprintf(file, "# Enable empty pattern matches, default: no-empty\n%s\n\n", flag_empty.is_undefined() ? "# no-empty" : flag_empty ? "empty" : "no-empty");
fprintf(file, "# Force option -c (--count) to return non-zero matches with --min-count=1, default: --min-count=0\nmin-count=%zu\n\n", flag_min_count);
fprintf(file, "# Force option -c (--count) to return non-zero matches with --min-count=1, default: --min-count=0\n");
if (flag_min_count == 0)
fprintf(file, "# min-count=0\n\n");
else
fprintf(file, "min-count=%zu\n\n", flag_min_count);

fprintf(file, "### SEARCH TARGETS ###\n\n");

Expand Down Expand Up @@ -4702,6 +4689,8 @@ void options(std::list<std::pair<CNF::PATTERN,const char*>>& pattern_args, int a
case 'd':
if (strcmp(arg, "decompress") == 0)
flag_decompress = true;
else if (strncmp(arg, "delay=", 6) == 0)
flag_delay = strtopos(arg + 6, "invalid argument --delay=");
else if (strncmp(arg, "depth=", 6) == 0)
strtopos2(arg + 6, flag_min_depth, flag_max_depth, "invalid argument --depth=");
else if (strcmp(arg, "dereference") == 0)
Expand All @@ -4721,7 +4710,7 @@ void options(std::list<std::pair<CNF::PATTERN,const char*>>& pattern_args, int a
strcmp(arg, "directories") == 0)
usage("missing argument for --", arg);
else
usage("invalid option --", arg, "--decompress, --depth, --dereference, --dereference-files, --dereference-recursive, --devices, --directories or --dotall");
usage("invalid option --", arg, "--decompress, --delay, --depth, --dereference, --dereference-files, --dereference-recursive, --devices, --directories or --dotall");
break;

case 'e':
Expand Down Expand Up @@ -5056,7 +5045,7 @@ void options(std::list<std::pair<CNF::PATTERN,const char*>>& pattern_args, int a

case 'q':
if (strcmp(arg, "query") == 0)
flag_query = DEFAULT_QUERY_DELAY;
flag_query = flag_delay;
else if (strncmp(arg, "query=", 6) == 0)
flag_query = strtopos(arg + 6, "invalid argument --query=");
else if (strcmp(arg, "quiet") == 0)
Expand Down Expand Up @@ -5414,7 +5403,7 @@ void options(std::list<std::pair<CNF::PATTERN,const char*>>& pattern_args, int a
}
else
{
flag_query = DEFAULT_QUERY_DELAY;
flag_query = flag_delay;
}
break;

Expand Down Expand Up @@ -7529,8 +7518,8 @@ void ugrep()
if (flag_invert_match || flag_any_line)
flag_only_matching = flag_ungroup = false;

// --match: when matching everything disable -ABC unless -o
if (flag_match && !flag_only_matching)
// --match: when matching everything disable -ABC unless -o or -x
if (flag_match && !flag_only_matching && !flag_line_regexp)
flag_after_context = flag_before_context = 0;

// -y: disable -ABC
Expand Down Expand Up @@ -9398,9 +9387,8 @@ void Grep::search(const char *pathname, uint16_t cost)

#if WITH_SKIP_NEWLINE // this is only valid if no \n is part of the patterns
// if the match does not span more than one line, then skip to end of the line (we count matching lines)
if (matcher->lines() == 1)
if (!matcher->skip('\n'))
break;
if (!matcher->at_bol())
matcher->skip('\n');
#endif
}
}
Expand Down Expand Up @@ -10457,7 +10445,7 @@ void Grep::search(const char *pathname, uint16_t cost)
#if WITH_SKIP_NEWLINE // this is only valid if no \n is part of the patterns
// no -u and no colors: if the match does not span more than one line, then skip to end of the line
if (!flag_ungroup && !colorize)
if (matcher->lines() == 1)
if (!matcher->at_bol())
if (!matcher->skip('\n'))
break;
#endif
Expand Down Expand Up @@ -11296,32 +11284,6 @@ void Grep::search(const char *pathname, uint16_t cost)
continue;
}

// get the lines before the matched line
context = matcher->before();

if (context.len > 0)
context_handler(*matcher, context.buf, context.len, context.num);

if (binfile || (binary && !flag_hex && !flag_with_hex))
{
if (flag_binary_without_match)
{
matches = 0;
}
else
{
out.binary_file_matches(pathname, partname);
matches = 1;
}

if (flag_files && matchers != NULL && out.holding())
continue;

goto done_search;
}

context_handler.output_before_context();

// --range: max line exceeded?
if (flag_max_line > 0 && current_lineno > flag_max_line)
break;
Expand All @@ -11337,14 +11299,30 @@ void Grep::search(const char *pathname, uint16_t cost)
goto exit_search;
}

// --max-count: max number of matches reached?
if (flag_max_count > 0 && matches > flag_max_count)
break;

// output blocked?
if (out.eof)
goto exit_search;

// --max-count: max number of matches reached?
if (flag_max_count > 0 && matches > flag_max_count)
{
if (flag_after_context == 0 || matches > flag_max_count + 1)
break;

// one more iteration to get the after context displayed
lineno = current_lineno;
context_handler.set_after_lineno(lineno + matcher->lines());
continue;
}

// get the lines before the matched line
context = matcher->before();

if (context.len > 0)
context_handler(*matcher, context.buf, context.len, context.num);

context_handler.output_before_context();

binary = flag_hex || (flag_with_hex && is_binary(bol, eol - bol));

if (binfile || (binary && !flag_hex && !flag_with_hex))
Expand Down Expand Up @@ -12743,6 +12721,8 @@ void help(std::ostream& out)
option. If ACTION is `dereference-recurse', read all files under\n\
each directory, recursively, following symbolic links. This is\n\
equivalent to the -R option.\n\
--delay=DELAY\n\
Set the default -Q response delay (nonzero). Default is 5.\n\
--depth=[MIN,][MAX], -1, -2, -3, ... -9, --10, --11, --12, ...\n\
Restrict recursive searches from MIN to MAX directory levels deep,\n\
where -1 (--depth=1) searches the specified path without recursing\n\
Expand Down
2 changes: 1 addition & 1 deletion src/ugrep.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
#define UGREP_HPP

// ugrep version
#define UGREP_VERSION "4.0.2"
#define UGREP_VERSION "4.0.3"

// disable mmap because mmap is almost always slower than the file reading speed improvements since 3.0.0
#define WITH_NO_MMAP
Expand Down

0 comments on commit 15a1b15

Please sign in to comment.