Fix Savannah bug #27017: find -D opt / -fstype ext3 -print , -quit coredump (vs. 4.5.x)

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.
This commit is contained in:
James Youngman
2009-07-11 19:55:27 +01:00
parent 9986eefc62
commit a9ffeaf3cf
5 changed files with 185 additions and 70 deletions

View File

@@ -1,3 +1,48 @@
2009-07-11 James Youngman <jay@gnu.org>
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-12 James Youngman <jay@gnu.org>
Savannah bug #23920: warn about -path arguments ending in /.

View File

@@ -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. */
@@ -485,13 +485,16 @@ void show_success_rates(const struct predicate *node);
boolean matches_start_point(const char * glob, boolean foldcase);
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);

View File

@@ -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);
@@ -1258,6 +1263,34 @@ parse_inum (const struct parser_table* entry, char **argv, int *arg_ptr)
}
}
/* -ipath is deprecated (at RMS's request) in favour of
* -iwholename. See the node "GNU Manuals" in standards.texi
* for the rationale for this (basically, GNU prefers the use
* of the phrase "file name" to "path name"
*/
static boolean
parse_ipath (const struct parser_table* entry, char **argv, int *arg_ptr)
{
const char *name;
fnmatch_sanitycheck ();
if (collect_arg (argv, arg_ptr, &name))
{
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);
return true;
}
return false;
}
static boolean
parse_iwholename (const struct parser_table* entry, char **argv, int *arg_ptr)
{
return parse_ipath (entry, argv, arg_ptr);
}
static boolean
parse_iregex (const struct parser_table* entry, char **argv, int *arg_ptr)
{
@@ -1291,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;
@@ -1366,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;
@@ -1402,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);
@@ -1420,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;
@@ -1433,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;
@@ -1505,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)
@@ -1598,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)
@@ -1635,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)
@@ -1691,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;
@@ -1707,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;
@@ -1931,7 +1965,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)
{
@@ -1965,7 +1999,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. */
@@ -2018,7 +2052,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
@@ -2031,7 +2065,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;
@@ -2073,7 +2107,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;
@@ -2098,6 +2132,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;
@@ -2110,42 +2145,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':
@@ -2164,14 +2200,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;
@@ -2199,9 +2235,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);
@@ -2326,7 +2363,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;
@@ -2389,7 +2426,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;
@@ -2408,7 +2445,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))
@@ -2453,7 +2490,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;
@@ -2511,7 +2548,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;
@@ -2689,7 +2726,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
@@ -2745,7 +2782,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;
@@ -3089,7 +3126,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;
@@ -3418,7 +3455,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);
@@ -3531,7 +3568,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;

View File

@@ -303,10 +303,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);
}
}
@@ -868,6 +872,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)
{
@@ -1435,6 +1440,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.
@@ -1476,6 +1493,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;
@@ -1492,7 +1511,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;
@@ -1514,7 +1534,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;
@@ -1522,6 +1542,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;
@@ -1532,6 +1553,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;
}

View File

@@ -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);
}