grep: add -R

This adds -R option to grep similar to GNU grep. It is the same as -r
but also dereferences symbolic links to directories.

function                                             old     new   delta
grep_main                                            834     850     +16
packed_usage                                       33362   33368      +6
grep_file                                           1440    1441      +1
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 23/0)               Total: 23 bytes

Signed-off-by: Tomi Leppanen <tomi.leppanen@jolla.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Tomi Leppanen 2019-11-25 17:59:52 +02:00 committed by Denys Vlasenko
parent 008413754b
commit 1b76ffaae4

View File

@ -60,7 +60,7 @@
/* options */ /* options */
//usage:#define grep_trivial_usage //usage:#define grep_trivial_usage
//usage: "[-HhnlLoqvsriwFE" //usage: "[-HhnlLoqvsrRiwFE"
//usage: IF_EXTRA_COMPAT("z") //usage: IF_EXTRA_COMPAT("z")
//usage: "] [-m N] " //usage: "] [-m N] "
//usage: IF_FEATURE_GREP_CONTEXT("[-A/B/C N] ") //usage: IF_FEATURE_GREP_CONTEXT("[-A/B/C N] ")
@ -78,6 +78,7 @@
//usage: "\n -v Select non-matching lines" //usage: "\n -v Select non-matching lines"
//usage: "\n -s Suppress open and read errors" //usage: "\n -s Suppress open and read errors"
//usage: "\n -r Recurse" //usage: "\n -r Recurse"
//usage: "\n -R Recurse and dereference symlinks"
//usage: "\n -i Ignore case" //usage: "\n -i Ignore case"
//usage: "\n -w Match whole words only" //usage: "\n -w Match whole words only"
//usage: "\n -x Match whole lines only" //usage: "\n -x Match whole lines only"
@ -108,7 +109,7 @@
/* -e,-f are lists; -m,-A,-B,-C have numeric param */ /* -e,-f are lists; -m,-A,-B,-C have numeric param */
#define OPTSTR_GREP \ #define OPTSTR_GREP \
"lnqvscFiHhe:*f:*Lorm:+wx" \ "lnqvscFiHhe:*f:*LorRm:+wx" \
IF_FEATURE_GREP_CONTEXT("A:+B:+C:+") \ IF_FEATURE_GREP_CONTEXT("A:+B:+C:+") \
"E" \ "E" \
IF_EXTRA_COMPAT("z") \ IF_EXTRA_COMPAT("z") \
@ -131,6 +132,7 @@ enum {
OPTBIT_L, /* list unmatched file names only */ OPTBIT_L, /* list unmatched file names only */
OPTBIT_o, /* show only matching parts of lines */ OPTBIT_o, /* show only matching parts of lines */
OPTBIT_r, /* recurse dirs */ OPTBIT_r, /* recurse dirs */
OPTBIT_R, /* recurse dirs and symlinks to dirs */
OPTBIT_m, /* -m MAX_MATCHES */ OPTBIT_m, /* -m MAX_MATCHES */
OPTBIT_w, /* -w whole word match */ OPTBIT_w, /* -w whole word match */
OPTBIT_x, /* -x whole line match */ OPTBIT_x, /* -x whole line match */
@ -154,6 +156,7 @@ enum {
OPT_L = 1 << OPTBIT_L, OPT_L = 1 << OPTBIT_L,
OPT_o = 1 << OPTBIT_o, OPT_o = 1 << OPTBIT_o,
OPT_r = 1 << OPTBIT_r, OPT_r = 1 << OPTBIT_r,
OPT_R = 1 << OPTBIT_R,
OPT_m = 1 << OPTBIT_m, OPT_m = 1 << OPTBIT_m,
OPT_w = 1 << OPTBIT_w, OPT_w = 1 << OPTBIT_w,
OPT_x = 1 << OPTBIT_x, OPT_x = 1 << OPTBIT_x,
@ -687,6 +690,7 @@ static int grep_dir(const char *dir)
int matched = 0; int matched = 0;
recursive_action(dir, recursive_action(dir,
/* recurse=yes */ ACTION_RECURSE | /* recurse=yes */ ACTION_RECURSE |
/* followLinks=always */ ((option_mask32 & OPT_R) ? ACTION_FOLLOWLINKS : 0) |
/* followLinks=command line only */ ACTION_FOLLOWLINKS_L0 | /* followLinks=command line only */ ACTION_FOLLOWLINKS_L0 |
/* depthFirst=yes */ ACTION_DEPTHFIRST, /* depthFirst=yes */ ACTION_DEPTHFIRST,
/* fileAction= */ file_action_grep, /* fileAction= */ file_action_grep,
@ -827,7 +831,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv)
if (!cur_file || LONE_DASH(cur_file)) { if (!cur_file || LONE_DASH(cur_file)) {
cur_file = "(standard input)"; cur_file = "(standard input)";
} else { } else {
if (option_mask32 & OPT_r) { if (option_mask32 & (OPT_r|OPT_R)) {
struct stat st; struct stat st;
if (stat(cur_file, &st) == 0 && S_ISDIR(st.st_mode)) { if (stat(cur_file, &st) == 0 && S_ISDIR(st.st_mode)) {
if (!(option_mask32 & OPT_h)) if (!(option_mask32 & OPT_h))