untypedef expr, find, test, as is existing style in sbase
This commit is contained in:
parent
93fd817536
commit
cf5114a133
68
expr.c
68
expr.c
|
@ -12,15 +12,15 @@ enum {
|
||||||
VAL = CHAR_MAX + 1, GE, LE, NE
|
VAL = CHAR_MAX + 1, GE, LE, NE
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct val {
|
||||||
char *s; /* iff s is NULL, Val is an integer */
|
char *s; /* iff s is NULL, val is an integer */
|
||||||
intmax_t n;
|
intmax_t n;
|
||||||
} Val;
|
};
|
||||||
|
|
||||||
static size_t intlen;
|
static size_t intlen;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
enan(Val v)
|
enan(struct val v)
|
||||||
{
|
{
|
||||||
if (v.s)
|
if (v.s)
|
||||||
enprintf(2, "syntax error: expected integer got `%s'\n", v.s);
|
enprintf(2, "syntax error: expected integer got `%s'\n", v.s);
|
||||||
|
@ -34,7 +34,7 @@ ezero(intmax_t n)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
valstr(Val val, char *buf, size_t bufsiz)
|
valstr(struct val val, char *buf, size_t bufsiz)
|
||||||
{
|
{
|
||||||
if (val.s)
|
if (val.s)
|
||||||
return val.s;
|
return val.s;
|
||||||
|
@ -43,7 +43,7 @@ valstr(Val val, char *buf, size_t bufsiz)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
valcmp(Val a, Val b)
|
valcmp(struct val a, struct val b)
|
||||||
{
|
{
|
||||||
char buf1[intlen], buf2[intlen];
|
char buf1[intlen], buf2[intlen];
|
||||||
char *astr = valstr(a, buf1, sizeof(buf1));
|
char *astr = valstr(a, buf1, sizeof(buf1));
|
||||||
|
@ -59,8 +59,8 @@ valcmp(Val a, Val b)
|
||||||
* then return the text matched by it \1 (empty string for no match)
|
* then return the text matched by it \1 (empty string for no match)
|
||||||
* else return number of characters matched (0 for no match)
|
* else return number of characters matched (0 for no match)
|
||||||
*/
|
*/
|
||||||
static Val
|
static struct val
|
||||||
match(Val vstr, Val vregx)
|
match(struct val vstr, struct val vregx)
|
||||||
{
|
{
|
||||||
regex_t re;
|
regex_t re;
|
||||||
regmatch_t matches[2];
|
regmatch_t matches[2];
|
||||||
|
@ -76,7 +76,7 @@ match(Val vstr, Val vregx)
|
||||||
|
|
||||||
if (regexec(&re, str, 2, matches, 0)) {
|
if (regexec(&re, str, 2, matches, 0)) {
|
||||||
regfree(&re);
|
regfree(&re);
|
||||||
return (Val){ (re.re_nsub ? "" : NULL), 0 };
|
return (struct val){ (re.re_nsub ? "" : NULL), 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (re.re_nsub) {
|
if (re.re_nsub) {
|
||||||
|
@ -87,15 +87,15 @@ match(Val vstr, Val vregx)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
d = strtoimax(s, &p, 10);
|
d = strtoimax(s, &p, 10);
|
||||||
if (*s && !*p) /* string matched by subexpression is an integer */
|
if (*s && !*p) /* string matched by subexpression is an integer */
|
||||||
return (Val){ NULL, d };
|
return (struct val){ NULL, d };
|
||||||
|
|
||||||
/* FIXME? string is never free()d, worth fixing?
|
/* FIXME? string is never free()d, worth fixing?
|
||||||
* need to allocate as it could be in buf1 instead of vstr.s */
|
* need to allocate as it could be in buf1 instead of vstr.s */
|
||||||
return (Val){ enstrdup(3, s), 0 };
|
return (struct val){ enstrdup(3, s), 0 };
|
||||||
}
|
}
|
||||||
regfree(&re);
|
regfree(&re);
|
||||||
str += matches[0].rm_so;
|
str += matches[0].rm_so;
|
||||||
return (Val){ NULL, utfnlen(str, matches[0].rm_eo - matches[0].rm_so) };
|
return (struct val){ NULL, utfnlen(str, matches[0].rm_eo - matches[0].rm_so) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ops points to a stack of operators, opp points to one past the last op
|
/* ops points to a stack of operators, opp points to one past the last op
|
||||||
|
@ -105,9 +105,9 @@ match(Val vstr, Val vregx)
|
||||||
* pop operator, pop two values, apply operator, push result
|
* pop operator, pop two values, apply operator, push result
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
doop(int *ops, int **opp, Val *vals, Val **valp)
|
doop(int *ops, int **opp, struct val *vals, struct val **valp)
|
||||||
{
|
{
|
||||||
Val ret, a, b;
|
struct val ret, a, b;
|
||||||
int op;
|
int op;
|
||||||
|
|
||||||
/* For an operation, we need a valid operator
|
/* For an operation, we need a valid operator
|
||||||
|
@ -123,30 +123,30 @@ doop(int *ops, int **opp, Val *vals, Val **valp)
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case '|':
|
case '|':
|
||||||
if ( a.s && *a.s) ret = (Val){ a.s , 0 };
|
if ( a.s && *a.s) ret = (struct val){ a.s , 0 };
|
||||||
else if (!a.s && a.n) ret = (Val){ NULL, a.n };
|
else if (!a.s && a.n) ret = (struct val){ NULL, a.n };
|
||||||
else if ( b.s && *b.s) ret = (Val){ b.s , 0 };
|
else if ( b.s && *b.s) ret = (struct val){ b.s , 0 };
|
||||||
else ret = (Val){ NULL, b.n };
|
else ret = (struct val){ NULL, b.n };
|
||||||
break;
|
break;
|
||||||
case '&':
|
case '&':
|
||||||
if (((a.s && *a.s) || a.n) && ((b.s && *b.s) || b.n))
|
if (((a.s && *a.s) || a.n) && ((b.s && *b.s) || b.n))
|
||||||
ret = a;
|
ret = a;
|
||||||
else
|
else
|
||||||
ret = (Val){ NULL, 0 };
|
ret = (struct val){ NULL, 0 };
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '=': ret = (Val){ NULL, valcmp(a, b) == 0 }; break;
|
case '=': ret = (struct val){ NULL, valcmp(a, b) == 0 }; break;
|
||||||
case '>': ret = (Val){ NULL, valcmp(a, b) > 0 }; break;
|
case '>': ret = (struct val){ NULL, valcmp(a, b) > 0 }; break;
|
||||||
case GE : ret = (Val){ NULL, valcmp(a, b) >= 0 }; break;
|
case GE : ret = (struct val){ NULL, valcmp(a, b) >= 0 }; break;
|
||||||
case '<': ret = (Val){ NULL, valcmp(a, b) < 0 }; break;
|
case '<': ret = (struct val){ NULL, valcmp(a, b) < 0 }; break;
|
||||||
case LE : ret = (Val){ NULL, valcmp(a, b) <= 0 }; break;
|
case LE : ret = (struct val){ NULL, valcmp(a, b) <= 0 }; break;
|
||||||
case NE : ret = (Val){ NULL, valcmp(a, b) != 0 }; break;
|
case NE : ret = (struct val){ NULL, valcmp(a, b) != 0 }; break;
|
||||||
|
|
||||||
case '+': enan(a); enan(b); ret = (Val){ NULL, a.n + b.n }; break;
|
case '+': enan(a); enan(b); ret = (struct val){ NULL, a.n + b.n }; break;
|
||||||
case '-': enan(a); enan(b); ret = (Val){ NULL, a.n - b.n }; break;
|
case '-': enan(a); enan(b); ret = (struct val){ NULL, a.n - b.n }; break;
|
||||||
case '*': enan(a); enan(b); ret = (Val){ NULL, a.n * b.n }; break;
|
case '*': enan(a); enan(b); ret = (struct val){ NULL, a.n * b.n }; break;
|
||||||
case '/': enan(a); enan(b); ezero(b.n); ret = (Val){ NULL, a.n / b.n }; break;
|
case '/': enan(a); enan(b); ezero(b.n); ret = (struct val){ NULL, a.n / b.n }; break;
|
||||||
case '%': enan(a); enan(b); ezero(b.n); ret = (Val){ NULL, a.n % b.n }; break;
|
case '%': enan(a); enan(b); ezero(b.n); ret = (struct val){ NULL, a.n % b.n }; break;
|
||||||
|
|
||||||
case ':': ret = match(a, b); break;
|
case ':': ret = match(a, b); break;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ doop(int *ops, int **opp, Val *vals, Val **valp)
|
||||||
* if it is a value, place the value in v for use by parser
|
* if it is a value, place the value in v for use by parser
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
lex(char *s, Val *v)
|
lex(char *s, struct val *v)
|
||||||
{
|
{
|
||||||
intmax_t d;
|
intmax_t d;
|
||||||
char *p, *ops = "|&=><+-*/%():";
|
char *p, *ops = "|&=><+-*/%():";
|
||||||
|
@ -168,7 +168,7 @@ lex(char *s, Val *v)
|
||||||
/* clean integer */
|
/* clean integer */
|
||||||
d = strtoimax(s, &p, 10);
|
d = strtoimax(s, &p, 10);
|
||||||
if (*s && !*p) {
|
if (*s && !*p) {
|
||||||
*v = (Val){ NULL, d };
|
*v = (struct val){ NULL, d };
|
||||||
return VAL;
|
return VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ lex(char *s, Val *v)
|
||||||
if (!strcmp(s, "!=")) return NE;
|
if (!strcmp(s, "!=")) return NE;
|
||||||
|
|
||||||
/* nothing matched, treat as string */
|
/* nothing matched, treat as string */
|
||||||
*v = (Val){ s, 0 };
|
*v = (struct val){ s, 0 };
|
||||||
return VAL;
|
return VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ lex(char *s, Val *v)
|
||||||
static int
|
static int
|
||||||
parse(char *expr[], int exprlen)
|
parse(char *expr[], int exprlen)
|
||||||
{
|
{
|
||||||
Val vals[exprlen], *valp = vals, v;
|
struct val vals[exprlen], *valp = vals, v;
|
||||||
int ops[exprlen], *opp = ops;
|
int ops[exprlen], *opp = ops;
|
||||||
int i, type, lasttype = 0;
|
int i, type, lasttype = 0;
|
||||||
char prec[] = { /* precedence of operators */
|
char prec[] = { /* precedence of operators */
|
||||||
|
|
310
find.c
310
find.c
|
@ -17,75 +17,74 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/* because putting integers in pointers is undefined by the standard */
|
/* because putting integers in pointers is undefined by the standard */
|
||||||
typedef union {
|
union extra {
|
||||||
void *p;
|
void *p;
|
||||||
intptr_t i;
|
intptr_t i;
|
||||||
} Extra;
|
};
|
||||||
|
|
||||||
/* Argument passed into a primary's function */
|
/* Argument passed into a primary's function */
|
||||||
typedef struct {
|
struct arg {
|
||||||
char *path;
|
char *path;
|
||||||
struct stat *st;
|
struct stat *st;
|
||||||
Extra extra;
|
union extra extra;
|
||||||
} Arg;
|
};
|
||||||
|
|
||||||
/* Information about each primary, for lookup table */
|
/* Information about each primary, for lookup table */
|
||||||
typedef struct {
|
struct pri_info {
|
||||||
char *name;
|
char *name;
|
||||||
int (*func)(Arg *arg);
|
int (*func)(struct arg *arg);
|
||||||
char **(*getarg)(char **argv, Extra *extra);
|
char **(*getarg)(char **argv, union extra *extra);
|
||||||
void (*freearg)(Extra extra);
|
void (*freearg)(union extra extra);
|
||||||
char narg; /* -xdev, -depth, -print don't take args but have getarg() */
|
char narg; /* -xdev, -depth, -print don't take args but have getarg() */
|
||||||
} Pri_info;
|
};
|
||||||
|
|
||||||
/* Information about operators, for lookup table */
|
/* Information about operators, for lookup table */
|
||||||
typedef struct {
|
struct op_info {
|
||||||
char *name; /* string representation of op */
|
char *name; /* string representation of op */
|
||||||
char type; /* from Tok.type */
|
char type; /* from tok.type */
|
||||||
char prec; /* precedence */
|
char prec; /* precedence */
|
||||||
char nargs; /* number of arguments (unary or binary) */
|
char nargs; /* number of arguments (unary or binary) */
|
||||||
char lassoc; /* left associative */
|
char lassoc; /* left associative */
|
||||||
} Op_info;
|
};
|
||||||
|
|
||||||
/* Token when lexing/parsing
|
/* Token when lexing/parsing
|
||||||
* (although also used for the expression tree) */
|
* (although also used for the expression tree) */
|
||||||
typedef struct Tok Tok;
|
struct tok {
|
||||||
struct Tok {
|
struct tok *left, *right; /* if (type == NOT) left = NULL */
|
||||||
Tok *left, *right; /* if (type == NOT) left = NULL */
|
union extra extra;
|
||||||
Extra extra;
|
|
||||||
union {
|
union {
|
||||||
Pri_info *pinfo; /* if (type == PRIM) */
|
struct pri_info *pinfo; /* if (type == PRIM) */
|
||||||
Op_info *oinfo;
|
struct op_info *oinfo;
|
||||||
} u;
|
} u;
|
||||||
enum {
|
enum {
|
||||||
PRIM = 0, LPAR, RPAR, NOT, AND, OR, END
|
PRIM = 0, LPAR, RPAR, NOT, AND, OR, END
|
||||||
} type;
|
} type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* structures used for Arg.extra.p and Tok.extra.p */
|
/* structures used for arg.extra.p and tok.extra.p */
|
||||||
typedef struct {
|
struct permarg {
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
char exact;
|
char exact;
|
||||||
} Permarg;
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct okarg {
|
||||||
char ***braces;
|
char ***braces;
|
||||||
char **argv;
|
char **argv;
|
||||||
} Okarg;
|
};
|
||||||
|
|
||||||
/* for all arguments that take a number
|
/* for all arguments that take a number
|
||||||
* +n, n, -n mean > n, == n, < n respectively */
|
* +n, n, -n mean > n, == n, < n respectively */
|
||||||
typedef struct {
|
struct narg {
|
||||||
int (*cmp)(int a, int b);
|
int (*cmp)(int a, int b);
|
||||||
int n;
|
int n;
|
||||||
} Narg;
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct sizearg {
|
||||||
Narg n;
|
struct narg n;
|
||||||
char bytes; /* size is in bytes, not 512 byte sectors */
|
char bytes; /* size is in bytes, not 512 byte sectors */
|
||||||
} Sizearg;
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct execarg {
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
char ***braces; /* NULL terminated list of pointers into argv where {} were */
|
char ***braces; /* NULL terminated list of pointers into argv where {} were */
|
||||||
|
@ -100,76 +99,75 @@ typedef struct {
|
||||||
} u;
|
} u;
|
||||||
char **argv; /* NULL terminated list of arguments (allocated if isplus) */
|
char **argv; /* NULL terminated list of arguments (allocated if isplus) */
|
||||||
char isplus; /* -exec + instead of -exec ; */
|
char isplus; /* -exec + instead of -exec ; */
|
||||||
} Execarg;
|
};
|
||||||
|
|
||||||
/* used to find loops while recursing through directory structure */
|
/* used to find loops while recursing through directory structure */
|
||||||
typedef struct Findhist Findhist;
|
struct findhist {
|
||||||
struct Findhist {
|
struct findhist *next;
|
||||||
Findhist *next;
|
char *path;
|
||||||
char *path;
|
dev_t dev;
|
||||||
dev_t dev;
|
ino_t ino;
|
||||||
ino_t ino;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Primaries */
|
/* Primaries */
|
||||||
static int pri_name (Arg *arg);
|
static int pri_name (struct arg *arg);
|
||||||
static int pri_path (Arg *arg);
|
static int pri_path (struct arg *arg);
|
||||||
static int pri_nouser (Arg *arg);
|
static int pri_nouser (struct arg *arg);
|
||||||
static int pri_nogroup(Arg *arg);
|
static int pri_nogroup(struct arg *arg);
|
||||||
static int pri_xdev (Arg *arg);
|
static int pri_xdev (struct arg *arg);
|
||||||
static int pri_prune (Arg *arg);
|
static int pri_prune (struct arg *arg);
|
||||||
static int pri_perm (Arg *arg);
|
static int pri_perm (struct arg *arg);
|
||||||
static int pri_type (Arg *arg);
|
static int pri_type (struct arg *arg);
|
||||||
static int pri_links (Arg *arg);
|
static int pri_links (struct arg *arg);
|
||||||
static int pri_user (Arg *arg);
|
static int pri_user (struct arg *arg);
|
||||||
static int pri_group (Arg *arg);
|
static int pri_group (struct arg *arg);
|
||||||
static int pri_size (Arg *arg);
|
static int pri_size (struct arg *arg);
|
||||||
static int pri_atime (Arg *arg);
|
static int pri_atime (struct arg *arg);
|
||||||
static int pri_ctime (Arg *arg);
|
static int pri_ctime (struct arg *arg);
|
||||||
static int pri_mtime (Arg *arg);
|
static int pri_mtime (struct arg *arg);
|
||||||
static int pri_exec (Arg *arg);
|
static int pri_exec (struct arg *arg);
|
||||||
static int pri_ok (Arg *arg);
|
static int pri_ok (struct arg *arg);
|
||||||
static int pri_print (Arg *arg);
|
static int pri_print (struct arg *arg);
|
||||||
static int pri_newer (Arg *arg);
|
static int pri_newer (struct arg *arg);
|
||||||
static int pri_depth (Arg *arg);
|
static int pri_depth (struct arg *arg);
|
||||||
|
|
||||||
/* Getargs */
|
/* Getargs */
|
||||||
static char **get_name_arg (char *argv[], Extra *extra);
|
static char **get_name_arg (char *argv[], union extra *extra);
|
||||||
static char **get_path_arg (char *argv[], Extra *extra);
|
static char **get_path_arg (char *argv[], union extra *extra);
|
||||||
static char **get_xdev_arg (char *argv[], Extra *extra);
|
static char **get_xdev_arg (char *argv[], union extra *extra);
|
||||||
static char **get_perm_arg (char *argv[], Extra *extra);
|
static char **get_perm_arg (char *argv[], union extra *extra);
|
||||||
static char **get_type_arg (char *argv[], Extra *extra);
|
static char **get_type_arg (char *argv[], union extra *extra);
|
||||||
static char **get_n_arg (char *argv[], Extra *extra);
|
static char **get_n_arg (char *argv[], union extra *extra);
|
||||||
static char **get_user_arg (char *argv[], Extra *extra);
|
static char **get_user_arg (char *argv[], union extra *extra);
|
||||||
static char **get_group_arg(char *argv[], Extra *extra);
|
static char **get_group_arg(char *argv[], union extra *extra);
|
||||||
static char **get_size_arg (char *argv[], Extra *extra);
|
static char **get_size_arg (char *argv[], union extra *extra);
|
||||||
static char **get_exec_arg (char *argv[], Extra *extra);
|
static char **get_exec_arg (char *argv[], union extra *extra);
|
||||||
static char **get_ok_arg (char *argv[], Extra *extra);
|
static char **get_ok_arg (char *argv[], union extra *extra);
|
||||||
static char **get_print_arg(char *argv[], Extra *extra);
|
static char **get_print_arg(char *argv[], union extra *extra);
|
||||||
static char **get_newer_arg(char *argv[], Extra *extra);
|
static char **get_newer_arg(char *argv[], union extra *extra);
|
||||||
static char **get_depth_arg(char *argv[], Extra *extra);
|
static char **get_depth_arg(char *argv[], union extra *extra);
|
||||||
|
|
||||||
/* Freeargs */
|
/* Freeargs */
|
||||||
static void free_extra (Extra extra);
|
static void free_extra (union extra extra);
|
||||||
static void free_exec_arg(Extra extra);
|
static void free_exec_arg(union extra extra);
|
||||||
static void free_ok_arg (Extra extra);
|
static void free_ok_arg (union extra extra);
|
||||||
|
|
||||||
/* Parsing/Building/Running */
|
/* Parsing/Building/Running */
|
||||||
static void fill_narg(char *s, Narg *n);
|
static void fill_narg(char *s, struct narg *n);
|
||||||
static Pri_info *find_primary(char *name);
|
static struct pri_info *find_primary(char *name);
|
||||||
static Op_info *find_op(char *name);
|
static struct op_info *find_op(char *name);
|
||||||
static void parse(int argc, char **argv);
|
static void parse(int argc, char **argv);
|
||||||
static int eval(Tok *tok, Arg *arg);
|
static int eval(struct tok *tok, struct arg *arg);
|
||||||
static void find(char *path, Findhist *hist);
|
static void find(char *path, struct findhist *hist);
|
||||||
static void usage(void);
|
static void usage(void);
|
||||||
|
|
||||||
/* for comparisons with Narg */
|
/* for comparisons with narg */
|
||||||
static int cmp_gt(int a, int b) { return a > b; }
|
static int cmp_gt(int a, int b) { return a > b; }
|
||||||
static int cmp_eq(int a, int b) { return a == b; }
|
static int cmp_eq(int a, int b) { return a == b; }
|
||||||
static int cmp_lt(int a, int b) { return a < b; }
|
static int cmp_lt(int a, int b) { return a < b; }
|
||||||
|
|
||||||
/* order from find(1p), may want to alphabetize */
|
/* order from find(1p), may want to alphabetize */
|
||||||
static Pri_info primaries[] = {
|
static struct pri_info primaries[] = {
|
||||||
{ "-name" , pri_name , get_name_arg , NULL , 1 },
|
{ "-name" , pri_name , get_name_arg , NULL , 1 },
|
||||||
{ "-path" , pri_path , get_path_arg , NULL , 1 },
|
{ "-path" , pri_path , get_path_arg , NULL , 1 },
|
||||||
{ "-nouser" , pri_nouser , NULL , NULL , 1 },
|
{ "-nouser" , pri_nouser , NULL , NULL , 1 },
|
||||||
|
@ -194,7 +192,7 @@ static Pri_info primaries[] = {
|
||||||
{ NULL, NULL, NULL, NULL, 0 }
|
{ NULL, NULL, NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static Op_info ops[] = {
|
static struct op_info ops[] = {
|
||||||
{ "(" , LPAR, 0, 0, 0 }, /* parens are handled specially */
|
{ "(" , LPAR, 0, 0, 0 }, /* parens are handled specially */
|
||||||
{ ")" , RPAR, 0, 0, 0 },
|
{ ")" , RPAR, 0, 0, 0 },
|
||||||
{ "!" , NOT , 3, 1, 0 },
|
{ "!" , NOT , 3, 1, 0 },
|
||||||
|
@ -206,8 +204,8 @@ static Op_info ops[] = {
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
static Tok *toks; /* holds allocated array of all Toks created while parsing */
|
static struct tok *toks; /* holds allocated array of all toks created while parsing */
|
||||||
static Tok *root; /* points to root of expression tree, inside toks array */
|
static struct tok *root; /* points to root of expression tree, inside toks array */
|
||||||
|
|
||||||
static struct timespec start; /* time find was started, used for -[acm]time */
|
static struct timespec start; /* time find was started, used for -[acm]time */
|
||||||
|
|
||||||
|
@ -228,13 +226,13 @@ static struct {
|
||||||
* Primaries
|
* Primaries
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
pri_name(Arg *arg)
|
pri_name(struct arg *arg)
|
||||||
{
|
{
|
||||||
return !fnmatch((char *)arg->extra.p, basename(arg->path), 0);
|
return !fnmatch((char *)arg->extra.p, basename(arg->path), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_path(Arg *arg)
|
pri_path(struct arg *arg)
|
||||||
{
|
{
|
||||||
return !fnmatch((char *)arg->extra.p, arg->path, 0);
|
return !fnmatch((char *)arg->extra.p, arg->path, 0);
|
||||||
}
|
}
|
||||||
|
@ -242,39 +240,39 @@ pri_path(Arg *arg)
|
||||||
/* FIXME: what about errors? find(1p) literally just says
|
/* FIXME: what about errors? find(1p) literally just says
|
||||||
* "for which the getpwuid() function ... returns NULL" */
|
* "for which the getpwuid() function ... returns NULL" */
|
||||||
static int
|
static int
|
||||||
pri_nouser(Arg *arg)
|
pri_nouser(struct arg *arg)
|
||||||
{
|
{
|
||||||
return !getpwuid(arg->st->st_uid);
|
return !getpwuid(arg->st->st_uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_nogroup(Arg *arg)
|
pri_nogroup(struct arg *arg)
|
||||||
{
|
{
|
||||||
return !getgrgid(arg->st->st_gid);
|
return !getgrgid(arg->st->st_gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_xdev(Arg *arg)
|
pri_xdev(struct arg *arg)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_prune(Arg *arg)
|
pri_prune(struct arg *arg)
|
||||||
{
|
{
|
||||||
return gflags.prune = 1;
|
return gflags.prune = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_perm(Arg *arg)
|
pri_perm(struct arg *arg)
|
||||||
{
|
{
|
||||||
Permarg *p = (Permarg *)arg->extra.p;
|
struct permarg *p = (struct permarg *)arg->extra.p;
|
||||||
|
|
||||||
return (arg->st->st_mode & 07777 & (p->exact ? -1U : p->mode)) == p->mode;
|
return (arg->st->st_mode & 07777 & (p->exact ? -1U : p->mode)) == p->mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_type(Arg *arg)
|
pri_type(struct arg *arg)
|
||||||
{
|
{
|
||||||
switch ((char)arg->extra.i) {
|
switch ((char)arg->extra.i) {
|
||||||
default : return 0; /* impossible, but placate warnings */
|
default : return 0; /* impossible, but placate warnings */
|
||||||
|
@ -289,28 +287,28 @@ pri_type(Arg *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_links(Arg *arg)
|
pri_links(struct arg *arg)
|
||||||
{
|
{
|
||||||
Narg *n = arg->extra.p;
|
struct narg *n = arg->extra.p;
|
||||||
return n->cmp(arg->st->st_nlink, n->n);
|
return n->cmp(arg->st->st_nlink, n->n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_user(Arg *arg)
|
pri_user(struct arg *arg)
|
||||||
{
|
{
|
||||||
return arg->st->st_uid == (uid_t)arg->extra.i;
|
return arg->st->st_uid == (uid_t)arg->extra.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_group(Arg *arg)
|
pri_group(struct arg *arg)
|
||||||
{
|
{
|
||||||
return arg->st->st_gid == (gid_t)arg->extra.i;
|
return arg->st->st_gid == (gid_t)arg->extra.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_size(Arg *arg)
|
pri_size(struct arg *arg)
|
||||||
{
|
{
|
||||||
Sizearg *s = arg->extra.p;
|
struct sizearg *s = arg->extra.p;
|
||||||
off_t size = arg->st->st_size;
|
off_t size = arg->st->st_size;
|
||||||
|
|
||||||
if (!s->bytes)
|
if (!s->bytes)
|
||||||
|
@ -321,37 +319,37 @@ pri_size(Arg *arg)
|
||||||
|
|
||||||
/* FIXME: ignoring nanoseconds in atime, ctime, mtime */
|
/* FIXME: ignoring nanoseconds in atime, ctime, mtime */
|
||||||
static int
|
static int
|
||||||
pri_atime(Arg *arg)
|
pri_atime(struct arg *arg)
|
||||||
{
|
{
|
||||||
Narg *n = arg->extra.p;
|
struct narg *n = arg->extra.p;
|
||||||
time_t time = (n->n - start.tv_sec) / 86400;
|
time_t time = (n->n - start.tv_sec) / 86400;
|
||||||
return n->cmp(time, n->n);
|
return n->cmp(time, n->n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_ctime(Arg *arg)
|
pri_ctime(struct arg *arg)
|
||||||
{
|
{
|
||||||
Narg *n = arg->extra.p;
|
struct narg *n = arg->extra.p;
|
||||||
time_t time = (n->n - start.tv_sec) / 86400;
|
time_t time = (n->n - start.tv_sec) / 86400;
|
||||||
return n->cmp(time, n->n);
|
return n->cmp(time, n->n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_mtime(Arg *arg)
|
pri_mtime(struct arg *arg)
|
||||||
{
|
{
|
||||||
Narg *n = arg->extra.p;
|
struct narg *n = arg->extra.p;
|
||||||
time_t time = (n->n - start.tv_sec) / 86400;
|
time_t time = (n->n - start.tv_sec) / 86400;
|
||||||
return n->cmp(time, n->n);
|
return n->cmp(time, n->n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_exec(Arg *arg)
|
pri_exec(struct arg *arg)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
size_t len;
|
size_t len;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char **sp, ***brace;
|
char **sp, ***brace;
|
||||||
Execarg *e = arg->extra.p;
|
struct execarg *e = arg->extra.p;
|
||||||
|
|
||||||
if (e->isplus) {
|
if (e->isplus) {
|
||||||
len = strlen(arg->path) + 1;
|
len = strlen(arg->path) + 1;
|
||||||
|
@ -406,12 +404,12 @@ pri_exec(Arg *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_ok(Arg *arg)
|
pri_ok(struct arg *arg)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char ***brace, reply, buf[256];
|
char ***brace, reply, buf[256];
|
||||||
Okarg *o = arg->extra.p;
|
struct okarg *o = arg->extra.p;
|
||||||
|
|
||||||
fprintf(stderr, "%s: %s ?", *o->argv, arg->path);
|
fprintf(stderr, "%s: %s ?", *o->argv, arg->path);
|
||||||
reply = fgetc(stdin);
|
reply = fgetc(stdin);
|
||||||
|
@ -445,7 +443,7 @@ pri_ok(Arg *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_print(Arg *arg)
|
pri_print(struct arg *arg)
|
||||||
{
|
{
|
||||||
if (puts(arg->path) == EOF)
|
if (puts(arg->path) == EOF)
|
||||||
eprintf("puts failed:");
|
eprintf("puts failed:");
|
||||||
|
@ -454,13 +452,13 @@ pri_print(Arg *arg)
|
||||||
|
|
||||||
/* FIXME: ignoring nanoseconds */
|
/* FIXME: ignoring nanoseconds */
|
||||||
static int
|
static int
|
||||||
pri_newer(Arg *arg)
|
pri_newer(struct arg *arg)
|
||||||
{
|
{
|
||||||
return arg->st->st_mtime > (time_t)arg->extra.i;
|
return arg->st->st_mtime > (time_t)arg->extra.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pri_depth(Arg *arg)
|
pri_depth(struct arg *arg)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -471,30 +469,30 @@ pri_depth(Arg *arg)
|
||||||
* return pointer to last argument, the pointer will be incremented in parse()
|
* return pointer to last argument, the pointer will be incremented in parse()
|
||||||
*/
|
*/
|
||||||
static char **
|
static char **
|
||||||
get_name_arg(char *argv[], Extra *extra)
|
get_name_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
extra->p = *argv;
|
extra->p = *argv;
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_path_arg(char *argv[], Extra *extra)
|
get_path_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
extra->p = *argv;
|
extra->p = *argv;
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_xdev_arg(char *argv[], Extra *extra)
|
get_xdev_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
gflags.xdev = 1;
|
gflags.xdev = 1;
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_perm_arg(char *argv[], Extra *extra)
|
get_perm_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
Permarg *p = extra->p = emalloc(sizeof(*p));
|
struct permarg *p = extra->p = emalloc(sizeof(*p));
|
||||||
|
|
||||||
if (**argv == '-')
|
if (**argv == '-')
|
||||||
(*argv)++;
|
(*argv)++;
|
||||||
|
@ -507,7 +505,7 @@ get_perm_arg(char *argv[], Extra *extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_type_arg(char *argv[], Extra *extra)
|
get_type_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
if (!strchr("bcdlpfs", **argv))
|
if (!strchr("bcdlpfs", **argv))
|
||||||
eprintf("invalid type %c for -type primary\n", **argv);
|
eprintf("invalid type %c for -type primary\n", **argv);
|
||||||
|
@ -517,15 +515,15 @@ get_type_arg(char *argv[], Extra *extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_n_arg(char *argv[], Extra *extra)
|
get_n_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
Narg *n = extra->p = emalloc(sizeof(*n));
|
struct narg *n = extra->p = emalloc(sizeof(*n));
|
||||||
fill_narg(*argv, n);
|
fill_narg(*argv, n);
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_user_arg(char *argv[], Extra *extra)
|
get_user_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
char *end;
|
char *end;
|
||||||
struct passwd *p = getpwnam(*argv);
|
struct passwd *p = getpwnam(*argv);
|
||||||
|
@ -541,7 +539,7 @@ get_user_arg(char *argv[], Extra *extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_group_arg(char *argv[], Extra *extra)
|
get_group_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
char *end;
|
char *end;
|
||||||
struct group *g = getgrnam(*argv);
|
struct group *g = getgrnam(*argv);
|
||||||
|
@ -557,10 +555,10 @@ get_group_arg(char *argv[], Extra *extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_size_arg(char *argv[], Extra *extra)
|
get_size_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
char *p = *argv + strlen(*argv);
|
char *p = *argv + strlen(*argv);
|
||||||
Sizearg *s = extra->p = emalloc(sizeof(*s));
|
struct sizearg *s = extra->p = emalloc(sizeof(*s));
|
||||||
/* if the number is followed by 'c', the size will by in bytes */
|
/* if the number is followed by 'c', the size will by in bytes */
|
||||||
if ((s->bytes = (p > *argv && *--p == 'c')))
|
if ((s->bytes = (p > *argv && *--p == 'c')))
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
@ -570,11 +568,11 @@ get_size_arg(char *argv[], Extra *extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_exec_arg(char *argv[], Extra *extra)
|
get_exec_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
char **arg, **new, ***braces;
|
char **arg, **new, ***braces;
|
||||||
int nbraces = 0;
|
int nbraces = 0;
|
||||||
Execarg *e = extra->p = emalloc(sizeof(*e));
|
struct execarg *e = extra->p = emalloc(sizeof(*e));
|
||||||
|
|
||||||
for (arg = argv; *arg; arg++)
|
for (arg = argv; *arg; arg++)
|
||||||
if (!strcmp(*arg, ";"))
|
if (!strcmp(*arg, ";"))
|
||||||
|
@ -615,11 +613,11 @@ get_exec_arg(char *argv[], Extra *extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_ok_arg(char *argv[], Extra *extra)
|
get_ok_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
char **arg, ***braces;
|
char **arg, ***braces;
|
||||||
int nbraces = 0;
|
int nbraces = 0;
|
||||||
Okarg *o = extra->p = emalloc(sizeof(*o));
|
struct okarg *o = extra->p = emalloc(sizeof(*o));
|
||||||
|
|
||||||
for (arg = argv; *arg; arg++)
|
for (arg = argv; *arg; arg++)
|
||||||
if (!strcmp(*arg, ";"))
|
if (!strcmp(*arg, ";"))
|
||||||
|
@ -643,7 +641,7 @@ get_ok_arg(char *argv[], Extra *extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_print_arg(char *argv[], Extra *extra)
|
get_print_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
gflags.print = 0;
|
gflags.print = 0;
|
||||||
return argv;
|
return argv;
|
||||||
|
@ -651,7 +649,7 @@ get_print_arg(char *argv[], Extra *extra)
|
||||||
|
|
||||||
/* FIXME: ignoring nanoseconds */
|
/* FIXME: ignoring nanoseconds */
|
||||||
static char **
|
static char **
|
||||||
get_newer_arg(char *argv[], Extra *extra)
|
get_newer_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
@ -663,7 +661,7 @@ get_newer_arg(char *argv[], Extra *extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_depth_arg(char *argv[], Extra *extra)
|
get_depth_arg(char *argv[], union extra *extra)
|
||||||
{
|
{
|
||||||
gflags.depth = 1;
|
gflags.depth = 1;
|
||||||
return argv;
|
return argv;
|
||||||
|
@ -673,18 +671,18 @@ get_depth_arg(char *argv[], Extra *extra)
|
||||||
* Freeargs
|
* Freeargs
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
free_extra(Extra extra)
|
free_extra(union extra extra)
|
||||||
{
|
{
|
||||||
free(extra.p);
|
free(extra.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_exec_arg(Extra extra)
|
free_exec_arg(union extra extra)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char **arg;
|
char **arg;
|
||||||
Execarg *e = extra.p;
|
struct execarg *e = extra.p;
|
||||||
|
|
||||||
if (!e->isplus) {
|
if (!e->isplus) {
|
||||||
free(e->u.s.braces);
|
free(e->u.s.braces);
|
||||||
|
@ -712,9 +710,9 @@ free_exec_arg(Extra extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_ok_arg(Extra extra)
|
free_ok_arg(union extra extra)
|
||||||
{
|
{
|
||||||
Okarg *o = extra.p;
|
struct okarg *o = extra.p;
|
||||||
|
|
||||||
free(o->braces);
|
free(o->braces);
|
||||||
free(o);
|
free(o);
|
||||||
|
@ -724,7 +722,7 @@ free_ok_arg(Extra extra)
|
||||||
* Parsing/Building/Running
|
* Parsing/Building/Running
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fill_narg(char *s, Narg *n)
|
fill_narg(char *s, struct narg *n)
|
||||||
{
|
{
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
|
@ -738,10 +736,10 @@ fill_narg(char *s, Narg *n)
|
||||||
eprintf("bad number '%s'\n", s);
|
eprintf("bad number '%s'\n", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Pri_info *
|
static struct pri_info *
|
||||||
find_primary(char *name)
|
find_primary(char *name)
|
||||||
{
|
{
|
||||||
Pri_info *p;
|
struct pri_info *p;
|
||||||
|
|
||||||
for (p = primaries; p->name; p++)
|
for (p = primaries; p->name; p++)
|
||||||
if (!strcmp(name, p->name))
|
if (!strcmp(name, p->name))
|
||||||
|
@ -749,10 +747,10 @@ find_primary(char *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Op_info *
|
static struct op_info *
|
||||||
find_op(char *name)
|
find_op(char *name)
|
||||||
{
|
{
|
||||||
Op_info *o;
|
struct op_info *o;
|
||||||
|
|
||||||
for (o = ops; o->name; o++)
|
for (o = ops; o->name; o++)
|
||||||
if (!strcmp(name, o->name))
|
if (!strcmp(name, o->name))
|
||||||
|
@ -761,32 +759,32 @@ find_op(char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* given the expression from the command line
|
/* given the expression from the command line
|
||||||
* 1) convert arguments from strings to Tok and place in an array duplicating
|
* 1) convert arguments from strings to tok and place in an array duplicating
|
||||||
* the infix expression given, inserting "-a" where it was omitted
|
* the infix expression given, inserting "-a" where it was omitted
|
||||||
* 2) allocate an array to hold the correct number of Tok, and convert from
|
* 2) allocate an array to hold the correct number of tok, and convert from
|
||||||
* infix to rpn (using shunting-yard), add -a and -print if necessary
|
* infix to rpn (using shunting-yard), add -a and -print if necessary
|
||||||
* 3) evaluate the rpn filling in left and right pointers to create an
|
* 3) evaluate the rpn filling in left and right pointers to create an
|
||||||
* expression tree (Tok are still all contained in the rpn array, just
|
* expression tree (tok are still all contained in the rpn array, just
|
||||||
* pointing at eachother)
|
* pointing at eachother)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
parse(int argc, char **argv)
|
parse(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Tok infix[2 * argc + 1], *stack[argc], *tok, *rpn, *out, **top;
|
struct tok infix[2 * argc + 1], *stack[argc], *tok, *rpn, *out, **top;
|
||||||
Op_info *op;
|
struct op_info *op;
|
||||||
Pri_info *pri;
|
struct pri_info *pri;
|
||||||
char **arg;
|
char **arg;
|
||||||
int lasttype = -1;
|
int lasttype = -1;
|
||||||
size_t ntok = 0;
|
size_t ntok = 0;
|
||||||
Tok and = { .u.oinfo = find_op("-a"), .type = AND };
|
struct tok and = { .u.oinfo = find_op("-a"), .type = AND };
|
||||||
|
|
||||||
gflags.print = 1;
|
gflags.print = 1;
|
||||||
|
|
||||||
/* convert argv to infix expression of Tok, inserting in *tok */
|
/* convert argv to infix expression of tok, inserting in *tok */
|
||||||
for (arg = argv, tok = infix; *arg; arg++, tok++) {
|
for (arg = argv, tok = infix; *arg; arg++, tok++) {
|
||||||
pri = find_primary(*arg);
|
pri = find_primary(*arg);
|
||||||
|
|
||||||
if (pri) { /* token is a primary, fill out Tok and get arguments */
|
if (pri) { /* token is a primary, fill out tok and get arguments */
|
||||||
if (lasttype == PRIM || lasttype == RPAR) {
|
if (lasttype == PRIM || lasttype == RPAR) {
|
||||||
*tok++ = and;
|
*tok++ = and;
|
||||||
ntok++;
|
ntok++;
|
||||||
|
@ -862,7 +860,7 @@ parse(int argc, char **argv)
|
||||||
* if there was an expression but no -print, -exec, or -ok, add -a -print
|
* if there was an expression but no -print, -exec, or -ok, add -a -print
|
||||||
* in rpn, not infix */
|
* in rpn, not infix */
|
||||||
if (gflags.print)
|
if (gflags.print)
|
||||||
*out++ = (Tok){ .u.pinfo = find_primary("-print"), .type = PRIM };
|
*out++ = (struct tok){ .u.pinfo = find_primary("-print"), .type = PRIM };
|
||||||
if (gflags.print == 2)
|
if (gflags.print == 2)
|
||||||
*out++ = and;
|
*out++ = and;
|
||||||
|
|
||||||
|
@ -897,7 +895,7 @@ parse(int argc, char **argv)
|
||||||
* NOTE: operator NOT has NULL left side, expression on right side
|
* NOTE: operator NOT has NULL left side, expression on right side
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
eval(Tok *tok, Arg *arg)
|
eval(struct tok *tok, struct arg *arg)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -921,14 +919,14 @@ eval(Tok *tok, Arg *arg)
|
||||||
* recurse
|
* recurse
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
find(char *path, Findhist *hist)
|
find(char *path, struct findhist *hist)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
Findhist *f, cur;
|
struct findhist *f, cur;
|
||||||
size_t len = strlen(path) + 2; /* null and '/' */
|
size_t len = strlen(path) + 2; /* null and '/' */
|
||||||
Arg arg = { path, &st, { NULL } };
|
struct arg arg = { path, &st, { NULL } };
|
||||||
|
|
||||||
if ((gflags.l || (gflags.h && !hist) ? stat(path, &st) : lstat(path, &st)) < 0) {
|
if ((gflags.l || (gflags.h && !hist) ? stat(path, &st) : lstat(path, &st)) < 0) {
|
||||||
weprintf("failed to stat %s:", path);
|
weprintf("failed to stat %s:", path);
|
||||||
|
@ -1000,7 +998,7 @@ main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char **paths;
|
char **paths;
|
||||||
int npaths;
|
int npaths;
|
||||||
Tok *t;
|
struct tok *t;
|
||||||
|
|
||||||
ARGBEGIN {
|
ARGBEGIN {
|
||||||
case 'H': gflags.l = !(gflags.h = 1); break;
|
case 'H': gflags.l = !(gflags.h = 1); break;
|
||||||
|
|
18
test.c
18
test.c
|
@ -38,12 +38,12 @@ static int binary_ge(char *s1, char *s2) { long long a = STOI(s1), b = STOI(s2);
|
||||||
static int binary_lt(char *s1, char *s2) { long long a = STOI(s1), b = STOI(s2); return a < b; }
|
static int binary_lt(char *s1, char *s2) { long long a = STOI(s1), b = STOI(s2); return a < b; }
|
||||||
static int binary_le(char *s1, char *s2) { long long a = STOI(s1), b = STOI(s2); return a <= b; }
|
static int binary_le(char *s1, char *s2) { long long a = STOI(s1), b = STOI(s2); return a <= b; }
|
||||||
|
|
||||||
typedef struct {
|
struct test {
|
||||||
char *name;
|
char *name;
|
||||||
int (*func)();
|
int (*func)();
|
||||||
} Test;
|
};
|
||||||
|
|
||||||
static Test unary[] = {
|
static struct test unary[] = {
|
||||||
{ "-b", unary_b },
|
{ "-b", unary_b },
|
||||||
{ "-c", unary_c },
|
{ "-c", unary_c },
|
||||||
{ "-d", unary_d },
|
{ "-d", unary_d },
|
||||||
|
@ -66,7 +66,7 @@ static Test unary[] = {
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static Test binary[] = {
|
static struct test binary[] = {
|
||||||
{ "=" , binary_se },
|
{ "=" , binary_se },
|
||||||
{ "!=" , binary_sn },
|
{ "!=" , binary_sn },
|
||||||
{ "-eq", binary_eq },
|
{ "-eq", binary_eq },
|
||||||
|
@ -79,10 +79,10 @@ static Test binary[] = {
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static Test *
|
static struct test *
|
||||||
find_test(Test *tests, char *name)
|
find_test(struct test *tests, char *name)
|
||||||
{
|
{
|
||||||
Test *t;
|
struct test *t;
|
||||||
|
|
||||||
for (t = tests; t->name; t++)
|
for (t = tests; t->name; t++)
|
||||||
if (!strcmp(t->name, name))
|
if (!strcmp(t->name, name))
|
||||||
|
@ -105,7 +105,7 @@ onearg(char *argv[])
|
||||||
static int
|
static int
|
||||||
twoarg(char *argv[])
|
twoarg(char *argv[])
|
||||||
{
|
{
|
||||||
Test *t;
|
struct test *t;
|
||||||
|
|
||||||
if (!strcmp(argv[0], "!"))
|
if (!strcmp(argv[0], "!"))
|
||||||
return !onearg(argv + 1);
|
return !onearg(argv + 1);
|
||||||
|
@ -120,7 +120,7 @@ twoarg(char *argv[])
|
||||||
static int
|
static int
|
||||||
threearg(char *argv[])
|
threearg(char *argv[])
|
||||||
{
|
{
|
||||||
Test *t = find_test(binary, argv[1]);
|
struct test *t = find_test(binary, argv[1]);
|
||||||
|
|
||||||
if (t)
|
if (t)
|
||||||
return t->func(argv[0], argv[2]);
|
return t->func(argv[0], argv[2]);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user