Re: [PATCH v2 09/16] scripts/qapi: add QAPISchemaIfCond.rsgen()
Paolo Bonzini <[email protected]> Wed, 25 Feb 2026 08:53:57 +0100
| Newsgroups | org.nongnu.qemu-rust,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
On 2/25/26 07:48, Markus Armbruster wrote: > Paolo Bonzini <[email protected]> writes: > >> From: Marc-André Lureau <[email protected]> >> >> Generate Rust #[cfg(...)] guards from QAPI 'if' conditions; it >> turns out that they are very similar, with both of them using >> not/any/all, so just walk the tree. >> >> The next commit will put it to use. >> >> Signed-off-by: Marc-André Lureau <[email protected]> >> Link: https://lore.kernel.org/r/[email protected] >> Signed-off-by: Paolo Bonzini <[email protected]> >> --- >> scripts/qapi/common.py | 19 +++++++++++++++++++ >> scripts/qapi/schema.py | 4 ++++ >> 2 files changed, 23 insertions(+) >> >> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py >> index d7c8aa3365c..14d5dd259c4 100644 >> --- a/scripts/qapi/common.py >> +++ b/scripts/qapi/common.py >> @@ -199,6 +199,25 @@ def guardend(name: str) -> str: >> name=c_fname(name).upper()) >> >> >> +def rsgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str: >> + >> + def cfg(ifcond: Union[str, Dict[str, Any]]) -> str: >> + if isinstance(ifcond, str): >> + return ifcond >> + assert isinstance(ifcond, dict) and len(ifcond) == 1 >> + if 'not' in ifcond: >> + oper = 'not' >> + arg = cfg(ifcond['not']) >> + else: >> + oper, operands = next(iter(ifcond.items())) >> + arg = ', '.join([cfg(c) for c in operands]) >> + return f'{oper}({arg})' >> + >> + if not ifcond: >> + return '' >> + return '#[cfg(%s)]' % cfg(ifcond) >> + >> + > > Why not reuse the existing tree walker? See appended diff. I think it won't work due to need_parens? gen_ifcond is really designed for infix notation, I have no doubt that it *can* be made to work (for example pass 'all' and 'any' and prefix them after processing need_parens), but there is little duplication in the code other than if isinstance(ifcond, str): return cond_fmt % ifcond assert isinstance(ifcond, dict) and len(ifcond) == 1 because unary and n-ary operators in prefix notation are quite similar, unlike unary and binary operators in infix notation. Paolo