Re: [PATCH v2 09/16] scripts/qapi: add QAPISchemaIfCond.rsgen()

Paolo Bonzini
2026-02-25T07:54:37Z

On 2/25/26 07:48, Markus Armbruster wrote:
> Paolo Bonzini <pbonzini@redhat.com> writes:
>
>> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>>
>> 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 <marcandre.lureau@redhat.com>
>> Link: https://lore.kernel.org/r/20210907121943.3498701-15-marcandre.lureau@redhat.com
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>> 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