On Tue, May 14, 2024 at 9:06 AM James Youngman <ja...@youngman.org> wrote:

>
>
> On Tue, May 14, 2024 at 9:06 AM James Youngman <ja...@youngman.org> wrote:
>
>> See attached patches.   If no objections, I will submit these soon.
>>
>>
>>
From 76215fb45f29a035ddeb64ede8eb8078f02f5e75 Mon Sep 17 00:00:00 2001
From: James Youngman <ja...@youngman.org>
Date: Mon, 13 May 2024 21:56:21 +0100
Subject: [PATCH 3/3] Simplify use of predicate->args.exec_vec slightly.
To: findutils-patc...@gnu.org

We introduce a function which tells us whether that union member is
valid.
---
 find/defs.h   |  6 ++----
 find/parser.c |  3 ++-
 find/pred.c   | 10 ++++++++++
 find/tree.c   |  2 +-
 find/util.c   | 13 +++++++------
 5 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/find/defs.h b/find/defs.h
index ee309e0a..453dc272 100644
--- a/find/defs.h
+++ b/find/defs.h
@@ -472,7 +472,8 @@ void print_tree (FILE*, struct predicate *node, int indent);
 void print_list (FILE*, struct predicate *node);
 void print_optlist (FILE *fp, const struct predicate *node);
 void show_success_rates(const struct predicate *node);
-
+bool predicate_uses_exec(const struct predicate*);
+# define pred_is(node, fn) ( ((node)->pred_func) == (fn) )
 
 /* tree.c */
 bool matches_start_point(const char * glob, bool foldcase);
@@ -512,9 +513,6 @@ void set_option_defaults (struct options *p);
 bool apply_predicate(const char *pathname, struct stat *stat_buf, struct predicate *p);
 # endif
 
-# define pred_is(node, fn) ( ((node)->pred_func) == (fn) )
-
-
 /* util.c. */
 bool following_links (void);
 bool digest_mode (mode_t *mode, const char *pathname, const char *name, struct stat *pstat, bool leaf);
diff --git a/find/parser.c b/find/parser.c
index efa2f41f..f95adfc7 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -2048,7 +2048,7 @@ parse_size (const struct parser_table* entry, char **argv, int *arg_ptr)
   int blksize = 512;
   int len;
 
-  /* XXX: cannot (yet) convert to ue collect_arg() as this
+  /* XXX: cannot (yet) convert to use collect_arg() as this
    * function modifies the args in-place.
    */
   if ((argv == NULL) || (argv[*arg_ptr] == NULL))
@@ -2787,6 +2787,7 @@ insert_exec_ok (const char *action,
   our_pred->side_effects = our_pred->no_default_print = true;
   our_pred->need_type = our_pred->need_stat = false;
 
+  assert(predicate_uses_exec (our_pred));
   execp = &our_pred->args.exec_vec;
   execp->wd_for_exec = NULL;
 
diff --git a/find/pred.c b/find/pred.c
index 148c27dc..8312f6e2 100644
--- a/find/pred.c
+++ b/find/pred.c
@@ -701,6 +701,16 @@ is_ok (const char *program, const char *arg)
   return yesno ();
 }
 
+bool
+predicate_uses_exec(const struct predicate* p)
+{
+  return pred_is(p, pred_exec)
+    || pred_is(p, pred_execdir)
+    || pred_is(p, pred_ok)
+    || pred_is(p, pred_okdir);
+}
+
+
 bool
 pred_ok (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
 {
diff --git a/find/tree.c b/find/tree.c
index 494aaa4b..1c6b4588 100644
--- a/find/tree.c
+++ b/find/tree.c
@@ -1056,7 +1056,7 @@ get_pred_cost (const struct predicate *p)
       data_requirement_cost = NeedsNothing;
     }
 
-  if (pred_is (p, pred_exec) || pred_is(p, pred_execdir))
+  if (predicate_uses_exec (p))
     {
       if (p->args.exec_vec.multiple)
 	inherent_cost = NeedsEventualExec;
diff --git a/find/util.c b/find/util.c
index a61e3e45..3445db14 100644
--- a/find/util.c
+++ b/find/util.c
@@ -395,9 +395,14 @@ do_complete_pending_execdirs (struct predicate *p)
 
   do_complete_pending_execdirs (p->pred_left);
 
-  if (pred_is (p, pred_execdir) || pred_is(p, pred_okdir))
+  /* We only want to do work here if there is a dir-local pending
+   * exec.  This is because the completion of work for -exec ... {} +
+   * happens when the program exits, not when we leave a directory.
+   */
+  if (pred_is(p, pred_okdir) || pred_is(p, pred_execdir))
     {
       /* It's an exec-family predicate.  p->args.exec_val is valid. */
+      assert(predicate_uses_exec(p));
       if (p->args.exec_vec.multiple)
 	{
 	  struct exec_val *execp = &p->args.exec_vec;
@@ -426,8 +431,6 @@ complete_pending_execdirs (void)
     }
 }
 
-
-
 /* Examine the predicate list for instances of -exec which have been
  * terminated with '+' (build argument list) rather than ';' (singles
  * only).  If there are any, run them (this will have no effect if
@@ -438,14 +441,12 @@ complete_pending_execs (struct predicate *p)
 {
   if (NULL == p)
     return;
-
   complete_pending_execs (p->pred_left);
 
   /* It's an exec-family predicate then p->args.exec_val is valid
    * and we can check it.
    */
-  /* XXX: what about pred_ok() ? */
-  if (pred_is (p, pred_exec) && p->args.exec_vec.multiple)
+  if (predicate_uses_exec (p) && p->args.exec_vec.multiple)
     {
       struct exec_val *execp = &p->args.exec_vec;
 
-- 
2.39.2

Reply via email to