find中的数据结构
struct predicate
{
/* Pointer to the function that implements this predicate. */
PRED_FUNC pred_func;
/* Used for debugging */
const char *p_name;
/* The type of this node. There are two kinds. The first is real
predicates ("primaries") such as -perm, -print, or -exec. The
other kind is operators for combining predicates. */
enum predicate_type p_type;
/* The precedence of this node. Only has meaning for operators. */
enum predicate_precedence p_prec;
/* True if this predicate node produces side effects.
If side_effects are produced
then optimization will not be performed */
bool side_effects;
/* True if this predicate node requires default print be turned off. */
bool no_default_print;
/* True if this predicate node requires a stat system call to execute. */
bool need_stat;
/* True if this predicate node requires knowledge of the file type. */
bool need_type;
/* True if this predicate node requires knowledge of the inode number. */
bool need_inum;
enum EvaluationCost p_cost;
/* est_success_rate is a number between 0.0 and 1.0 */
float est_success_rate;
/* True if this predicate should display control characters literally */
bool literal_control_chars;
/* True if this predicate didn't originate from the user. */
bool artificial;
/* The raw text of the argument of this predicate. */
const char *arg_text;
/* Information needed by the predicate processor.
Next to each member are listed the predicates that use it. */
union
{
const char *str; /* fstype [i]lname [i]name [i]path */
struct re_pattern_buffer *regex; /* regex */
struct exec_val exec_vec; /* exec ok */
struct long_val numinfo; /* gid inum links uid */
struct size_val size; /* size */
uid_t uid; /* user */
gid_t gid; /* group */
struct time_val reftime; /* newer newerXY anewer cnewer mtime atime ctime mmin amin cmin */
struct perm_val perm; /* perm */
struct samefile_file_id samefileid; /* samefile */
bool types[FTYPE_COUNT]; /* file type(s) */
struct format_val printf_vec; /* printf fprintf fprint ls fls print0 fprint0 print */
char *scontext; /* security context */
} args;
/* The next predicate in the user input sequence,
which represents the order in which the user supplied the
predicates on the command line. */
struct predicate *pred_next;
/* The right and left branches from this node in the expression
tree, which represents the order in which the nodes should be
processed. */
struct predicate *pred_left;
struct predicate *pred_right;
struct predicate_performance_info perf;
const struct parser_table* parser_entry;
};
struct parser_table
{
enum arg_type type;
const char *parser_name;
PARSE_FUNC parser_func;
PRED_FUNC pred_func;
};
static struct parser_table const parse_table[] =
{
PARSE_PUNCTUATION("!", negate), /* POSIX */
PARSE_PUNCTUATION("not", negate), /* GNU */
PARSE_PUNCTUATION("(", openparen), /* POSIX */
PARSE_PUNCTUATION(")", closeparen), /* POSIX */
PARSE_PUNCTUATION(",", comma), /* GNU */
PARSE_PUNCTUATION("a", and), /* POSIX */
PARSE_TEST ("amin", amin), /* GNU */
PARSE_PUNCTUATION("and", and), /* GNU */
PARSE_TEST ("anewer", anewer), /* GNU */
{ARG_TEST, "atime", parse_time, pred_atime}, /* POSIX */
PARSE_TEST ("cmin", cmin), /* GNU */
PARSE_TEST ("cnewer", cnewer), /* GNU */
{ARG_TEST, "ctime", parse_time, pred_ctime}, /* POSIX */
PARSE_TEST ("context", context), /* GNU */
PARSE_POSOPT ("daystart", daystart), /* GNU */
PARSE_ACTION ("delete", delete), /* GNU, Mac OS, FreeBSD */
PARSE_OPTION ("d", d), /* Mac OS X, FreeBSD, NetBSD, OpenBSD, but deprecated in favour of -depth */
PARSE_OPTION ("depth", depth), /* POSIX */
PARSE_TEST ("empty", empty), /* GNU */
{ARG_ACTION, "exec", parse_exec, pred_exec}, /* POSIX */
{ARG_TEST, "executable", parse_accesscheck, pred_executable}, /* GNU, 4.3.0+ */
PARSE_ACTION ("execdir", execdir), /* *BSD, GNU */
PARSE_ACTION ("fls", fls), /* GNU */
PARSE_POSOPT ("follow", follow), /* GNU, Unix */
PARSE_ACTION ("fprint", fprint), /* GNU */
PARSE_ACTION ("fprint0", fprint0), /* GNU */
{ARG_ACTION, "fprintf", parse_fprintf, pred_fprintf}, /* GNU */
PARSE_TEST ("fstype", fstype), /* GNU, Unix */
PARSE_TEST ("gid", gid), /* GNU */
PARSE_TEST ("group", group), /* POSIX */
PARSE_OPTION ("ignore_readdir_race", ignore_race), /* GNU */
PARSE_TEST ("ilname", ilname), /* GNU */
PARSE_TEST ("iname", iname), /* GNU */
PARSE_TEST ("inum", inum), /* GNU, Unix */
PARSE_TEST ("ipath", ipath), /* GNU, deprecated in favour of iwholename */
PARSE_TEST_NP ("iregex", iregex), /* GNU */
PARSE_TEST_NP ("iwholename", iwholename), /* GNU */
PARSE_TEST ("links", links), /* POSIX */
PARSE_TEST ("lname", lname), /* GNU */
PARSE_ACTION ("ls", ls), /* GNU, Unix */
PARSE_OPTION ("maxdepth", maxdepth), /* GNU */
PARSE_OPTION ("mindepth", mindepth), /* GNU */
PARSE_TEST ("mmin", mmin), /* GNU */
PARSE_OPTION ("mount", xdev), /* Unix */
{ARG_TEST, "mtime", parse_time, pred_mtime}, /* POSIX */
PARSE_TEST ("name", name),
#ifdef UNIMPLEMENTED_UNIX
PARSE(ARG_UNIMPLEMENTED, "ncpio", ncpio), /* Unix */
#endif
PARSE_TEST ("newer", newer), /* POSIX */
{ARG_TEST, "atime", parse_time, pred_atime}, /* POSIX */
PARSE_OPTION ("noleaf", noleaf), /* GNU */
PARSE_TEST ("nogroup", nogroup), /* POSIX */
PARSE_TEST ("nouser", nouser), /* POSIX */
PARSE_OPTION ("noignore_readdir_race", noignore_race), /* GNU */
PARSE_POSOPT ("nowarn", nowarn), /* GNU */
PARSE_POSOPT ("warn", warn), /* GNU */
PARSE_PUNCTUATION("o", or), /* POSIX */
PARSE_PUNCTUATION("or", or), /* GNU */
PARSE_ACTION ("ok", ok), /* POSIX */
PARSE_ACTION ("okdir", okdir), /* GNU (-execdir is BSD) */
PARSE_TEST ("path", path), /* POSIX */
PARSE_TEST ("perm", perm), /* POSIX */
PARSE_ACTION ("print", print), /* POSIX */
PARSE_ACTION ("print0", print0), /* GNU */
{ARG_ACTION, "printf", parse_printf, NULL}, /* GNU */
PARSE_ACTION ("prune", prune), /* POSIX */
PARSE_ACTION ("quit", quit), /* GNU */
{ARG_TEST, "readable", parse_accesscheck, pred_readable}, /* GNU, 4.3.0+ */
PARSE_TEST ("regex", regex), /* GNU */
PARSE_POSOPT ("regextype", regextype), /* GNU */
PARSE_TEST ("samefile", samefile), /* GNU */
#if 0
PARSE_OPTION ("show-control-chars", show_control_chars), /* GNU, 4.3.0+ */
#endif
PARSE_TEST ("size", size), /* POSIX */
PARSE_TEST ("type", type), /* POSIX */
PARSE_TEST ("uid", uid), /* GNU */
PARSE_TEST ("used", used), /* GNU */
PARSE_TEST ("user", user), /* POSIX */
PARSE_TEST_NP ("wholename", wholename), /* GNU, replaced -path, but now -path is standardized since POSIX 2008 */
{ARG_TEST, "writable", parse_accesscheck, pred_writable}, /* GNU, 4.3.0+ */
PARSE_OPTION ("xdev", xdev), /* POSIX */
PARSE_OPTION ("xautofs", xautofs),
PARSE_TEST ("xtype", xtype), /* GNU */
#ifdef UNIMPLEMENTED_UNIX
/* It's pretty ugly for find to know about archive formats.
Plus what it could do with cpio archives is very limited.
Better to leave it out. */
PARSE(ARG_UNIMPLEMENTED, "cpio", cpio), /* Unix */
#endif
/* gnulib's stdbool.h might have made true and false into macros,
* so we can't leave named 'true' and 'false' tokens, so we have
* to expeant the relevant entries longhand.
*/
{ARG_TEST, "false", parse_false, pred_false}, /* GNU */
{ARG_TEST, "true", parse_true, pred_true }, /* GNU */
/* Internal pseudo-option, therefore 3 minus: ---noop. */
{ARG_NOOP, "--noop", NULL, pred_true }, /* GNU, internal use only */
/* Various other cases that don't fit neatly into our macro scheme. */
{ARG_TEST, "help", parse_help, NULL}, /* GNU */
{ARG_TEST, "-help", parse_help, NULL}, /* GNU */
{ARG_TEST, "version", parse_version, NULL}, /* GNU */
{ARG_TEST, "-version", parse_version, NULL}, /* GNU */
{0, 0, 0, 0}
};
xargs中的数据结构
struct buildcmd_state
{
/* Number of valid elements in `cmd_argv', including terminating NULL. */
size_t cmd_argc; /* 0 */
/* The list of args being built. */
char **cmd_argv; /* NULL */
/* Number of elements allocated for `cmd_argv'. */
size_t cmd_argv_alloc;
/* Storage for elements of `cmd_argv'. */
char *argbuf;
/* Number of chars being used in `cmd_argv'. */
size_t cmd_argv_chars;
/* Number of chars being used in `cmd_argv' for the initial args.. */
size_t cmd_initial_argv_chars;
/* User context information. */
void *usercontext;
/* to-do flag. */
int todo;
/* Directory in which to perform the exec. */
int dir_fd;
/* Summary of what we think the argv limits are. */
size_t largest_successful_arg_count;
size_t smallest_failed_arg_count;
};
struct option
{
const char *name;
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
static struct option const longopts[] =
{
{"null", no_argument, NULL, '0'},
{"arg-file", required_argument, NULL, 'a'},
{"delimiter", required_argument, NULL, 'd'},
{"eof", optional_argument, NULL, 'e'},
{"replace", optional_argument, NULL, 'I'},
{"max-lines", optional_argument, NULL, 'l'},
{"max-args", required_argument, NULL, 'n'},
{"open-tty", no_argument, NULL, 'o'},
{"interactive", no_argument, NULL, 'p'},
{"no-run-if-empty", no_argument, NULL, 'r'},
{"max-chars", required_argument, NULL, 's'},
{"verbose", no_argument, NULL, 't'},
{"show-limits", no_argument, NULL, 'S'},
{"exit", no_argument, NULL, 'x'},
{"max-procs", required_argument, NULL, 'P'},
{"process-slot-var", required_argument, NULL, PROCESS_SLOT_VAR},
{"version", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, no_argument, NULL, 0}
};