[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Findutils-patches] [PATCH] Fix Savannah bug #20865.
From: |
James Youngman |
Subject: |
[Findutils-patches] [PATCH] Fix Savannah bug #20865. |
Date: |
Wed, 28 Nov 2007 00:24:38 +0000 |
2007-11-28 James Youngman <address@hidden>
Fix Savannah bug #20865.
* find/parser.c (check_option_combinations): Diagnose the
situation where -delete and -prune are both used, because -delete
turns on -depth and -depth makes -prune do nothing.
* find/tree.c (build_expression_tree): call
check_option_combinations().
* find/defs.h (struct options): Add new boolean field
explicit_depth.
Also declare check_option_combinations.
* find/util.c (set_option_defaults): Initialise explicit_depth.
---
find/defs.h | 5 +++++
find/parser.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
find/tree.c | 1 +
find/util.c | 1 +
4 files changed, 51 insertions(+), 0 deletions(-)
diff --git a/find/defs.h b/find/defs.h
index d886fa2..c3e330b 100644
--- a/find/defs.h
+++ b/find/defs.h
@@ -391,6 +391,7 @@ struct parser_table
const struct parser_table* find_parser PARAMS((char *search_name));
boolean parse_print PARAMS((const struct parser_table*, char *argv[], int
*arg_ptr));
void pred_sanity_check PARAMS((const struct predicate *predicates));
+void check_option_combinations (const struct predicate *p);
void parse_begin_user_args PARAMS((char **args, int argno, const struct
predicate *last, const struct predicate *predicates));
void parse_end_user_args PARAMS((char **args, int argno, const struct
predicate *last, const struct predicate *predicates));
boolean parse_openparen PARAMS((const struct parser_table* entry,
char *argv[], int *arg_ptr));
@@ -530,6 +531,10 @@ struct options
{
/* If true, process directory before contents. True unless -depth given. */
boolean do_dir_first;
+ /* If true, -depth was EXPLICITLY set (as opposed to having been turned
+ * on by -delete, for example).
+ */
+ boolean explicit_depth;
/* If >=0, don't descend more than this many levels of subdirectories. */
int maxdepth;
diff --git a/find/parser.c b/find/parser.c
index 18d26cc..7eaefc1 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -349,6 +349,49 @@ static const char *first_nonoption_arg = NULL;
static const struct parser_table *noop = NULL;
+void
+check_option_combinations(const struct predicate *p)
+{
+ enum { seen_delete=1u, seen_prune=2u };
+ unsigned int predicates = 0u;
+
+ while (p)
+ {
+ if (p->pred_func == pred_delete)
+ predicates |= seen_delete;
+ else if (p->pred_func == pred_prune)
+ predicates |= seen_prune;
+ p = p->pred_next;
+ }
+
+ if ((predicates & seen_prune) && (predicates & seen_delete))
+ {
+ /* The user specified both -delete and -prune. One might test
+ * this by first doing
+ * find dirs .... -prune ..... -print
+ * to fnd out what's going to get deleted, and then switch to
+ * find dirs .... -prune ..... -delete
+ * once we are happy. Unfortunately, the -delete action also
+ * implicitly turns on -depth, which will affect the behaviour
+ * of -prune (in fact, it makes it a no-op). In this case we
+ * would like to prevent unfortunate accidents, so we require
+ * the user to have explicitly used -depth.
+ *
+ * We only get away with this because the -delete predicate is not
+ * in POSIX. If it was, we couldn't issue a fatal error here.
+ */
+ if (!options.explicit_depth)
+ {
+ /* This fixes Savannah bug #20865. */
+ error (1, 0, _("The -delete action atomatically turns on -depth, "
+ "but -prune does nothing when -depth is in effect. "
+ "If you want to carry on anyway, just explicitly use "
+ "the -depth option."));
+ }
+ }
+}
+
+
static const struct parser_table*
get_noop(void)
{
@@ -760,6 +803,7 @@ parse_depth (const struct parser_table* entry, char **argv,
int *arg_ptr)
(void) argv;
options.do_dir_first = false;
+ options.explicit_depth = true;
return parse_noop(entry, argv, arg_ptr);
}
diff --git a/find/tree.c b/find/tree.c
index d12d579..7420c60 100644
--- a/find/tree.c
+++ b/find/tree.c
@@ -1325,6 +1325,7 @@ build_expression_tree(int argc, char *argv[], int
end_of_leading_options)
}
/* do a sanity check */
+ check_option_combinations(predicates);
pred_sanity_check(predicates);
/* Done parsing the predicates. Build the evaluation tree. */
diff --git a/find/util.c b/find/util.c
index 388f9fc..f057f5d 100644
--- a/find/util.c
+++ b/find/util.c
@@ -923,6 +923,7 @@ set_option_defaults(struct options *p)
}
p->do_dir_first = true;
+ p->explicit_depth = false;
p->maxdepth = p->mindepth = -1;
p->start_time = now();
p->cur_day_start = p->start_time.tv_sec - DAYSECS;
--
1.5.3.6
- [Findutils-patches] [PATCH] Fix Savannah bug #20865.,
James Youngman <=