findutils-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Findutils-patches] [6 PATCHES] New feature added to find: -type xyz


From: Young Mo Kang
Subject: [Findutils-patches] [6 PATCHES] New feature added to find: -type xyz
Date: Mon, 29 Feb 2016 07:06:36 +0900

Hello,

I just thought it would be useful to enable multiple type search at once 
feature in find, i.e.,
find’s option "-type xyz” can be a shorthand form for “( -type x -o -type -y -o 
-type z )”. It should work with -xtype exactly the same way.

To me, this new syntax seems very intuitive, and it should greatly reduce 
typing.
I have modified from the most recent git commit 4.7.0-git 
19f6f691de4f41b4af76c33782a96f191378830a to enable this feature, but have not 
done much testing; I just added one simple test case.

Below is the git patch result. I am new to contributing to GNU projects and am 
NOT an experienced hacker, so I would very much like to learn. By the way, I am 
not sure if this is the proper way to sending out the patch results: should I 
send out each patch result one by one? I have followed the instructions on the 
READM-hacking file as much as possible.

Anyways, I really thank everyone's hard effort in GNU projects and I hope to be 
able to help others too.

Sincerely,
Young

- - - - - - - - - - - - - - - - -
From c53f29966706850fa14c978c077d58bdf7efe5e6 Mon Sep 17 00:00:00 2001
From: Young Mo Kang <address@hidden>
Date: Sat, 27 Feb 2016 19:03:13 -0500
Subject: [PATCH 1/6] Enable multiple char argument to -type

* find/parser.c (insert_type): When the option '-type xyz' is supplied by the 
user, 
convert it into '( -type x -o -type y -type z )' option; that is, prepend [(] 
predicate, parse a single char, append [-o] and repeat, and at the end append 
[)] predicate to close.
find/tree.c (build_expression_tree): Do not change p_name of the last predicate 
if 
the last predicate is the closing parenthesis [)]
---
 find/parser.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++------------
 find/tree.c   |  3 ++-
 2 files changed, 70 insertions(+), 17 deletions(-)

diff --git a/find/parser.c b/find/parser.c
index 57fb296..b163df3 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -2681,15 +2681,31 @@ insert_type (char **argv, int *arg_ptr,
   struct predicate *our_pred;
   float rate = 0.01;
   const char *typeletter;
+  int typeletter_length, i;
+  const struct parser_table *entry_open, *entry_close, *entry_or;
 
   if (collect_arg (argv, arg_ptr, &typeletter))
     {
-      if (strlen (typeletter) != 1u)
+       /* if the input is '-type lfd', we simply modify the predicate tree to 
be
+       ( -type l -o -type f -o -type d ) */
+      typeletter_length = strlen (typeletter);
+       if (typeletter_length > 1)
        {
-         error (EXIT_FAILURE, 0,
-                _("Arguments to -type should contain only one letter"));
-         /*NOTREACHED*/
-         return false;
+       /* More than one letter argument found.
+       Open the parenthesis */
+       entry_open  = find_parser ("(");
+       entry_close = find_parser (")");
+       entry_or = find_parser ("or");
+       assert (entry_open  != NULL);
+       assert (entry_close != NULL);
+       assert (entry_or != NULL);
+
+       our_pred = get_new_pred_chk_op (entry_open, NULL);
+       our_pred->pred_func = pred_openparen;
+       our_pred->p_type = OPEN_PAREN;
+       our_pred->p_prec = NO_PREC;
+       our_pred->need_stat = our_pred->need_type = false;
+       our_pred->p_name = "(";
        }
 
       /* From a real system here are the counts of files by type:
@@ -2702,10 +2718,11 @@ insert_type (char **argv, int *arg_ptr,
          s         80  1.59e-05
          p         38  7.54e-06
        */
-      {
        mode_t type_cell;
 
-       switch (typeletter[0])
+       for (i=0; i<typeletter_length; i++)
+               {
+      switch (typeletter[i])
          {
          case 'b':                     /* block special */
            type_cell = S_IFBLK;
@@ -2732,7 +2749,7 @@ insert_type (char **argv, int *arg_ptr,
            error (EXIT_FAILURE, 0,
                   _("-type %c is not supported because symbolic links "
                     "are not supported on the platform find was compiled on."),
-                  (*typeletter));
+                  typeletter[i]);
 #endif
            break;
          case 'p':                     /* pipe */
@@ -2744,7 +2761,7 @@ insert_type (char **argv, int *arg_ptr,
            error (EXIT_FAILURE, 0,
                   _("-type %c is not supported because FIFOs "
                     "are not supported on the platform find was compiled on."),
-                  (*typeletter));
+                  typeletter[i]);
 #endif
            break;
          case 's':                     /* socket */
@@ -2756,7 +2773,7 @@ insert_type (char **argv, int *arg_ptr,
            error (EXIT_FAILURE, 0,
                   _("-type %c is not supported because named sockets "
                     "are not supported on the platform find was compiled on."),
-                  (*typeletter));
+                  typeletter[i]);
 #endif
            break;
          case 'D':                     /* Solaris door */
@@ -2772,17 +2789,21 @@ insert_type (char **argv, int *arg_ptr,
            error (EXIT_FAILURE, 0,
                   _("-type %c is not supported because Solaris doors "
                     "are not supported on the platform find was compiled on."),
-                  (*typeletter));
+                  typeletter[i]);
 #endif
            break;
          default:                      /* None of the above ... nuke 'em. */
            type_cell = 0;
            error (EXIT_FAILURE, 0,
-                  _("Unknown argument to -type: %c"), (*typeletter));
+                  _("Unknown argument to -type: %c"), typeletter[i]);
            /*NOTREACHED*/
            return false;
          }
-       our_pred = insert_primary_withpred (entry, which_pred, typeletter);
+    /* NOTE: the arg_text field will not be a single char unless the last one.
+    To fix it, one will need to go through the hassle of allocating and 
freeing memory, because pred->arg_text is just a string pointer to argv[].
+    Note sure if the fix is necessary */
+    our_pred = insert_primary_withpred (entry, which_pred, &typeletter[i]);
+    our_pred->p_name = "-type";        /* otherwise, its p_name will be "type" 
*/
        our_pred->est_success_rate = rate;
 
        /* Figure out if we will need to stat the file, because if we don't
@@ -2800,9 +2821,40 @@ insert_type (char **argv, int *arg_ptr,
            our_pred->need_type = true;
          }
        our_pred->args.type = type_cell;
-      }
-      return true;
-    }
+                       if (typeletter_length == 1)
+                       {
+                               return true;
+                       }
+                       else if (i+1 < typeletter_length)
+                       {
+                               /* add -o predicate */
+                               our_pred = get_new_pred_noarg (entry_or);
+                               our_pred->p_name = "-o";
+                               our_pred->pred_func = pred_or;
+                               our_pred->p_type = BI_OP;
+                               our_pred->p_prec = OR_PREC;
+                               our_pred->need_stat = false;
+                               our_pred->need_type = false;
+                               our_pred->need_inum = false;
+                               our_pred->arg_text = NULL;
+                               our_pred->args.str = NULL;
+                               our_pred->side_effects = false;
+                               our_pred->no_default_print = false;
+                       }
+                       else
+                       {
+                               /* close the parenthesis */
+                               our_pred = get_new_pred (entry_close);
+                               our_pred->pred_func = pred_closeparen;
+                               our_pred->p_type = CLOSE_PAREN;
+                               our_pred->p_prec = NO_PREC;
+                               our_pred->need_stat = our_pred->need_type = 
false;
+                               our_pred->p_name = ")";
+                       }
+     }
+               return true;
+       }
+
   return false;
 }
 
diff --git a/find/tree.c b/find/tree.c
index 8a413f8..834b331 100644
--- a/find/tree.c
+++ b/find/tree.c
@@ -1332,7 +1332,8 @@ build_expression_tree (int argc, char *argv[], int 
end_of_leading_options)
              usage (EXIT_FAILURE);
            }
        }
-      else
+                       /* w/o this if condition, something funky happens with 
the form "-type lfd" */
+            else if(last_pred->parser_entry != find_parser(")"))
        {
          last_pred->p_name = predicate_name;
 
-- 
1.9.1


- - - - - - - - - - - - - - - - -
From 8bea457710c0e6259bfbe6d8873d250a9c08396f Mon Sep 17 00:00:00 2001
From: Young Mo Kang <address@hidden>
Date: Sun, 28 Feb 2016 14:08:57 -0500
Subject: [PATCH 2/6] doc: add description on -type multi arg support

* find/find.l (-type): Add description that -type now has multiple argument
support. 
(EXAMPLES) Also add one example.
* doc/find.texi (-type): Add the same description above.
* README-hacking: corrected a few misspelled words.
---
 README-hacking |  6 +++---
 doc/find.texi  |  4 ++++
 find/find.1    | 16 ++++++++++++++++
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/README-hacking b/README-hacking
index 12de1bb..280a8f0 100644
--- a/README-hacking
+++ b/README-hacking
@@ -18,7 +18,7 @@ Prerequisites
  * GNU gettext
  * GNU Dejagnu
 
-Dejagnu is in fact optional, but it's strongly recommened, since it is
+Dejagnu is in fact optional, but it's strongly recommended, since it is
 needed to run findutils' test suite (which is how you know that find
 works once it is built on your system).
 
@@ -106,10 +106,10 @@ MAX_PROC_MAX.
 --- example ends ---
 
 There are several things to notice about this checkin message.  Most
-importatly, it begins with a single line summary of the whole change.
+importantly, it begins with a single line summary of the whole change.
 This needs to be short.  It would be used as the subject line of
 patches mailed by "git send-email".  Some people begin that line with
-a one-word tag indicating what is addected (for example find: for
+a one-word tag indicating what is affected (for example find: for
 changes to find, doc: to changes to the documentation, maint: for
 changes to the maintainer automation and so forth).
 
diff --git a/doc/find.texi b/doc/find.texi
index fdeaefa..9e9ec63 100644
--- a/doc/find.texi
+++ b/doc/find.texi
@@ -1081,6 +1081,10 @@ socket
 @item D
 door (Solaris)
 @end table
+
+Multiple file types can be provided as a combined list without commas and
+will be interpreted with '-o' in between. For example, '-type fld' is
+interpreted as '( -type f -o -type l -o -type d )'.
 @end deffn
 
 @deffn Test -xtype c
diff --git a/find/find.1 b/find/find.1
index cb2ff19..02c85f0 100644
--- a/find/find.1
+++ b/find/find.1
@@ -954,6 +954,9 @@ socket
 .IP D
 door (Solaris)
 .RE
+.IP
+To search for more than one type, you can supply the combined list of
+type letters without commas.
 .IP "\-uid \fIn\fR"
 File's numeric user ID is \fIn\fR.
 
@@ -2087,6 +2090,19 @@ discovered (for example we do not search project3/src 
because we
 already found project3/.svn), but ensures sibling directories
 (project2 and project3) are found.
 
+.P
+.nf
+.B find /tmp -type fdl
+.fi
+
+Search for any files, links, and directories in the directory
+.B /tmp
+, which is equivalent to
+
+.nf
+.B find /tmep \e( -type f -o -type l -o -type d \e)
+.fi
+
 .SH EXIT STATUS
 .PP
 .B find
-- 
1.9.1

- - - - - - - - - - - - - - - - -
From 8c435d94aab68666927f1e728f0ab9a45daf0e52 Mon Sep 17 00:00:00 2001
From: Young Mo Kang <address@hidden>
Date: Sun, 28 Feb 2016 15:03:53 -0500
Subject: [PATCH 3/6] test: Add test case for -type multiple arg support

* find/testsuites/find.gnu/type.exp: Add -type fl support
* find/testsuites/find.gnu/type.xo: Same as above
* find/testsuites/Makefile.am: Add above to files
---
 find/testsuite/Makefile.am       |  2 ++
 find/testsuite/find.gnu/type.exp | 10 ++++++++++
 find/testsuite/find.gnu/type.xo  |  4 ++++
 3 files changed, 16 insertions(+)
 create mode 100644 find/testsuite/find.gnu/type.exp
 create mode 100644 find/testsuite/find.gnu/type.xo

diff --git a/find/testsuite/Makefile.am b/find/testsuite/Makefile.am
index 228957f..7b19ef6 100644
--- a/find/testsuite/Makefile.am
+++ b/find/testsuite/Makefile.am
@@ -87,6 +87,7 @@ find.gnu/sv-bug-17782.xo \
 find.gnu/sv-bug-18222.xo \
 find.gnu/sv-bug-27563-execdir.xo \
 find.gnu/true.xo \
+find.gnu/type.xo \
 find.gnu/wholename.xo \
 find.gnu/xtype-symlink.xo \
 find.gnu/quit.xo \
@@ -202,6 +203,7 @@ find.gnu/sv-bug-17782.exp \
 find.gnu/sv-bug-18222.exp \
 find.gnu/sv-bug-24169.exp \
 find.gnu/sv-bug-27563-execdir.exp \
+find.gnu/type.exp \
 find.gnu/quit.exp \
 find.gnu/used-invarg.exp \
 find.gnu/used-missing.exp \
diff --git a/find/testsuite/find.gnu/type.exp b/find/testsuite/find.gnu/type.exp
new file mode 100644
index 0000000..3bced86
--- /dev/null
+++ b/find/testsuite/find.gnu/type.exp
@@ -0,0 +1,10 @@
+# check for the -type test.
+exec rm -rf tmp
+
+exec mkdir tmp
+exec touch tmp/file
+exec mkdir tmp/directory
+exec ln -s /etc/passwd tmp/link
+exec ln -s /NOSUCHFILE tmp/broken_link
+
+find_start p { tmp/file tmp/directory tmp/link tmp/broken_link -type fl 
-printf "type is fl: %p\n" , \! -type fl -printf "type is not fl: %p\n" }
diff --git a/find/testsuite/find.gnu/type.xo b/find/testsuite/find.gnu/type.xo
new file mode 100644
index 0000000..42b13ed
--- /dev/null
+++ b/find/testsuite/find.gnu/type.xo
@@ -0,0 +1,4 @@
+type is fl: tmp/file
+type is fl: tmp/link
+type is fl: tmp/broken_link
+type is not fl: tmp/directory
-- 
1.9.1

- - - - - - - - - - - - - - - - -
From f72d5875a9efc7bb6e512fd9e3463babdfcc7592 Mon Sep 17 00:00:00 2001
From: Young Mo Kang <address@hidden>
Date: Sun, 28 Feb 2016 15:12:49 -0500
Subject: [PATCH 4/6] doc: Add description to the -type mult arg support

* NEWS: Add description -type's multiple arg support
---
 NEWS | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index 009b7a3..ca9d24b 100644
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,7 @@ GNU findutils NEWS - User visible changes.      -*- outline -*- 
(allout)
 
 * Major changes in release 4.7.0-git, YYYY-MM-DD
 
-** Changes to locate / updatedb
+** Changes to locate / updatedb / find
 
 Support for generating old-format databases (with updatedb
 --old-format or updatedb --dbformat=old) has been removed.  The old
@@ -20,6 +20,11 @@ database is now different to previous versions.  However, 
you should
 not rely on locate's output appearing in any particular order in any
 case.
 
+The find program will now accept multiple letters as -type arguments.
+For example, to search for files and directories and links all together,
+simply give the option '-type fdl' which will be interpreted as
+'( -type f -o -type d -o -type l )'.
+
 ** Improvements
 
 All utilities now only show the full usage text when requested via
-- 
1.9.1

- - - - - - - - - - - - - - - - -
From 326d5feac7c6b8e7248472f0aa06597c6e8a8d8e Mon Sep 17 00:00:00 2001
From: Young Mo Kang <address@hidden>
Date: Sun, 28 Feb 2016 15:35:19 -0500
Subject: [PATCH 5/6] Remove tabs and inserted spaces

* find/parser.c (insert_type): Remove any tabs and replace with spaces
---
 find/parser.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/find/parser.c b/find/parser.c
index b163df3..2556864 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -2721,7 +2721,7 @@ insert_type (char **argv, int *arg_ptr,
        mode_t type_cell;
 
        for (i=0; i<typeletter_length; i++)
-               {
+          {
       switch (typeletter[i])
          {
          case 'b':                     /* block special */
@@ -2803,7 +2803,7 @@ insert_type (char **argv, int *arg_ptr,
     To fix it, one will need to go through the hassle of allocating and 
freeing memory, because pred->arg_text is just a string pointer to argv[].
     Note sure if the fix is necessary */
     our_pred = insert_primary_withpred (entry, which_pred, &typeletter[i]);
-    our_pred->p_name = "-type";        /* otherwise, its p_name will be "type" 
*/
+    our_pred->p_name = "-type";     /* otherwise, its p_name will be "type" */
        our_pred->est_success_rate = rate;
 
        /* Figure out if we will need to stat the file, because if we don't
-- 
1.9.1

- - - - - - - - - - - - - - - - -
From 5d50422df1a97fb297d31f9ff24e937ae5d2fa95 Mon Sep 17 00:00:00 2001
From: Young Mo Kang <address@hidden>
Date: Sun, 28 Feb 2016 16:51:08 -0500
Subject: [PATCH 6/6] Modify pred->p_name for -type and -xtype

* find/parser.c (insert_type): Modify pred->p_name here instead from
tree.c's build_expression function.
---
 find/parser.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/find/parser.c b/find/parser.c
index 2556864..a9b688e 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -2801,9 +2801,8 @@ insert_type (char **argv, int *arg_ptr,
          }
     /* NOTE: the arg_text field will not be a single char unless the last one.
     To fix it, one will need to go through the hassle of allocating and 
freeing memory, because pred->arg_text is just a string pointer to argv[].
-    Note sure if the fix is necessary */
+    Not sure if the fix is necessary */
     our_pred = insert_primary_withpred (entry, which_pred, &typeletter[i]);
-    our_pred->p_name = "-type";     /* otherwise, its p_name will be "type" */
        our_pred->est_success_rate = rate;
 
        /* Figure out if we will need to stat the file, because if we don't
@@ -2814,11 +2813,13 @@ insert_type (char **argv, int *arg_ptr,
          {
            our_pred->need_stat = true;
            our_pred->need_type = false;
+            our_pred->p_name = "-xtype";
          }
        else
          {
            our_pred->need_stat = false; /* struct dirent is enough */
            our_pred->need_type = true;
+            our_pred->p_name = "-type";
          }
        our_pred->args.type = type_cell;
                        if (typeletter_length == 1)
-- 
1.9.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]