Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 354219 - [Future EAPI] Zero-or-one-of operator for REQUIRED_USE
Summary: [Future EAPI] Zero-or-one-of operator for REQUIRED_USE
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Hosted Projects
Classification: Unclassified
Component: PMS/EAPI (show other bugs)
Hardware: All Linux
: High enhancement (vote)
Assignee: PMS/EAPI
URL:
Whiteboard: in-eapi-5
Keywords:
Depends on:
Blocks: future-eapi
  Show dependency tree
 
Reported: 2011-02-09 10:16 UTC by Ulrich Müller
Modified: 2012-09-23 06:36 UTC (History)
4 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ulrich Müller gentoo-dev 2011-02-09 10:16:29 UTC
Both of the two cases of REQUIRED_USE that I needed so far would have profited from a zero-or-one-of/at-most-one-of group. Not a large statistic, but I guess that the case is not uncommon.

Of course there are several ways to express it with the existing operators, but already for three flags it's becoming clumsy and difficult to read:
   ^^ ( foo bar baz ( !foo !bar !baz ) )
   || ( ( !foo !bar ) ( !bar !baz ) ( !baz !foo ) )
   foo? ( !bar !baz ) bar? ( !baz )

So, should we have another operator for this? Either a zero-or-one-of group:
   ?? ( ... )      Zero or one of the child elements must be matched.

Or, a more general interval operator, as in regexps:
   {N} ( ... )     Exactly N elements must be matched.
   {N,} ( ... )    At least N elements must be matched.
   {N,M} ( ... )   At least N, but not more than M elements must be matched.
Comment 1 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2011-10-17 21:13:44 UTC
(In reply to comment #0)
> Of course there are several ways to express it with the existing operators, but
> already for three flags it's becoming clumsy and difficult to read:
>    ^^ ( foo bar baz ( !foo !bar !baz ) )

Well, that could be written as:
	^^ ( foo bar baz ( !foo ) )

In fact, going this way we could even go to:
	^^ ( foo bar baz ( ) )

but this doesn't work in portage. Not sure if it could be considered as a bug, portage just drops empty group.
Comment 2 Ulrich Müller gentoo-dev 2011-10-17 21:38:31 UTC
(In reply to comment #1)
> (In reply to comment #0)
> > Of course there are several ways to express it with the existing operators,
> > but already for three flags it's becoming clumsy and difficult to read:
> >    ^^ ( foo bar baz ( !foo !bar !baz ) )
> 
> Well, that could be written as:
>     ^^ ( foo bar baz ( !foo ) )

No, because that would (e.g.) disallow the combination "-foo +bar -baz".

> In fact, going this way we could even go to:
>     ^^ ( foo bar baz ( ) )

That also doesn't work: To what should the empty group evaluate? False would just be a no-op here. And if it evaluates to true, then it would effectively be a "zero of" group.
Comment 3 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2011-10-18 07:16:39 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > (In reply to comment #0)
> > > Of course there are several ways to express it with the existing operators,
> > > but already for three flags it's becoming clumsy and difficult to read:
> > >    ^^ ( foo bar baz ( !foo !bar !baz ) )
> > 
> > Well, that could be written as:
> >     ^^ ( foo bar baz ( !foo ) )
> 
> No, because that would (e.g.) disallow the combination "-foo +bar -baz".

Sorry, you're right.

> 
> > In fact, going this way we could even go to:
> >     ^^ ( foo bar baz ( ) )
> 
> That also doesn't work: To what should the empty group evaluate? False would
> just be a no-op here. And if it evaluates to true, then it would effectively be
> a "zero of" group.

Hm, right, that's undefined. On the other hand, spec defines that it could be empty, and for the || and ^^ groups, it also defines that empty clauses count as being matched.

Well, considering the above this does no longer matter. I missed the point.
Comment 4 Ulrich Müller gentoo-dev 2011-10-18 14:14:02 UTC
Meanwhile, some time has passed since introduction of EAPI 4, and REQUIRED_USE has found some use in the Portage tree. By a quick scan I found the following patterns:

foo? ( !bar ) bar ( !foo )

   Examples:
   faac? ( !aac ) aac? ( !faac )
   gmthigh? ( !gmtfull ) gmtfull? ( !gmthigh )
   opengl? ( !gles ) gles? ( !opengl )
   pam? ( !skey ) skey? ( !pam )
   pcsc-lite? ( !openct ) openct? ( !pcsc-lite )
   portaudio? ( !pulseaudio ) pulseaudio? ( !portaudio )
   xml? ( !expat ) expat? ( !xml )
   
   Please note that one half of it would be sufficient, but for some reason
   people prefer to add extra redundancy in the majority of cases.

^^ ( ( !foo !bar ) ( foo !bar ) ( !foo bar ) )

   Examples:
   ^^ ( ( !ruby !s7 ) ( ruby !s7 ) ( !ruby s7 ) )
   ^^ ( ( !slurm !pbs ) ( slurm !pbs ) ( !slurm pbs ) )

Both of these cases could be expressed in a much clearer way (and without negation) as:
   ?? ( foo bar )

I found no usage cases where a general interval operator would be of advantage, so I retract this part of my proposal.


The implementation in Portage should be easy: In function check_required_use the following change needs to be done:

 		if operator == "||":
 			return (True in argument)
 		elif operator == "^^":
 			return (argument.count(True) == 1)
+		elif operator == "??":
+			return (argument.count(True) <= 1)
 		elif operator[-1] == "?":
 			return (False not in argument)

Additionally, ?? has to be added as another (EAPI dependent) alternative in all places where || and ^^ occur.