[Toybox] Broken find [Was: Re: Towards find cleanup]

Rob Landley rob at landley.net
Thu Apr 11 15:12:55 PDT 2013


On 04/11/2013 04:37:36 PM, Felix Janda wrote:
> Now I think that I know better how this toy works and see that my  
> cleanup
> has broken it.
> 
> > > >  	if (filter->op==OP_OR) {
> > > > -		result = evaluate(filter->next, node, fnext);
> > > > -		result2 = evaluate(*fnext, node, fnext);
> > > > -		if (result) {
> > > > -			return result;
> > > > -		} else {
> > > > -			if (result2) {
> > > > -				return result2;
> > > > -			} else {
> > > > -				return 0;
> > > > -			}
> > > > -		}
> > > > +		return evaluate(filter->next, node, fnext) ||  
> evaluate(*fnext, node, fnext);
> > > This will have different side effects than the original code.
> > > The original code evaluates both sides, and then returns the 'or'  
> operation
> > > on the results.  The new one will (of course) do short-circuit  
> evaluation of
> > > the '||',  meaning that sometimes the second node won't be  
> evaluated.
> > > I believe that at one time, I actually had it coded that way, but  
> for some
> > > reason or other I went back to forcing the evaluation of both  
> nodes.
> > > Unfortunately, I can't remember the reason why I went back.  I  
> would have expected
> > > regular find to do short-circuit evaluation of expressions with  
> 'or' operations,
> > > so I'd be happy if this were correct.  I just have a nagging  
> feeling that
> > > there was some reason I couldn't do it this way.  I could be  
> completely wrong,
> > > though.  So unless testing reveals the need for evaluating both  
> sides of the
> > > 'or', this should be fine.
> 
> The reason is that we want the side effects evaluate has on *fnext. If
> we have a prefix expression like
> 
> OR AND CONDITION1 CONDITION2 CONDITION3

You can have and/or prefix expressions?

$ find . -or -exec echo one {} \; -exec echo two {} \; | grep two
find: invalid expression; you have used a binary operator '-or' with  
nothing before it.

> and CONDITION1 is false, the current version of evaluate will
> 1. see OR
> 2. descend to AND
> 3. find that CONDITION1 is false (side effect: *fnext=CONDITION2)
> 4. don't evaluate *fnext but go back to OR
> 5. OR now checks CONDITION2 instead of CONDITION3.

I'm not following this at all.

I did however try this:

   find . -exec echo one {} \; -or -exec echo two {} \; | grep two

It does not print two for any of the files, so -or is successfully  
short-circuiting. This is in the gnu/dammit version.

> In the previous version of evaluate in step 4 CONDITION2 would have  
> been
> evaluated, ignored and as a side effect fnext would then point to
> CONDITION3.

Which behavior is right, and can you give me a test command line I can  
try in the other implementation?

> > >
> > > Do you know if regular find does short-circuit evaluation?
> > > What would regular find do with
> > >   'find . -exec test1_with_side_effects {} \; -o -exec  
> test2_with_side_effects {} \;'
> > > ?
> >
> > POSIX says that these short-circuit evaluations shall be applied.  
> (The
> > same applies for -a.)
> 
> Now we have the problem that we want to have some side effects of
> evaluate but not all of them.

I'm not following this.

Rob


More information about the Toybox mailing list