a bunch of cleanup
This commit is contained in:
parent
e427364a28
commit
3eed1fced6
188
find.c
188
find.c
|
@ -35,6 +35,7 @@ typedef struct {
|
||||||
int (*func)(Arg *arg);
|
int (*func)(Arg *arg);
|
||||||
char **(*getarg)(char **argv, Extra *extra);
|
char **(*getarg)(char **argv, Extra *extra);
|
||||||
void (*freearg)(Extra extra);
|
void (*freearg)(Extra extra);
|
||||||
|
char narg; /* -xdev, -depth, -print don't take args but have getarg() */
|
||||||
} Pri_info;
|
} Pri_info;
|
||||||
|
|
||||||
/* Information about operators, for lookup table */
|
/* Information about operators, for lookup table */
|
||||||
|
@ -135,6 +136,7 @@ static int pri_depth (Arg *arg);
|
||||||
/* Getargs */
|
/* Getargs */
|
||||||
static char **get_name_arg (char **argv, Extra *extra);
|
static char **get_name_arg (char **argv, Extra *extra);
|
||||||
static char **get_path_arg (char **argv, Extra *extra);
|
static char **get_path_arg (char **argv, Extra *extra);
|
||||||
|
static char **get_xdev_arg (char **argv, Extra *extra);
|
||||||
static char **get_perm_arg (char **argv, Extra *extra);
|
static char **get_perm_arg (char **argv, Extra *extra);
|
||||||
static char **get_type_arg (char **argv, Extra *extra);
|
static char **get_type_arg (char **argv, Extra *extra);
|
||||||
static char **get_n_arg (char **argv, Extra *extra);
|
static char **get_n_arg (char **argv, Extra *extra);
|
||||||
|
@ -143,7 +145,9 @@ static char **get_group_arg(char **argv, Extra *extra);
|
||||||
static char **get_size_arg (char **argv, Extra *extra);
|
static char **get_size_arg (char **argv, Extra *extra);
|
||||||
static char **get_exec_arg (char **argv, Extra *extra);
|
static char **get_exec_arg (char **argv, Extra *extra);
|
||||||
static char **get_ok_arg (char **argv, Extra *extra);
|
static char **get_ok_arg (char **argv, Extra *extra);
|
||||||
|
static char **get_print_arg(char **argv, Extra *extra);
|
||||||
static char **get_newer_arg(char **argv, Extra *extra);
|
static char **get_newer_arg(char **argv, Extra *extra);
|
||||||
|
static char **get_depth_arg(char **argv, Extra *extra);
|
||||||
|
|
||||||
/* Freeargs */
|
/* Freeargs */
|
||||||
static void free_extra (Extra extra);
|
static void free_extra (Extra extra);
|
||||||
|
@ -151,6 +155,7 @@ static void free_exec_arg(Extra extra);
|
||||||
static void free_ok_arg (Extra extra);
|
static void free_ok_arg (Extra extra);
|
||||||
|
|
||||||
/* Parsing/Building/Running */
|
/* Parsing/Building/Running */
|
||||||
|
static void fill_narg(char *s, Narg *n);
|
||||||
static Pri_info *find_primary(char *name);
|
static Pri_info *find_primary(char *name);
|
||||||
static Op_info *find_op(char *name);
|
static Op_info *find_op(char *name);
|
||||||
static void parse(int argc, char **argv);
|
static void parse(int argc, char **argv);
|
||||||
|
@ -165,28 +170,28 @@ 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 Pri_info primaries[] = {
|
||||||
{ "-name" , pri_name , get_name_arg , NULL },
|
{ "-name" , pri_name , get_name_arg , NULL , 1 },
|
||||||
{ "-path" , pri_path , get_path_arg , NULL },
|
{ "-path" , pri_path , get_path_arg , NULL , 1 },
|
||||||
{ "-nouser" , pri_nouser , NULL , NULL },
|
{ "-nouser" , pri_nouser , NULL , NULL , 1 },
|
||||||
{ "-nogroup", pri_nogroup, NULL , NULL },
|
{ "-nogroup", pri_nogroup, NULL , NULL , 1 },
|
||||||
{ "-xdev" , pri_xdev , NULL , NULL },
|
{ "-xdev" , pri_xdev , get_xdev_arg , NULL , 0 },
|
||||||
{ "-prune" , pri_prune , NULL , NULL },
|
{ "-prune" , pri_prune , NULL , NULL , 1 },
|
||||||
{ "-perm" , pri_perm , get_perm_arg , free_extra },
|
{ "-perm" , pri_perm , get_perm_arg , free_extra , 1 },
|
||||||
{ "-type" , pri_type , get_type_arg , NULL },
|
{ "-type" , pri_type , get_type_arg , NULL , 1 },
|
||||||
{ "-links" , pri_links , get_n_arg , free_extra },
|
{ "-links" , pri_links , get_n_arg , free_extra , 1 },
|
||||||
{ "-user" , pri_user , get_user_arg , NULL },
|
{ "-user" , pri_user , get_user_arg , NULL , 1 },
|
||||||
{ "-group" , pri_group , get_group_arg, NULL },
|
{ "-group" , pri_group , get_group_arg, NULL , 1 },
|
||||||
{ "-size" , pri_size , get_size_arg , free_extra },
|
{ "-size" , pri_size , get_size_arg , free_extra , 1 },
|
||||||
{ "-atime" , pri_atime , get_n_arg , free_extra },
|
{ "-atime" , pri_atime , get_n_arg , free_extra , 1 },
|
||||||
{ "-ctime" , pri_ctime , get_n_arg , free_extra },
|
{ "-ctime" , pri_ctime , get_n_arg , free_extra , 1 },
|
||||||
{ "-mtime" , pri_mtime , get_n_arg , free_extra },
|
{ "-mtime" , pri_mtime , get_n_arg , free_extra , 1 },
|
||||||
{ "-exec" , pri_exec , get_exec_arg , free_exec_arg },
|
{ "-exec" , pri_exec , get_exec_arg , free_exec_arg, 1 },
|
||||||
{ "-ok" , pri_ok , get_ok_arg , free_ok_arg },
|
{ "-ok" , pri_ok , get_ok_arg , free_ok_arg , 1 },
|
||||||
{ "-print" , pri_print , NULL , NULL },
|
{ "-print" , pri_print , get_print_arg, NULL , 0 },
|
||||||
{ "-newer" , pri_newer , get_newer_arg, NULL },
|
{ "-newer" , pri_newer , get_newer_arg, NULL , 1 },
|
||||||
{ "-depth" , pri_depth , NULL , NULL },
|
{ "-depth" , pri_depth , get_depth_arg, NULL , 0 },
|
||||||
|
|
||||||
{ NULL, NULL, NULL, NULL }
|
{ NULL, NULL, NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static Op_info ops[] = {
|
static Op_info ops[] = {
|
||||||
|
@ -216,6 +221,7 @@ static struct {
|
||||||
char l ; /* -L, follow all symlinks (command line and search) */
|
char l ; /* -L, follow all symlinks (command line and search) */
|
||||||
char prune; /* hit -prune */
|
char prune; /* hit -prune */
|
||||||
char xdev ; /* -xdev, prune directories on different devices */
|
char xdev ; /* -xdev, prune directories on different devices */
|
||||||
|
char print; /* whether we will need -print when parsing */
|
||||||
} gflags;
|
} gflags;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -341,17 +347,16 @@ pri_mtime(Arg *arg)
|
||||||
static int
|
static int
|
||||||
pri_exec(Arg *arg)
|
pri_exec(Arg *arg)
|
||||||
{
|
{
|
||||||
|
int status;
|
||||||
|
pid_t pid;
|
||||||
Execarg *e = arg->extra.p;
|
Execarg *e = arg->extra.p;
|
||||||
|
|
||||||
if (e->isplus) {
|
if (e->isplus) {
|
||||||
size_t len = strlen(arg->path) + 1;
|
size_t len = strlen(arg->path) + 1;
|
||||||
|
|
||||||
/* if we've reached ARG_MAX, fork, exec, wait, free file names, reset
|
/* if we reached ARG_MAX, fork, exec, wait, free file names, reset list */
|
||||||
* list */
|
|
||||||
if (len + e->u.p.arglen + e->u.p.filelen + envlen > argmax) {
|
if (len + e->u.p.arglen + e->u.p.filelen + envlen > argmax) {
|
||||||
char **arg;
|
char **arg;
|
||||||
int status;
|
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
e->argv[e->u.p.next] = NULL;
|
e->argv[e->u.p.next] = NULL;
|
||||||
|
|
||||||
|
@ -369,8 +374,7 @@ pri_exec(Arg *arg)
|
||||||
e->u.p.filelen = 0;
|
e->u.p.filelen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we have too many filenames, realloc (with space for NULL
|
/* if we have too many files, realloc (with space for NULL termination) */
|
||||||
* termination) */
|
|
||||||
if (e->u.p.next + 1 == e->u.p.cap)
|
if (e->u.p.next + 1 == e->u.p.cap)
|
||||||
e->argv = erealloc(e->argv, (e->u.p.cap *= 2) * sizeof(*e->argv));
|
e->argv = erealloc(e->argv, (e->u.p.cap *= 2) * sizeof(*e->argv));
|
||||||
|
|
||||||
|
@ -381,9 +385,7 @@ pri_exec(Arg *arg)
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
int status;
|
|
||||||
char ***brace;
|
char ***brace;
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
/* insert path everywhere user gave us {} */
|
/* insert path everywhere user gave us {} */
|
||||||
for (brace = e->u.s.braces; *brace; brace++)
|
for (brace = e->u.s.braces; *brace; brace++)
|
||||||
|
@ -416,13 +418,13 @@ pri_ok(Arg *arg)
|
||||||
* byte? probably shouldn't juse fgets() */
|
* byte? probably shouldn't juse fgets() */
|
||||||
;
|
;
|
||||||
|
|
||||||
if (feof(stdin)) /* ferror()? */
|
if (feof(stdin)) /* FIXME: ferror()? */
|
||||||
clearerr(stdin);
|
clearerr(stdin);
|
||||||
|
|
||||||
if (reply != 'y' && reply != 'Y')
|
if (reply != 'y' && reply != 'Y')
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* insert filename everywhere use gave us {} */
|
/* insert filename everywhere user gave us {} */
|
||||||
for (brace = o->braces; *brace; brace++)
|
for (brace = o->braces; *brace; brace++)
|
||||||
**brace = arg->path;
|
**brace = arg->path;
|
||||||
|
|
||||||
|
@ -437,7 +439,8 @@ pri_ok(Arg *arg)
|
||||||
static int
|
static int
|
||||||
pri_print(Arg *arg)
|
pri_print(Arg *arg)
|
||||||
{
|
{
|
||||||
puts(arg->path);
|
if (puts(arg->path) == EOF)
|
||||||
|
eprintf("puts failed:");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,10 +476,17 @@ get_path_arg(char **argv, Extra *extra)
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char **
|
||||||
|
get_xdev_arg(char **argv, Extra *extra)
|
||||||
|
{
|
||||||
|
gflags.xdev = 1;
|
||||||
|
return argv;
|
||||||
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
get_perm_arg(char **argv, Extra *extra)
|
get_perm_arg(char **argv, Extra *extra)
|
||||||
{
|
{
|
||||||
Permarg *p = emalloc(sizeof(*p));
|
Permarg *p = extra->p = emalloc(sizeof(*p));
|
||||||
|
|
||||||
if (**argv == '-')
|
if (**argv == '-')
|
||||||
(*argv)++;
|
(*argv)++;
|
||||||
|
@ -484,7 +494,6 @@ get_perm_arg(char **argv, Extra *extra)
|
||||||
p->exact = 1;
|
p->exact = 1;
|
||||||
|
|
||||||
p->mode = parsemode(*argv, 0, 0);
|
p->mode = parsemode(*argv, 0, 0);
|
||||||
extra->p = p;
|
|
||||||
|
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
@ -502,20 +511,8 @@ get_type_arg(char **argv, Extra *extra)
|
||||||
static char **
|
static char **
|
||||||
get_n_arg(char **argv, Extra *extra)
|
get_n_arg(char **argv, Extra *extra)
|
||||||
{
|
{
|
||||||
Narg *n = emalloc(sizeof(*n));
|
Narg *n = extra->p = emalloc(sizeof(*n));
|
||||||
char *end;
|
fill_narg(*argv, n);
|
||||||
|
|
||||||
switch (**argv) {
|
|
||||||
case '+': n->cmp = cmp_gt; (*argv)++; break;
|
|
||||||
case '-': n->cmp = cmp_lt; (*argv)++; break;
|
|
||||||
default : n->cmp = cmp_eq; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
n->n = strtol(*argv, &end, 10);
|
|
||||||
if (end == *argv || *end)
|
|
||||||
eprintf("bad number '%s'\n", *argv);
|
|
||||||
|
|
||||||
extra->p = n;
|
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,27 +551,13 @@ get_group_arg(char **argv, Extra *extra)
|
||||||
static char **
|
static char **
|
||||||
get_size_arg(char **argv, Extra *extra)
|
get_size_arg(char **argv, Extra *extra)
|
||||||
{
|
{
|
||||||
char *end;
|
|
||||||
char *p = *argv + strlen(*argv);
|
char *p = *argv + strlen(*argv);
|
||||||
Sizearg *s = emalloc(sizeof(*s));
|
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 */
|
||||||
s->bytes = p > *argv && *--p == 'c';
|
if ((s->bytes = (p > *argv && *--p == 'c')))
|
||||||
|
|
||||||
if (s->bytes)
|
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
/* FIXME: no need to have this in get_n_arg and here */
|
fill_narg(*argv, &s->n);
|
||||||
switch (**argv) {
|
|
||||||
case '+': s->n.cmp = cmp_gt; (*argv)++; break;
|
|
||||||
case '-': s->n.cmp = cmp_lt; (*argv)++; break;
|
|
||||||
default : s->n.cmp = cmp_eq; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->n.n = strtol(*argv, &end, 10);
|
|
||||||
if (end == *argv || *end)
|
|
||||||
eprintf("bad number '%s'\n", *argv);
|
|
||||||
|
|
||||||
extra->p = s;
|
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,7 +566,7 @@ get_exec_arg(char **argv, Extra *extra)
|
||||||
{
|
{
|
||||||
char **arg;
|
char **arg;
|
||||||
int nbraces = 0;
|
int nbraces = 0;
|
||||||
Execarg *e = emalloc(sizeof(*e));
|
Execarg *e = extra->p = emalloc(sizeof(*e));
|
||||||
|
|
||||||
for (arg = argv; *arg; arg++)
|
for (arg = argv; *arg; arg++)
|
||||||
if (!strcmp(*arg, ";"))
|
if (!strcmp(*arg, ";"))
|
||||||
|
@ -623,7 +606,7 @@ get_exec_arg(char **argv, Extra *extra)
|
||||||
if (!strcmp(*arg, "{}"))
|
if (!strcmp(*arg, "{}"))
|
||||||
*braces++ = arg;
|
*braces++ = arg;
|
||||||
}
|
}
|
||||||
extra->p = e;
|
gflags.print = 0;
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,7 +615,7 @@ get_ok_arg(char **argv, Extra *extra)
|
||||||
{
|
{
|
||||||
char **arg, ***braces;
|
char **arg, ***braces;
|
||||||
int nbraces = 0;
|
int nbraces = 0;
|
||||||
Okarg *o = emalloc(sizeof(*o));
|
Okarg *o = extra->p = emalloc(sizeof(*o));
|
||||||
|
|
||||||
for (arg = argv; *arg; arg++)
|
for (arg = argv; *arg; arg++)
|
||||||
if (!strcmp(*arg, ";"))
|
if (!strcmp(*arg, ";"))
|
||||||
|
@ -651,10 +634,17 @@ get_ok_arg(char **argv, Extra *extra)
|
||||||
if (!strcmp(*arg, "{}"))
|
if (!strcmp(*arg, "{}"))
|
||||||
*braces++ = arg;
|
*braces++ = arg;
|
||||||
|
|
||||||
extra->p = o;
|
gflags.print = 0;
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char **
|
||||||
|
get_print_arg(char **argv, Extra *extra)
|
||||||
|
{
|
||||||
|
gflags.print = 0;
|
||||||
|
return argv;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: ignoring nanoseconds */
|
/* FIXME: ignoring nanoseconds */
|
||||||
static char **
|
static char **
|
||||||
get_newer_arg(char **argv, Extra *extra)
|
get_newer_arg(char **argv, Extra *extra)
|
||||||
|
@ -668,6 +658,13 @@ get_newer_arg(char **argv, Extra *extra)
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char **
|
||||||
|
get_depth_arg(char **argv, Extra *extra)
|
||||||
|
{
|
||||||
|
gflags.depth = 1;
|
||||||
|
return argv;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Freeargs
|
* Freeargs
|
||||||
*/
|
*/
|
||||||
|
@ -681,6 +678,7 @@ static void
|
||||||
free_exec_arg(Extra extra)
|
free_exec_arg(Extra extra)
|
||||||
{
|
{
|
||||||
Execarg *e = extra.p;
|
Execarg *e = extra.p;
|
||||||
|
|
||||||
if (!e->isplus) {
|
if (!e->isplus) {
|
||||||
free(e->u.s.braces);
|
free(e->u.s.braces);
|
||||||
} else {
|
} else {
|
||||||
|
@ -711,6 +709,7 @@ static void
|
||||||
free_ok_arg(Extra extra)
|
free_ok_arg(Extra extra)
|
||||||
{
|
{
|
||||||
Okarg *o = extra.p;
|
Okarg *o = extra.p;
|
||||||
|
|
||||||
free(o->braces);
|
free(o->braces);
|
||||||
free(o);
|
free(o);
|
||||||
}
|
}
|
||||||
|
@ -718,6 +717,21 @@ free_ok_arg(Extra extra)
|
||||||
/*
|
/*
|
||||||
* Parsing/Building/Running
|
* Parsing/Building/Running
|
||||||
*/
|
*/
|
||||||
|
static void
|
||||||
|
fill_narg(char *s, Narg *n)
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
|
||||||
|
switch (*s) {
|
||||||
|
case '+': n->cmp = cmp_gt; s++; break;
|
||||||
|
case '-': n->cmp = cmp_lt; s++; break;
|
||||||
|
default : n->cmp = cmp_eq; break;
|
||||||
|
}
|
||||||
|
n->n = strtol(s, &end, 10);
|
||||||
|
if (end == s || *end)
|
||||||
|
eprintf("bad number '%s'\n", s);
|
||||||
|
}
|
||||||
|
|
||||||
static Pri_info *
|
static Pri_info *
|
||||||
find_primary(char *name)
|
find_primary(char *name)
|
||||||
{
|
{
|
||||||
|
@ -756,37 +770,27 @@ parse(int argc, char **argv)
|
||||||
Tok infix[2 * argc + 1], *stack[argc], *tok, *rpn, *out, **top;
|
Tok infix[2 * argc + 1], *stack[argc], *tok, *rpn, *out, **top;
|
||||||
char **arg;
|
char **arg;
|
||||||
size_t ntok = 0;
|
size_t ntok = 0;
|
||||||
int print = 1;
|
|
||||||
Tok and = { .u.oinfo = find_op("-a"), .type = AND };
|
Tok and = { .u.oinfo = find_op("-a"), .type = AND };
|
||||||
|
|
||||||
|
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++) {
|
||||||
Op_info *op;
|
Op_info *op;
|
||||||
Pri_info *pri = find_primary(*arg);
|
Pri_info *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 */
|
||||||
|
|
||||||
/* FIXME: should never have to ask "which primary is this?" Should
|
|
||||||
* probably move this into getarg even though there's no arg */
|
|
||||||
if (pri->func == pri_depth)
|
|
||||||
gflags.depth = 1;
|
|
||||||
else if (pri->func == pri_xdev)
|
|
||||||
gflags.xdev = 1;
|
|
||||||
else if (pri->func == pri_exec || pri->func == pri_ok || pri->func == pri_print)
|
|
||||||
print = 0;
|
|
||||||
|
|
||||||
if (lasttype == PRIM || lasttype == RPAR) {
|
if (lasttype == PRIM || lasttype == RPAR) {
|
||||||
*tok++ = and;
|
*tok++ = and;
|
||||||
ntok++;
|
ntok++;
|
||||||
}
|
}
|
||||||
if (pri->getarg) {
|
if (pri->getarg) {
|
||||||
if (!*++arg)
|
if (pri->narg && !*++arg)
|
||||||
eprintf("no argument for primary %s\n", pri->name);
|
eprintf("no argument for primary %s\n", pri->name);
|
||||||
arg = pri->getarg(arg, &tok->extra);
|
arg = pri->getarg(arg, &tok->extra);
|
||||||
}
|
}
|
||||||
tok->u.pinfo = pri;
|
tok->u.pinfo = pri;
|
||||||
tok->type = PRIM;
|
tok->type = PRIM;
|
||||||
|
|
||||||
} else if ((op = find_op(*arg))) { /* token is an operator */
|
} else if ((op = find_op(*arg))) { /* token is an operator */
|
||||||
if (lasttype == LPAR && op->type == RPAR)
|
if (lasttype == LPAR && op->type == RPAR)
|
||||||
eprintf("empty parens\n");
|
eprintf("empty parens\n");
|
||||||
|
@ -796,7 +800,6 @@ parse(int argc, char **argv)
|
||||||
}
|
}
|
||||||
tok->type = op->type;
|
tok->type = op->type;
|
||||||
tok->u.oinfo = op;
|
tok->u.oinfo = op;
|
||||||
|
|
||||||
} else { /* token is neither primary nor operator, must be path in the wrong place */
|
} else { /* token is neither primary nor operator, must be path in the wrong place */
|
||||||
eprintf("paths must precede expression: %s\n", *arg);
|
eprintf("paths must precede expression: %s\n", *arg);
|
||||||
}
|
}
|
||||||
|
@ -807,15 +810,14 @@ parse(int argc, char **argv)
|
||||||
tok->type = END;
|
tok->type = END;
|
||||||
ntok++;
|
ntok++;
|
||||||
|
|
||||||
if (print && (arg != argv)) /* need to add -a -print (not just -print) */
|
if (gflags.print && (arg != argv)) /* need to add -a -print (not just -print) */
|
||||||
print++;
|
gflags.print++;
|
||||||
|
|
||||||
/* use shunting-yard to convert from infix to rpn
|
/* use shunting-yard to convert from infix to rpn
|
||||||
* https://en.wikipedia.org/wiki/Shunting-yard_algorithm
|
* https://en.wikipedia.org/wiki/Shunting-yard_algorithm
|
||||||
* read from infix, resulting rpn ends up in rpn, next position in rpn is out
|
* read from infix, resulting rpn ends up in rpn, next position in rpn is out
|
||||||
* push operators onto stack, next position in stack is top
|
* push operators onto stack, next position in stack is top */
|
||||||
*/
|
rpn = emalloc((ntok + gflags.print) * sizeof(*rpn));
|
||||||
rpn = emalloc((ntok + print) * sizeof(*rpn));
|
|
||||||
for (tok = infix, out = rpn, top = stack; tok->type != END; tok++) {
|
for (tok = infix, out = rpn, top = stack; tok->type != END; tok++) {
|
||||||
switch (tok->type) {
|
switch (tok->type) {
|
||||||
case PRIM: *out++ = *tok; break;
|
case PRIM: *out++ = *tok; break;
|
||||||
|
@ -851,11 +853,10 @@ parse(int argc, char **argv)
|
||||||
|
|
||||||
/* if there was no expression, use -print
|
/* if there was no expression, use -print
|
||||||
* 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 (print)
|
|
||||||
*out++ = (Tok){ .u.pinfo = find_primary("-print"), .type = PRIM };
|
*out++ = (Tok){ .u.pinfo = find_primary("-print"), .type = PRIM };
|
||||||
if (print == 2)
|
if (gflags.print == 2)
|
||||||
*out++ = and;
|
*out++ = and;
|
||||||
|
|
||||||
out->type = END;
|
out->type = END;
|
||||||
|
@ -864,8 +865,7 @@ parse(int argc, char **argv)
|
||||||
* values are pushed onto stack, operators pop values off stack into left
|
* values are pushed onto stack, operators pop values off stack into left
|
||||||
* and right pointers, pushing operator node back onto stack
|
* and right pointers, pushing operator node back onto stack
|
||||||
* could probably just do this during shunting-yard, but this is simpler
|
* could probably just do this during shunting-yard, but this is simpler
|
||||||
* code IMO
|
* code IMO */
|
||||||
*/
|
|
||||||
for (tok = rpn, top = stack; tok->type != END; tok++) {
|
for (tok = rpn, top = stack; tok->type != END; tok++) {
|
||||||
if (tok->type == PRIM) {
|
if (tok->type == PRIM) {
|
||||||
*top++ = tok;
|
*top++ = tok;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user