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