findutils-patches
[Top][All Lists]
Advanced

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

[Findutils-patches] [PATCH] Fix Savannah bug #27017: find -D opt / -fsty


From: James Youngman
Subject: [Findutils-patches] [PATCH] Fix Savannah bug #27017: find -D opt / -fstype ext3 -print , -quit coredump (vs. 4.5.x)
Date: Sat, 11 Jul 2009 21:29:22 +0100

Fix Savannah bug #27017: find -D opt / -fstype ext3 -print , -quit
coredumps.
* find/tree.c (set_new_parent): Initialise struct
predicate->arg_text to NULL (instead of leaving it uninitialised).
(get_new_pred_noarg): Likewise.
(get_new_pred): Initialise predicate->arg_text to
"ThisShouldBeSetToSomethingElse" to make it easier to notice
bugs.
(get_new_pred_chk_op): Use get_new_pred_noarg.
(print_predicate): Use an if statement instead of
two ternary operators.
* find/util.c (insert_primary_withpred): Accept new argument, arg,
being the argument (if any) of this predicate.  Pass it to
get_new_pred_chk_op.
(insert_primary): Likewise (pass arg to insert_primary_withpred).
(insert_primary_noarg): New function; calls insert_primary with
arg=NULL.
* find/parser.c (collect_arg_stat_info): Add an output parameter;
the filename from which we collected the stat information.
(parse_closeparen, parse_delete, parse_and, parse_or,
parse_comma): Use get_new_pred_noarg.
(parse_cnewer, parse_newer, parse_anewer): Use new
collect_arg_stat_info and insert_primary interface.
(parse_print, parse_prune, parse_nouser, parse_empty): Use
insert_primary_noarg.
(parse_accesscheck, parse_false): Use insert_primary_noarg.
(parse_used, parse_iname, parse_fprint, insert_fprint,
parse_fstype, parse_ilname): Use new collect_arg and
insert_primary interfaces.
(parse_ipath, parse_lname, do_parse_xmin, parse_name, parse_path,
parse_perm, parse_size, parse_user, parse_time): Use new
collect_arg and insert_primary_withpred interface.
(parse_negate, parse_openparen): Use new get_new_pred_chk_op interface.
(parse_newerXY, parse_nogroup): Use new insert_primary interface.
(insert_regex, parse_samefile): Use new insert_primary_withpred
interface.
(insert_type, insert_fprintf, new_insert_exec_ok, insert_num): Use
new insert_primary_withpred interface.
* find/defs.h (struct predicate.arg_text): make const.
Add declarations for new function get_new_pred_noarg and
insert_primary_noarg.  Add 'arg' parameter to get_new_pred_chk_op
and insert_primary_withpred.
---
 ChangeLog     |   45 ++++++++++++++++++++
 find/defs.h   |   11 +++--
 find/parser.c |  125 ++++++++++++++++++++++++++++++--------------------------
 find/tree.c   |   34 +++++++++++++---
 find/util.c   |   16 +++++--
 5 files changed, 159 insertions(+), 72 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index cccc2f9..c7dd24d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,50 @@
 2009-07-11  James Youngman  <address@hidden>
 
+       Fix Savannah bug #27017: find -D opt / -fstype ext3 -print , -quit
+       coredumps.
+       * find/tree.c (set_new_parent): Initialise struct
+       predicate->arg_text to NULL (instead of leaving it uninitialised).
+       (get_new_pred_noarg): Likewise.
+       (get_new_pred): Initialise predicate->arg_text to
+       "ThisShouldBeSetToSomethingElse" to make it easier to notice
+       bugs.
+       (get_new_pred_chk_op): Use get_new_pred_noarg.
+       (print_predicate): Use an if statement instead of
+       two ternary operators.
+       * find/util.c (insert_primary_withpred): Accept new argument, arg,
+       being the argument (if any) of this predicate.  Pass it to
+       get_new_pred_chk_op.
+       (insert_primary): Likewise (pass arg to insert_primary_withpred).
+       (insert_primary_noarg): New function; calls insert_primary with
+       arg=NULL.
+       * find/parser.c (collect_arg_stat_info): Add an output parameter;
+       the filename from which we collected the stat information.
+       (parse_closeparen, parse_delete, parse_and, parse_or,
+       parse_comma): Use get_new_pred_noarg.
+       (parse_cnewer, parse_newer, parse_anewer): Use new
+       collect_arg_stat_info and insert_primary interface.
+       (parse_print, parse_prune, parse_nouser, parse_empty): Use
+       insert_primary_noarg.
+       (parse_accesscheck, parse_false): Use insert_primary_noarg.
+       (parse_used, parse_iname, parse_fprint, insert_fprint,
+       parse_fstype, parse_ilname): Use new collect_arg and
+       insert_primary interfaces.
+       (parse_ipath, parse_lname, do_parse_xmin, parse_name, parse_path,
+       parse_perm, parse_size, parse_user, parse_time): Use new
+       collect_arg and insert_primary_withpred interface.
+       (parse_negate, parse_openparen): Use new get_new_pred_chk_op interface.
+       (parse_newerXY, parse_nogroup): Use new insert_primary interface.
+       (insert_regex, parse_samefile): Use new insert_primary_withpred
+       interface.
+       (insert_type, insert_fprintf, new_insert_exec_ok, insert_num): Use
+       new insert_primary_withpred interface.
+       * find/defs.h (struct predicate.arg_text): make const.
+       Add declarations for new function get_new_pred_noarg and
+       insert_primary_noarg.  Add 'arg' parameter to get_new_pred_chk_op
+       and insert_primary_withpred.
+
+2009-07-11  James Youngman  <address@hidden>
+
        * NEWS: Set the version to 4.5.6-git, so that we can make test
        releases.
 
diff --git a/find/defs.h b/find/defs.h
index 692328a..bc3bca6 100644
--- a/find/defs.h
+++ b/find/defs.h
@@ -301,7 +301,7 @@ struct predicate
   boolean artificial;
 
   /* The raw text of the argument of this predicate. */
-  char *arg_text;
+  const char *arg_text;
 
   /* Information needed by the predicate processor.
      Next to each member are listed the predicates that use it. */
@@ -484,13 +484,16 @@ void show_success_rates(const struct predicate *node);
 /* tree.c */
 struct predicate * build_expression_tree PARAMS((int argc, char *argv[], int 
end_of_leading_options));
 struct predicate * get_eval_tree PARAMS((void));
+struct predicate *get_new_pred_noarg (const struct parser_table *entry);
 struct predicate *get_new_pred PARAMS((const struct parser_table *entry));
-struct predicate *get_new_pred_chk_op PARAMS((const struct parser_table 
*entry));
+struct predicate *get_new_pred_chk_op PARAMS((const struct parser_table *entry,
+                                             const char *arg));
 float  calculate_derived_rates PARAMS((struct predicate *p));
 
 /* util.c */
-struct predicate *insert_primary PARAMS((const struct parser_table *entry));
-struct predicate *insert_primary_withpred PARAMS((const struct parser_table 
*entry, PRED_FUNC fptr));
+struct predicate *insert_primary PARAMS((const struct parser_table *entry, 
const char *arg));
+struct predicate *insert_primary_noarg PARAMS((const struct parser_table 
*entry));
+struct predicate *insert_primary_withpred PARAMS((const struct parser_table 
*entry, PRED_FUNC fptr, const char *arg));
 void usage PARAMS((FILE *fp, int status, char *msg));
 extern boolean check_nofollow(void);
 void complete_pending_execs(struct predicate *p);
diff --git a/find/parser.c b/find/parser.c
index 427c14a..473d10a 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -640,11 +640,13 @@ collect_arg(char **argv, int *arg_ptr, const char 
**collected_arg)
 }
 
 static boolean
-collect_arg_stat_info(char **argv, int *arg_ptr, struct stat *p)
+collect_arg_stat_info(char **argv, int *arg_ptr, struct stat *p,
+                     const char **argument)
 {
   const char *filename;
   if (collect_arg(argv, arg_ptr, &filename))
     {
+      *argument = filename;
       if (0 == (options.xstat)(filename, p))
        {
          return true;
@@ -656,6 +658,7 @@ collect_arg_stat_info(char **argv, int *arg_ptr, struct 
stat *p)
     }
   else
     {
+      *argument = NULL;
       return false;
     }
 }
@@ -679,7 +682,7 @@ parse_and (const struct parser_table* entry, char **argv, 
int *arg_ptr)
   (void) argv;
   (void) arg_ptr;
 
-  our_pred = get_new_pred (entry);
+  our_pred = get_new_pred_noarg (entry);
   our_pred->pred_func = pred_and;
   our_pred->p_type = BI_OP;
   our_pred->p_prec = AND_PREC;
@@ -691,11 +694,12 @@ static boolean
 parse_anewer (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
   struct stat stat_newer;
+  const char *arg;
 
   set_stat_placeholders(&stat_newer);
-  if (collect_arg_stat_info(argv, arg_ptr, &stat_newer))
+  if (collect_arg_stat_info(argv, arg_ptr, &stat_newer, &arg))
     {
-      struct predicate *our_pred = insert_primary (entry);
+      struct predicate *our_pred = insert_primary (entry, arg);
       our_pred->args.reftime.xval = XVAL_ATIME;
       our_pred->args.reftime.ts = get_stat_mtime(&stat_newer);
       our_pred->args.reftime.kind = COMP_GT;
@@ -713,7 +717,7 @@ parse_closeparen (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   (void) argv;
   (void) arg_ptr;
 
-  our_pred = get_new_pred (entry);
+  our_pred = get_new_pred_noarg (entry);
   our_pred->pred_func = pred_closeparen;
   our_pred->p_type = CLOSE_PAREN;
   our_pred->p_prec = NO_PREC;
@@ -725,11 +729,12 @@ static boolean
 parse_cnewer (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
   struct stat stat_newer;
+  const char *arg;
 
   set_stat_placeholders(&stat_newer);
-  if (collect_arg_stat_info(argv, arg_ptr, &stat_newer))
+  if (collect_arg_stat_info(argv, arg_ptr, &stat_newer, &arg))
     {
-      struct predicate *our_pred = insert_primary (entry);
+      struct predicate *our_pred = insert_primary (entry, arg);
       our_pred->args.reftime.xval = XVAL_CTIME; /* like -newercm */
       our_pred->args.reftime.ts = get_stat_mtime(&stat_newer);
       our_pred->args.reftime.kind = COMP_GT;
@@ -747,7 +752,7 @@ parse_comma (const struct parser_table* entry, char **argv, 
int *arg_ptr)
   (void) argv;
   (void) arg_ptr;
 
-  our_pred = get_new_pred (entry);
+  our_pred = get_new_pred_noarg (entry);
   our_pred->pred_func = pred_comma;
   our_pred->p_type = BI_OP;
   our_pred->p_prec = COMMA_PREC;
@@ -786,7 +791,7 @@ parse_delete (const struct parser_table* entry, char 
*argv[], int *arg_ptr)
   (void) argv;
   (void) arg_ptr;
 
-  our_pred = insert_primary (entry);
+  our_pred = insert_primary_noarg (entry);
   our_pred->side_effects = our_pred->no_default_print = true;
   /* -delete implies -depth */
   options.do_dir_first = false;
@@ -831,7 +836,7 @@ parse_empty (const struct parser_table* entry, char **argv, 
int *arg_ptr)
   (void) argv;
   (void) arg_ptr;
 
-  our_pred = insert_primary (entry);
+  our_pred = insert_primary_noarg (entry);
   our_pred->est_success_rate = 0.01f; /* assume 1% of files are empty. */
   return true;
 }
@@ -856,7 +861,7 @@ parse_false (const struct parser_table* entry, char **argv, 
int *arg_ptr)
   (void) argv;
   (void) arg_ptr;
 
-  our_pred = insert_primary (entry);
+  our_pred = insert_primary_noarg (entry);
   our_pred->need_stat = our_pred->need_type = false;
   our_pred->side_effects = our_pred->no_default_print = false;
   our_pred->est_success_rate = 0.0f;
@@ -866,7 +871,7 @@ parse_false (const struct parser_table* entry, char **argv, 
int *arg_ptr)
 static boolean
 insert_fls (const struct parser_table* entry, const char *filename)
 {
-  struct predicate *our_pred = insert_primary (entry);
+  struct predicate *our_pred = insert_primary_noarg (entry);
   if (filename)
     open_output_file (filename, &our_pred->args.printf_vec);
   else
@@ -899,7 +904,7 @@ parse_fprint (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   const char *filename;
   if (collect_arg(argv, arg_ptr, &filename))
     {
-      our_pred = insert_primary (entry);
+      our_pred = insert_primary (entry, filename);
       open_output_file (filename, &our_pred->args.printf_vec);
       our_pred->side_effects = our_pred->no_default_print = true;
       our_pred->need_stat = our_pred->need_type = false;
@@ -915,7 +920,7 @@ parse_fprint (const struct parser_table* entry, char 
**argv, int *arg_ptr)
 static boolean
 insert_fprint(const struct parser_table* entry, const char *filename)
 {
-  struct predicate *our_pred = insert_primary (entry);
+  struct predicate *our_pred = insert_primary (entry, filename);
   if (filename)
     open_output_file (filename, &our_pred->args.printf_vec);
   else
@@ -960,7 +965,7 @@ parse_fstype (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   const char *typename;
   if (collect_arg(argv, arg_ptr, &typename))
     {
-      struct predicate *our_pred = insert_primary (entry);
+      struct predicate *our_pred = insert_primary (entry, typename);
       our_pred->args.str = typename;
 
       /* This is an expensive operation, so although there are
@@ -1090,7 +1095,7 @@ parse_group (const struct parser_table* entry, char 
**argv, int *arg_ptr)
              return false;
            }
        }
-      our_pred = insert_primary (entry);
+      our_pred = insert_primary (entry, groupname);
       our_pred->args.gid = gid;
       our_pred->est_success_rate = (our_pred->args.numinfo.l_val < 100) ? 0.99 
: 0.2;
       return true;
@@ -1160,7 +1165,7 @@ parse_ilname (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   const char *name;
   if (collect_arg(argv, arg_ptr, &name))
     {
-      struct predicate *our_pred = insert_primary (entry);
+      struct predicate *our_pred = insert_primary (entry, name);
       our_pred->args.str = name;
       /* Use the generic glob pattern estimator to figure out how many
        * links will match, but bear in mind that most files won't be links.
@@ -1227,7 +1232,7 @@ parse_iname (const struct parser_table* entry, char 
**argv, int *arg_ptr)
     {
       if (check_name_arg("-iname", name))
        {
-         struct predicate *our_pred = insert_primary (entry);
+         struct predicate *our_pred = insert_primary (entry, name);
          our_pred->need_stat = our_pred->need_type = false;
          our_pred->args.str = name;
          our_pred->est_success_rate = estimate_pattern_match_rate(name, 0);
@@ -1271,7 +1276,7 @@ parse_ipath (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   fnmatch_sanitycheck ();
   if (collect_arg (argv, arg_ptr, &name))
     {
-      struct predicate *our_pred = insert_primary_withpred (entry, pred_ipath);
+      struct predicate *our_pred = insert_primary_withpred (entry, pred_ipath, 
name);
       our_pred->need_stat = our_pred->need_type = false;
       our_pred->args.str = name;
       our_pred->est_success_rate = estimate_pattern_match_rate (name, 0);
@@ -1319,7 +1324,7 @@ parse_lname (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   fnmatch_sanitycheck();
   if (collect_arg(argv, arg_ptr, &name))
     {
-      struct predicate *our_pred = insert_primary (entry);
+      struct predicate *our_pred = insert_primary (entry, name);
       our_pred->args.str = name;
       our_pred->est_success_rate = 0.1 * estimate_pattern_match_rate(name, 0);
       return true;
@@ -1394,7 +1399,7 @@ do_parse_xmin (const struct parser_table* entry,
                                 "arithmetic overflow while converting %s "
                                 "minutes to a number of seconds"))
        {
-         struct predicate *our_pred = insert_primary (entry);
+         struct predicate *our_pred = insert_primary (entry, minutes);
          our_pred->args.reftime = tval;
          our_pred->est_success_rate = 
estimate_timestamp_success_rate(tval.ts.tv_sec);
          return true;
@@ -1430,7 +1435,7 @@ parse_name (const struct parser_table* entry, char 
**argv, int *arg_ptr)
       fnmatch_sanitycheck();
       if (check_name_arg("-name", name))
        {
-         struct predicate *our_pred = insert_primary (entry);
+         struct predicate *our_pred = insert_primary (entry, name);
          our_pred->need_stat = our_pred->need_type = false;
          our_pred->args.str = name;
          our_pred->est_success_rate = estimate_pattern_match_rate(name, 0);
@@ -1448,7 +1453,7 @@ parse_negate (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   (void) &argv;
   (void) &arg_ptr;
 
-  our_pred = get_new_pred_chk_op (entry);
+  our_pred = get_new_pred_chk_op (entry, NULL);
   our_pred->pred_func = pred_negate;
   our_pred->p_type = UNI_OP;
   our_pred->p_prec = NEGATE_PREC;
@@ -1461,11 +1466,12 @@ parse_newer (const struct parser_table* entry, char 
**argv, int *arg_ptr)
 {
   struct predicate *our_pred;
   struct stat stat_newer;
+  const char *arg;
 
   set_stat_placeholders(&stat_newer);
-  if (collect_arg_stat_info(argv, arg_ptr, &stat_newer))
+  if (collect_arg_stat_info(argv, arg_ptr, &stat_newer, &arg))
     {
-      our_pred = insert_primary (entry);
+      our_pred = insert_primary (entry, arg);
       our_pred->args.reftime.ts = get_stat_mtime(&stat_newer);
       our_pred->args.reftime.xval = XVAL_MTIME;
       our_pred->args.reftime.kind = COMP_GT;
@@ -1533,7 +1539,7 @@ parse_newerXY (const struct parser_table* entry, char 
**argv, int *arg_ptr)
              (*arg_ptr)++;
            }
 
-         our_pred = insert_primary (entry);
+         our_pred = insert_primary (entry, argv[*arg_ptr]);
 
 
          switch (x)
@@ -1626,7 +1632,7 @@ parse_nogroup (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   (void) &argv;
   (void) &arg_ptr;
 
-  our_pred = insert_primary (entry);
+  our_pred = insert_primary (entry, NULL);
   our_pred->est_success_rate = 1e-4;
 #ifdef CACHE_IDS
   if (gid_unused == NULL)
@@ -1663,7 +1669,7 @@ parse_nouser (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   (void) arg_ptr;
 
 
-  our_pred = insert_primary (entry);
+  our_pred = insert_primary_noarg (entry);
   our_pred->est_success_rate = 1e-3;
 #ifdef CACHE_IDS
   if (uid_unused == NULL)
@@ -1719,7 +1725,7 @@ parse_openparen (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   (void) argv;
   (void) arg_ptr;
 
-  our_pred = get_new_pred_chk_op (entry);
+  our_pred = get_new_pred_chk_op (entry, NULL);
   our_pred->pred_func = pred_openparen;
   our_pred->p_type = OPEN_PAREN;
   our_pred->p_prec = NO_PREC;
@@ -1735,7 +1741,7 @@ parse_or (const struct parser_table* entry, char **argv, 
int *arg_ptr)
   (void) argv;
   (void) arg_ptr;
 
-  our_pred = get_new_pred (entry);
+  our_pred = get_new_pred_noarg (entry);
   our_pred->pred_func = pred_or;
   our_pred->p_type = BI_OP;
   our_pred->p_prec = OR_PREC;
@@ -1759,7 +1765,7 @@ parse_path (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   const char *name;
   if (collect_arg(argv, arg_ptr, &name))
     {
-      struct predicate *our_pred = insert_primary_withpred (entry, pred_path);
+      struct predicate *our_pred = insert_primary_withpred (entry, pred_path, 
name);
       our_pred->need_stat = our_pred->need_type = false;
       our_pred->args.str = name;
       our_pred->est_success_rate = estimate_pattern_match_rate (name, 0);
@@ -1897,7 +1903,7 @@ parse_perm (const struct parser_table* entry, char 
**argv, int *arg_ptr)
       rate = 0.9986; /* probably matches anything but a broken symlink */
     }
 
-  our_pred = insert_primary (entry);
+  our_pred = insert_primary (entry, perm_expr);
   our_pred->est_success_rate = rate;
   if (havekind)
     {
@@ -1931,7 +1937,7 @@ parse_print (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   (void) argv;
   (void) arg_ptr;
 
-  our_pred = insert_primary (entry);
+  our_pred = insert_primary_noarg (entry);
   /* -print has the side effect of printing.  This prevents us
      from doing undesired multiple printing when the user has
      already specified -print. */
@@ -1984,7 +1990,7 @@ parse_prune (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   (void) argv;
   (void) arg_ptr;
 
-  our_pred = insert_primary (entry);
+  our_pred = insert_primary_noarg (entry);
   if (options.do_dir_first == false)
     our_pred->need_stat = our_pred->need_type = false;
   /* -prune has a side effect that it does not descend into
@@ -1997,7 +2003,7 @@ parse_prune (const struct parser_table* entry, char 
**argv, int *arg_ptr)
 static boolean
 parse_quit  (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
-  struct predicate *our_pred = insert_primary (entry);
+  struct predicate *our_pred = insert_primary_noarg (entry);
   (void) argv;
   (void) arg_ptr;
   our_pred->need_stat = our_pred->need_type = false;
@@ -2039,7 +2045,7 @@ insert_regex (char **argv,
     {
       struct re_pattern_buffer *re;
       const char *error_message;
-      struct predicate *our_pred = insert_primary_withpred (entry, pred_regex);
+      struct predicate *our_pred = insert_primary_withpred (entry, pred_regex, 
rx);
       our_pred->need_stat = our_pred->need_type = false;
       re = xmalloc (sizeof (struct re_pattern_buffer));
       our_pred->args.regex = re;
@@ -2064,6 +2070,7 @@ static boolean
 parse_size (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
   struct predicate *our_pred;
+  char *arg;
   uintmax_t num;
   char suffix;
   enum comparison_type c_type;
@@ -2076,42 +2083,43 @@ parse_size (const struct parser_table* entry, char 
**argv, int *arg_ptr)
    */
   if ((argv == NULL) || (argv[*arg_ptr] == NULL))
     return false;
+  arg = argv[*arg_ptr];
 
-  len = strlen (argv[*arg_ptr]);
+  len = strlen (arg);
   if (len == 0)
     error (1, 0, _("invalid null argument to -size"));
 
-  suffix = argv[*arg_ptr][len - 1];
+  suffix = arg[len - 1];
   switch (suffix)
     {
     case 'b':
       blksize = 512;
-      argv[*arg_ptr][len - 1] = '\0';
+      arg[len - 1] = '\0';
       break;
 
     case 'c':
       blksize = 1;
-      argv[*arg_ptr][len - 1] = '\0';
+      arg[len - 1] = '\0';
       break;
 
     case 'k':
       blksize = 1024;
-      argv[*arg_ptr][len - 1] = '\0';
+      arg[len - 1] = '\0';
       break;
 
     case 'M':                  /* Megabytes */
       blksize = 1024*1024;
-      argv[*arg_ptr][len - 1] = '\0';
+      arg[len - 1] = '\0';
       break;
 
     case 'G':                  /* Gigabytes */
       blksize = 1024*1024*1024;
-      argv[*arg_ptr][len - 1] = '\0';
+      arg[len - 1] = '\0';
       break;
 
     case 'w':
       blksize = 2;
-      argv[*arg_ptr][len - 1] = '\0';
+      arg[len - 1] = '\0';
       break;
 
     case '0':
@@ -2130,14 +2138,14 @@ parse_size (const struct parser_table* entry, char 
**argv, int *arg_ptr)
       error (1, 0, _("invalid -size type `%c'"), argv[*arg_ptr][len - 1]);
     }
   /* TODO: accept fractional megabytes etc. ? */
-  if (!get_num (argv[*arg_ptr], &num, &c_type))
+  if (!get_num (arg, &num, &c_type))
     {
       error(1, 0,
            _("Invalid argument `%s%c' to -size"),
-           argv[*arg_ptr], (int)suffix);
+           arg, (int)suffix);
       return false;
     }
-  our_pred = insert_primary (entry);
+our_pred = insert_primary (entry, arg);
   our_pred->args.size.kind = c_type;
   our_pred->args.size.blocksize = blksize;
   our_pred->args.size.size = num;
@@ -2165,9 +2173,10 @@ parse_samefile (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   struct predicate *our_pred;
   struct stat st, fst;
   int fd, openflags;
+  const char *filename;
 
   set_stat_placeholders(&st);
-  if (!collect_arg_stat_info(argv, arg_ptr, &st))
+  if (!collect_arg_stat_info(argv, arg_ptr, &st, &filename))
     return false;
 
   set_stat_placeholders(&fst);
@@ -2292,7 +2301,7 @@ parse_samefile (const struct parser_table* entry, char 
**argv, int *arg_ptr)
        }
     }
 
-  our_pred = insert_primary (entry);
+  our_pred = insert_primary (entry, filename);
   our_pred->args.samefileid.ino = st.st_ino;
   our_pred->args.samefileid.dev = st.st_dev;
   our_pred->args.samefileid.fd  = fd;
@@ -2355,7 +2364,7 @@ parse_true (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   (void) argv;
   (void) arg_ptr;
 
-  our_pred = insert_primary (entry);
+  our_pred = insert_primary_noarg (entry);
   our_pred->need_stat = our_pred->need_type = false;
   our_pred->est_success_rate = 1.0f;
   return true;
@@ -2374,7 +2383,7 @@ parse_accesscheck (const struct parser_table* entry, char 
**argv, int *arg_ptr)
   struct predicate *our_pred;
   (void) argv;
   (void) arg_ptr;
-  our_pred = insert_primary (entry);
+  our_pred = insert_primary_noarg (entry);
   our_pred->need_stat = our_pred->need_type = false;
   our_pred->side_effects = our_pred->no_default_print = false;
   if (pred_is(our_pred, pred_executable))
@@ -2419,7 +2428,7 @@ parse_used (const struct parser_table* entry, char 
**argv, int *arg_ptr)
       struct timespec zero = {0,0};
       if (get_relative_timestamp(offset_str, &tval, zero, DAYSECS, errmsg))
        {
-         our_pred = insert_primary (entry);
+         our_pred = insert_primary (entry, offset_str);
          our_pred->args.reftime = tval;
          our_pred->est_success_rate = 
estimate_file_age_success_rate(tval.ts.tv_sec / DAYSECS);
          return true;
@@ -2477,7 +2486,7 @@ parse_user (const struct parser_table* entry, char 
**argv, int *arg_ptr)
              return false;
            }
        }
-      our_pred = insert_primary (entry);
+      our_pred = insert_primary (entry, username);
       our_pred->args.uid = uid;
       our_pred->est_success_rate = (our_pred->args.uid < 100) ? 0.99 : 0.2;
       return true;
@@ -2655,7 +2664,7 @@ insert_type (char **argv, int *arg_ptr,
          error(1, 0, _("Unknown argument to -type: %c"), (*typeletter));
          return false;
        }
-      our_pred = insert_primary_withpred (entry, which_pred);
+      our_pred = insert_primary_withpred (entry, which_pred, typeletter);
       our_pred->est_success_rate = rate;
 
       /* Figure out if we will need to stat the file, because if we don't
@@ -2711,7 +2720,7 @@ insert_fprintf (struct format_val *vec,
   struct segment **segmentp;   /* Address of current segment. */
   struct predicate *our_pred;
 
-  our_pred = insert_primary_withpred (entry, func);
+  our_pred = insert_primary_withpred (entry, func, format_const);
   our_pred->side_effects = our_pred->no_default_print = true;
   our_pred->args.printf_vec = *vec;
   our_pred->need_type = false;
@@ -3055,7 +3064,7 @@ new_insert_exec_ok (const char *action,
   if ((argv == NULL) || (argv[*arg_ptr] == NULL))
     return false;
 
-  our_pred = insert_primary_withpred (entry, func);
+  our_pred = insert_primary_withpred (entry, func, "(some -exec* arguments)");
   our_pred->side_effects = our_pred->no_default_print = true;
   our_pred->need_type = our_pred->need_stat = false;
 
@@ -3384,7 +3393,7 @@ parse_time (const struct parser_table* entry, char 
*argv[], int *arg_ptr)
   if (!get_relative_timestamp(timearg, &tval, origin, DAYSECS, errmsg))
     return false;
 
-  our_pred = insert_primary (entry);
+  our_pred = insert_primary (entry, orig_timearg);
   our_pred->args.reftime = tval;
   our_pred->est_success_rate = estimate_timestamp_success_rate(tval.ts.tv_sec);
 
@@ -3497,7 +3506,7 @@ insert_num (char **argv, int *arg_ptr, const struct 
parser_table *entry)
 
     if (get_num (numstr, &num, &c_type))
       {
-       struct predicate *our_pred = insert_primary (entry);
+       struct predicate *our_pred = insert_primary (entry, numstr);
        our_pred->args.numinfo.kind = c_type;
        our_pred->args.numinfo.l_val = num;
 
diff --git a/find/tree.c b/find/tree.c
index 929c5f6..aa1c535 100644
--- a/find/tree.c
+++ b/find/tree.c
@@ -269,10 +269,14 @@ predicate_is_cost_free(const struct predicate *p)
 /* Prints a predicate */
 void print_predicate(FILE *fp, const struct predicate *p)
 {
-  fprintf (fp, "%s%s%s",
-          p->p_name,
-          p->arg_text ? " " : "",
-          p->arg_text ? p->arg_text : "");
+  if (p->arg_text)
+    {
+      fprintf (fp, "%s %s", p->p_name, p->arg_text);
+    }
+  else
+    {
+      fprintf (fp, "%s", p->p_name);
+    }
 }
 
 
@@ -834,6 +838,7 @@ set_new_parent (struct predicate *curr, enum 
predicate_precedence high_prec, str
   new_parent->need_type = false;
   new_parent->need_inum = false;
   new_parent->p_cost = NeedsNothing;
+  new_parent->arg_text = NULL;
 
   switch (high_prec)
     {
@@ -1399,6 +1404,18 @@ init_pred_perf(struct predicate *pred)
   p->visits = p->successes = 0;
 }
 
+
+struct predicate *
+get_new_pred_noarg (const struct parser_table *entry)
+{
+  struct predicate *p = get_new_pred(entry);
+  if (p)
+    {
+      p->arg_text = NULL;
+    }
+  return p;
+}
+
 
 /* Return a pointer to a new predicate structure, which has been
    linked in as the last one in the predicates list.
@@ -1440,6 +1457,8 @@ get_new_pred (const struct parser_table *entry)
   last_pred->need_stat = true;
   last_pred->need_type = true;
   last_pred->need_inum = false;
+  last_pred->p_cost = NeedsUnknown;
+  last_pred->arg_text = "ThisShouldBeSetToSomethingElse";
   last_pred->args.str = NULL;
   last_pred->pred_next = NULL;
   last_pred->pred_left = NULL;
@@ -1456,7 +1475,8 @@ get_new_pred (const struct parser_table *entry)
    predicate is an operator.  If it isn't, the AND operator is inserted. */
 
 struct predicate *
-get_new_pred_chk_op (const struct parser_table *entry)
+get_new_pred_chk_op (const struct parser_table *entry,
+                    const char *arg)
 {
   struct predicate *new_pred;
   static const struct parser_table *entry_and = NULL;
@@ -1478,7 +1498,7 @@ get_new_pred_chk_op (const struct parser_table *entry)
       case PRIMARY_TYPE:
       case CLOSE_PAREN:
        /* We need to interpose the and operator. */
-       new_pred = get_new_pred (entry_and);
+       new_pred = get_new_pred_noarg (entry_and);
        new_pred->pred_func = pred_and;
        new_pred->p_name = "-a";
        new_pred->p_type = BI_OP;
@@ -1486,6 +1506,7 @@ get_new_pred_chk_op (const struct parser_table *entry)
        new_pred->need_stat = false;
        new_pred->need_type = false;
        new_pred->need_inum = false;
+       new_pred->arg_text = NULL;
        new_pred->args.str = NULL;
        new_pred->side_effects = false;
        new_pred->no_default_print = false;
@@ -1496,6 +1517,7 @@ get_new_pred_chk_op (const struct parser_table *entry)
       }
 
   new_pred = get_new_pred (entry);
+  new_pred->arg_text = arg;
   new_pred->parser_entry = entry;
   return new_pred;
 }
diff --git a/find/util.c b/find/util.c
index a6e4325..4a0bb9b 100644
--- a/find/util.c
+++ b/find/util.c
@@ -89,11 +89,13 @@ static struct debug_option_assoc debugassoc[] =
    operator. */
 
 struct predicate *
-insert_primary_withpred (const struct parser_table *entry, PRED_FUNC pred_func)
+insert_primary_withpred (const struct parser_table *entry,
+                        PRED_FUNC pred_func,
+                        const char *arg)
 {
   struct predicate *new_pred;
 
-  new_pred = get_new_pred_chk_op (entry);
+  new_pred = get_new_pred_chk_op (entry, arg);
   new_pred->pred_func = pred_func;
   new_pred->p_name = entry->parser_name;
   new_pred->args.str = NULL;
@@ -118,10 +120,16 @@ insert_primary_withpred (const struct parser_table 
*entry, PRED_FUNC pred_func)
    either not there at all (we are the very first node) or is an
    operator. */
 struct predicate *
-insert_primary (const struct parser_table *entry)
+insert_primary (const struct parser_table *entry, const char *arg)
 {
   assert (entry->pred_func != NULL);
-  return insert_primary_withpred(entry, entry->pred_func);
+  return insert_primary_withpred(entry, entry->pred_func, arg);
+}
+
+struct predicate *
+insert_primary_noarg (const struct parser_table *entry)
+{
+  return insert_primary(entry, NULL);
 }
 
 
-- 
1.5.6.5





reply via email to

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