grep: add -R
authorTomi Leppanen <tomi.leppanen@jolla.com>
Mon, 25 Nov 2019 15:59:52 +0000 (17:59 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 27 Nov 2019 16:11:09 +0000 (17:11 +0100)
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>
findutils/grep.c

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