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