commit af974034b68bf59337c7a384e488a518a77dfecd Author: James Youngman Date: Sat Jul 11 19:55:27 2009 +0100 Fix Savannah bug #27017: find -D opt / -fstype ext3 -print , -quit coredump. 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. diff --git a/ChangeLog b/ChangeLog index 6e346b8..e8ba0f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,0 +1,45 @@ +2009-07-11 James Youngman + + 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. + diff --git a/find/defs.h b/find/defs.h index 1708d83..4539fd9 100644 --- a/find/defs.h +++ b/find/defs.h @@ -297,7 +297,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. */ @@ -480,13 +480,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 534b670..2e6b989 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); @@ -1268,7 +1273,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); @@ -1316,7 +1321,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; @@ -1391,7 +1396,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; @@ -1427,7 +1432,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); @@ -1445,7 +1450,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; @@ -1458,11 +1463,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; @@ -1530,7 +1536,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) @@ -1623,7 +1629,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) @@ -1660,7 +1666,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) @@ -1716,7 +1722,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; @@ -1732,7 +1738,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; @@ -1756,7 +1762,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); @@ -1894,7 +1900,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) { @@ -1928,7 +1934,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. */ @@ -1981,7 +1987,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 @@ -1994,7 +2000,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; @@ -2036,7 +2042,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; @@ -2061,6 +2067,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; @@ -2073,42 +2080,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': @@ -2127,14 +2135,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; @@ -2162,9 +2170,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); @@ -2289,7 +2298,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; @@ -2350,7 +2359,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; @@ -2369,7 +2378,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)) @@ -2414,7 +2423,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; @@ -2472,7 +2481,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; @@ -2650,7 +2659,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 @@ -2706,7 +2715,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; @@ -3045,7 +3054,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; @@ -3374,7 +3383,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); @@ -3487,7 +3496,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 7420c60..60a0601 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); + } } @@ -832,7 +836,8 @@ set_new_parent (struct predicate *curr, enum predicate_precedence high_prec, str new_parent->need_stat = false; new_parent->need_type = false; new_parent->p_cost = NeedsNothing; - + new_parent->arg_text = NULL; + switch (high_prec) { case COMMA_PREC: @@ -1393,6 +1398,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. @@ -1433,6 +1450,8 @@ get_new_pred (const struct parser_table *entry) last_pred->no_default_print = false; last_pred->need_stat = true; last_pred->need_type = true; + 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; @@ -1449,7 +1468,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; @@ -1471,13 +1491,14 @@ 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; new_pred->p_prec = AND_PREC; new_pred->need_stat = false; new_pred->need_type = false; + new_pred->arg_text = NULL; new_pred->args.str = NULL; new_pred->side_effects = false; new_pred->no_default_print = false; @@ -1488,6 +1509,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 a06eada..cc9a3eb 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); }