Message ID | 20210907121943.3498701-15-marcandre.lureau@redhat.com |
---|---|
State | New |
Headers | show |
Series | Rust binding for QAPI and qemu-ga QMP handler examples | expand |
marcandre.lureau@redhat.com writes: > From: Marc-André Lureau <marcandre.lureau@redhat.com> > > Generate Rust #[cfg(...)] guards from QAPI 'if' conditions. > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> > --- > scripts/qapi/common.py | 16 ++++++++++++++++ > scripts/qapi/schema.py | 4 ++++ > 2 files changed, 20 insertions(+) > > diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py > index 5f8f76e5b2..6d22c66391 100644 > --- a/scripts/qapi/common.py > +++ b/scripts/qapi/common.py > @@ -201,6 +201,22 @@ def guardend(name: str) -> str: > name=c_fname(name).upper()) > > > +def rsgen_ifcond(ifcond: Union[str, Dict[str, Any]]) -> str: > + > + def cfg(ifcond: Union[str, Dict[str, Any]]): > + if isinstance(ifcond, str): > + return ifcond > + if isinstance(ifcond, list): > + return ', '.join([cfg(c) for c in ifcond]) > + oper, operands = next(iter(ifcond.items())) > + operands = cfg(operands) > + return f'{oper}({operands})' > + > + if not ifcond: > + return '' > + return '#[cfg(%s)]' % cfg(ifcond) > + > + > def gen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]], > cond_fmt: str, not_fmt: str, > all_operator: str, any_operator: str) -> str: Can we generalize gen_ifcond() to work for rsgen_ifcond(), too? > diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py > index 6455a8f425..c61f35e13f 100644 > --- a/scripts/qapi/schema.py > +++ b/scripts/qapi/schema.py > @@ -26,6 +26,7 @@ > docgen_ifcond, > gen_endif, > gen_if, > + rsgen_ifcond, > ) > from .error import QAPIError, QAPISemError, QAPISourceError > from .expr import check_exprs > @@ -48,6 +49,9 @@ def gen_endif(self): > def docgen(self): > return docgen_ifcond(self.ifcond) > > + def rsgen(self): > + return rsgen_ifcond(self.ifcond) > + > def is_present(self): > return bool(self.ifcond)
Hi On Wed, Sep 8, 2021 at 4:33 PM Markus Armbruster <armbru@redhat.com> wrote: > marcandre.lureau@redhat.com writes: > > > From: Marc-André Lureau <marcandre.lureau@redhat.com> > > > > Generate Rust #[cfg(...)] guards from QAPI 'if' conditions. > > > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> > > --- > > scripts/qapi/common.py | 16 ++++++++++++++++ > > scripts/qapi/schema.py | 4 ++++ > > 2 files changed, 20 insertions(+) > > > > diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py > > index 5f8f76e5b2..6d22c66391 100644 > > --- a/scripts/qapi/common.py > > +++ b/scripts/qapi/common.py > > @@ -201,6 +201,22 @@ def guardend(name: str) -> str: > > name=c_fname(name).upper()) > > > > > > +def rsgen_ifcond(ifcond: Union[str, Dict[str, Any]]) -> str: > > + > > + def cfg(ifcond: Union[str, Dict[str, Any]]): > > + if isinstance(ifcond, str): > > + return ifcond > > + if isinstance(ifcond, list): > > + return ', '.join([cfg(c) for c in ifcond]) > > + oper, operands = next(iter(ifcond.items())) > > + operands = cfg(operands) > > + return f'{oper}({operands})' > > + > > + if not ifcond: > > + return '' > > + return '#[cfg(%s)]' % cfg(ifcond) > > + > > + > > def gen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]], > > cond_fmt: str, not_fmt: str, > > all_operator: str, any_operator: str) -> str: > > Can we generalize gen_ifcond() to work for rsgen_ifcond(), too? > > Not elegantly, I am afraid. The logic of gen_ifcond() is based around the distinct prefix vs infix handling. In contrast, Rust cfg are all infix. As you can see from the code above, it is quite straightforward. Reusing gen_ifcond() would make it quite convoluted. > > diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py > > index 6455a8f425..c61f35e13f 100644 > > --- a/scripts/qapi/schema.py > > +++ b/scripts/qapi/schema.py > > @@ -26,6 +26,7 @@ > > docgen_ifcond, > > gen_endif, > > gen_if, > > + rsgen_ifcond, > > ) > > from .error import QAPIError, QAPISemError, QAPISourceError > > from .expr import check_exprs > > @@ -48,6 +49,9 @@ def gen_endif(self): > > def docgen(self): > > return docgen_ifcond(self.ifcond) > > > > + def rsgen(self): > > + return rsgen_ifcond(self.ifcond) > > + > > def is_present(self): > > return bool(self.ifcond) > >
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 5f8f76e5b2..6d22c66391 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -201,6 +201,22 @@ def guardend(name: str) -> str: name=c_fname(name).upper()) +def rsgen_ifcond(ifcond: Union[str, Dict[str, Any]]) -> str: + + def cfg(ifcond: Union[str, Dict[str, Any]]): + if isinstance(ifcond, str): + return ifcond + if isinstance(ifcond, list): + return ', '.join([cfg(c) for c in ifcond]) + oper, operands = next(iter(ifcond.items())) + operands = cfg(operands) + return f'{oper}({operands})' + + if not ifcond: + return '' + return '#[cfg(%s)]' % cfg(ifcond) + + def gen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]], cond_fmt: str, not_fmt: str, all_operator: str, any_operator: str) -> str: diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 6455a8f425..c61f35e13f 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -26,6 +26,7 @@ docgen_ifcond, gen_endif, gen_if, + rsgen_ifcond, ) from .error import QAPIError, QAPISemError, QAPISourceError from .expr import check_exprs @@ -48,6 +49,9 @@ def gen_endif(self): def docgen(self): return docgen_ifcond(self.ifcond) + def rsgen(self): + return rsgen_ifcond(self.ifcond) + def is_present(self): return bool(self.ifcond)