Skip to content

Commit

Permalink
released 3.7.6
Browse files Browse the repository at this point in the history
New option --min-count
  • Loading branch information
genivia-inc committed Mar 15, 2022
1 parent 4bc8a93 commit 59392f4
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 28 deletions.
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3516,8 +3516,10 @@ Same, but in this case select `<script>` `src` URLs when referencing `http` and
levels deep. Enables -R if -R or -r is not specified.
-K FIRST[,LAST], --range=FIRST[,LAST]
Start searching at line FIRST, stop at line LAST when specified.
-m NUM, --max-count=NUM
Stop reading the input after NUM matches for each file processed.
-m [MIN,][MAX], --min-count=MIN, --max-count=MAX
Stop reading the input after MAX matches in each input file when
specified. Require at least MIN matches when specified, for
options -c, -l, -L and -q.
--max-files=NUM
Restrict the number of files matched to NUM. Note that --sort or
-J1 may be specified to produce replicable results. If --sort is
Expand Down Expand Up @@ -4233,8 +4235,10 @@ in markdown:
Every file on the search path is read, making searches poten-
tially more expensive.

-m NUM, --max-count=NUM
Stop reading the input after NUM matches in each input file.
-m [MIN,][MAX], --min-count=MIN, --max-count=MAX
Stop reading the input after MAX matches in each input file when
specified. Require at least MIN matches when specified, for
options -c, -l, -L and -q.

--match
Match all input. Same as specifying an empty pattern to search.
Expand Down Expand Up @@ -5094,7 +5098,7 @@ in markdown:



ugrep 3.7.5 March 13, 2022 UGREP(1)
ugrep 3.7.6 March 15, 2022 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.
8 changes: 5 additions & 3 deletions man/ugrep.1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.TH UGREP "1" "March 13, 2022" "ugrep 3.7.5" "User Commands"
.TH UGREP "1" "March 15, 2022" "ugrep 3.7.6" "User Commands"
.SH NAME
\fBugrep\fR, \fBug\fR -- file pattern searcher
.SH SYNOPSIS
Expand Down Expand Up @@ -485,8 +485,10 @@ MAGIC signatures. This option may be repeated and may be combined
with options \fB\-O\fR and \fB\-t\fR to expand the search. Every file on the
search path is read, making searches potentially more expensive.
.TP
\fB\-m\fR \fINUM\fR, \fB\-\-max\-count\fR=\fINUM\fR
Stop reading the input after NUM matches in each input file.
\fB\-m\fR [\fIMIN\fR,][\fIMAX\fR], \fB\-\-min\-count\fR=\fIMIN\fR, \fB\-\-max\-count\fR=\fIMAX\fR
Stop reading the input after MAX matches in each input file when
specified. Require at least MIN matches when specified, for
options \fB\-c\fR, \fB\-l\fR, \fB\-L\fR and \fB\-q\fR.
.TP
\fB\-\-match\fR
Match all input. Same as specifying an empty pattern to search.
Expand Down
1 change: 1 addition & 0 deletions src/flag.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ extern size_t flag_max_depth;
extern size_t flag_max_files;
extern size_t flag_max_line;
extern size_t flag_max_mmap;
extern size_t flag_min_count;
extern size_t flag_min_depth;
extern size_t flag_min_line;
extern size_t flag_min_magic;
Expand Down
65 changes: 46 additions & 19 deletions src/ugrep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ size_t flag_max_depth = 0;
size_t flag_max_files = 0;
size_t flag_max_line = 0;
size_t flag_max_mmap = DEFAULT_MAX_MMAP_SIZE;
size_t flag_min_count = 0;
size_t flag_min_depth = 0;
size_t flag_min_line = 0;
size_t flag_min_magic = 1;
Expand Down Expand Up @@ -4555,6 +4556,8 @@ void options(std::list<std::pair<CNF::PATTERN,const char*>>& pattern_args, int a
flag_max_count = strtopos(arg + 10, "invalid argument --max-count=");
else if (strncmp(arg, "max-files=", 10) == 0)
flag_max_files = strtopos(arg + 10, "invalid argument --max-files=");
else if (strncmp(arg, "min-count=", 10) == 0)
flag_min_count = strtopos(arg + 10, "invalid argument --min-count=");
else if (strncmp(arg, "min-steal=", 10) == 0)
flag_min_steal = strtopos(arg + 10, "invalid argument --min-steal=");
else if (strcmp(arg, "mmap") == 0)
Expand All @@ -4566,7 +4569,7 @@ void options(std::list<std::pair<CNF::PATTERN,const char*>>& pattern_args, int a
else if (strcmp(arg, "max-count") == 0 || strcmp(arg, "max-files") == 0)
usage("missing argument for --", arg);
else
usage("invalid option --", arg, "--match, --max-count, --max-files, --mmap or --messages");
usage("invalid option --", arg, "--match, --max-count, --max-files, --min-count, --mmap or --messages");
break;

case 'n':
Expand Down Expand Up @@ -4973,9 +4976,9 @@ void options(std::list<std::pair<CNF::PATTERN,const char*>>& pattern_args, int a
case 'm':
++arg;
if (*arg)
flag_max_count = strtopos(&arg[*arg == '='], "invalid argument -m=");
strtopos2(&arg[*arg == '='], flag_min_count, flag_max_count, "invalid argument -m=", true);
else if (++i < argc)
flag_max_count = strtopos(argv[i], "invalid argument -m=");
strtopos2(argv[i], flag_min_count, flag_max_count, "invalid argument -m=", true);
else
usage("missing NUM argument for option -m");
is_grouped = false;
Expand Down Expand Up @@ -5880,6 +5883,10 @@ void init(int argc, const char **argv)
if (flag_files && flag_invert_match)
abort("-v is not permitted with --files, invert the Boolean query instead");

// --min-count is not permitted with options other than -q, -l, -L and -c
if (flag_min_count > 0 && !flag_quiet && !flag_files_with_matches && !flag_files_without_match && !flag_count)
abort("--min-count is not permitted without -c, -l, -L or -q");

#ifdef HAVE_STATVFS

// --exclude-fs: add file system ids to exclude
Expand Down Expand Up @@ -8301,17 +8308,21 @@ void Grep::search(const char *pathname)
{
// option -q, -l, or -L

// -v with empty pattern matches nothing
if (flag_empty && flag_invert_match)
// --match and -v matches nothing
if (flag_match && flag_invert_match)
goto exit_search;

// --format: whether to out.acquire() early before Stats::found_part()
bool acquire = flag_format != NULL && (flag_format_open != NULL || flag_format_close != NULL);

size_t lineno = 0;

while (matcher->find())
{
size_t current_lineno = matcher->lineno();

// --range: max line exceeded?
if (flag_max_line > 0 && matcher->lineno() > flag_max_line)
if (flag_max_line > 0 && current_lineno > flag_max_line)
break;

if (matchers != NULL)
Expand All @@ -8324,10 +8335,20 @@ void Grep::search(const char *pathname)
continue;
}

matches = 1;
break;
if (flag_min_count == 0 || flag_ungroup || flag_only_matching || lineno != current_lineno)
++matches;

// --min-count: require at least min-count matches, otherwise stop searching
if (flag_min_count == 0 || matches >= flag_min_count)
break;

lineno = current_lineno;
}

// --min-count: require at least min-count matches
if (flag_min_count > 0 && matches < flag_min_count)
matches = 0;

// --files: if we are still holding the output and CNF is finally satisfyable then a match was made
if (flag_files && matchers != NULL)
{
Expand Down Expand Up @@ -8404,7 +8425,7 @@ void Grep::search(const char *pathname)
// --format: whether to out.acquire() early before Stats::found_part()
bool acquire = flag_format != NULL && (flag_format_open != NULL || flag_format_close != NULL);

if (!flag_empty || !flag_invert_match)
if (!flag_match || !flag_invert_match)
{
if (flag_ungroup || flag_only_matching)
{
Expand Down Expand Up @@ -8479,10 +8500,14 @@ void Grep::search(const char *pathname)
}

// --match: adjust match count when the last line has no \n line ending
if (flag_empty && matcher->last() > 0 && *(matcher->eol(true) - 1) != '\n')
if (flag_match && matcher->last() > 0 && *(matcher->eol(true) - 1) != '\n')
++matches;
}

// --min-count: require at least min-count matches
if (flag_min_count > 0 && matches < flag_min_count)
goto exit_search;

// --files: if we are still holding the output and CNF is not satisfyable then no global matches were made
if (flag_files && matchers != NULL)
{
Expand Down Expand Up @@ -11259,20 +11284,20 @@ size_t strtopos(const char *string, const char *message)
}

// convert one or two comma-separated unsigned decimals specifying a range to positive size_t, produce error when conversion fails or when the range is invalid
void strtopos2(const char *string, size_t& pos1, size_t& pos2, const char *message, bool optional_first)
void strtopos2(const char *string, size_t& min, size_t& max, const char *message, bool optional_first)
{
char *rest = const_cast<char*>(string);
if (*string != ',')
pos1 = static_cast<size_t>(strtoull(string, &rest, 10));
min = static_cast<size_t>(strtoull(string, &rest, 10));
else
pos1 = 0;
min = 0;
if (*rest == ',')
pos2 = static_cast<size_t>(strtoull(rest + 1, &rest, 10));
max = static_cast<size_t>(strtoull(rest + 1, &rest, 10));
else if (optional_first)
pos2 = pos1, pos1 = 0;
max = min, min = 0;
else
pos2 = 0;
if (rest == NULL || *rest != '\0' || (pos2 > 0 && pos1 > pos2))
max = 0;
if (rest == NULL || *rest != '\0' || (max > 0 && min > max))
usage(message, string);
}

Expand Down Expand Up @@ -11720,8 +11745,10 @@ void help(std::ostream& out)
MAGIC signatures. This option may be repeated and may be combined\n\
with options -O and -t to expand the search. Every file on the\n\
search path is read, making searches potentially more expensive.\n\
-m NUM, --max-count=NUM\n\
Stop reading the input after NUM matches in each input file.\n\
-m [MIN,][MAX], --min-count=MIN, --max-count=MAX\n\
Stop reading the input after MAX matches in each input file when\n\
specified. Require at least MIN matches when specified, for\n\
options -c, -l, -L and -q.\n\
--match\n\
Match all input. Same as specifying an empty pattern to search.\n\
--max-files=NUM\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 "3.7.5"
#define UGREP_VERSION "3.7.6"

// 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 59392f4

Please sign in to comment.