diff mbox series

[RFC,v3,14/32] scripts/qapi: add QAPISchemaIfCond.rsgen()

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

Commit Message

Marc-André Lureau Sept. 7, 2021, 12:19 p.m. UTC
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(+)

Comments

Markus Armbruster Sept. 8, 2021, 12:33 p.m. UTC | #1
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)
Marc-André Lureau Sept. 8, 2021, 2:06 p.m. UTC | #2
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 mbox series

Patch

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)