[libvirt] [PATCH 08/21] qemu: qapi: Separate virQEMUQAPISchemaTraverse into functions by object type

Peter Krempa posted 21 patches 6 years, 9 months ago
[libvirt] [PATCH 08/21] qemu: qapi: Separate virQEMUQAPISchemaTraverse into functions by object type
Posted by Peter Krempa 6 years, 9 months ago
Simplify virQEMUQAPISchemaTraverse by separating out the necessary
operations for given 'meta-type' into separate functions.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
---
 src/qemu/qemu_qapi.c | 117 ++++++++++++++++++++++++++++---------------
 1 file changed, 78 insertions(+), 39 deletions(-)

diff --git a/src/qemu/qemu_qapi.c b/src/qemu/qemu_qapi.c
index 2652061f4e..5995e5006e 100644
--- a/src/qemu/qemu_qapi.c
+++ b/src/qemu/qemu_qapi.c
@@ -105,68 +105,107 @@ static int
 virQEMUQAPISchemaTraverse(const char *baseName,
                           char **query,
                           virHashTablePtr schema,
-                          virJSONValuePtr *type)
+                          virJSONValuePtr *type);
+
+
+static int
+virQEMUQAPISchemaTraverseObject(virJSONValuePtr cur,
+                                char **query,
+                                virHashTablePtr schema,
+                                virJSONValuePtr *type)
 {
-    virJSONValuePtr curtype;
     virJSONValuePtr obj;
-    const char *metatype;
     const char *querytype = NULL;
-    const char *querystr;
-    char modifier;
+    const char *querystr = *query;
+    char modifier = *querystr;
+
+    if (!c_isalpha(modifier))
+        querystr++;
+
+    if (modifier == '+') {
+        querytype = virQEMUQAPISchemaObjectGetType("variants",
+                                                   querystr,
+                                                   "case", cur);
+    } else {
+        obj = virQEMUQAPISchemaObjectGet("members", querystr, "name", cur);
+
+        if (modifier == '*' &&
+            !virJSONValueObjectHasKey(obj, "default"))
+            return 0;
+
+        querytype = virQEMUQAPISchemaTypeFromObject(obj);
+    }

-    if (!(curtype = virHashLookup(schema, baseName)))
+    return virQEMUQAPISchemaTraverse(querytype, query + 1, schema, type);
+}
+
+
+static int
+virQEMUQAPISchemaTraverseArray(virJSONValuePtr cur,
+                               char **query,
+                               virHashTablePtr schema,
+                               virJSONValuePtr *type)
+{
+    const char *querytype;
+
+    /* arrays are just flattened by default */
+    if (!(querytype = virJSONValueObjectGetString(cur, "element-type")))
+        return 0;
+
+    return virQEMUQAPISchemaTraverse(querytype, query, schema, type);
+}
+
+
+static int
+virQEMUQAPISchemaTraverseCommand(virJSONValuePtr cur,
+                                 char **query,
+                                 virHashTablePtr schema,
+                                 virJSONValuePtr *type)
+{
+    const char *querytype;
+
+    if (!(querytype = virJSONValueObjectGetString(cur, *query)))
+        return 0;
+
+    return virQEMUQAPISchemaTraverse(querytype, query + 1, schema, type);
+}
+
+
+static int
+virQEMUQAPISchemaTraverse(const char *baseName,
+                          char **query,
+                          virHashTablePtr schema,
+                          virJSONValuePtr *type)
+{
+    virJSONValuePtr cur;
+    const char *metatype;
+
+    if (!(cur = virHashLookup(schema, baseName)))
         return 0;

     if (!*query) {
         if (type)
-            *type = curtype;
+            *type = cur;

         return 1;
     }

-    if (!(metatype = virJSONValueObjectGetString(curtype, "meta-type")))
+    if (!(metatype = virJSONValueObjectGetString(cur, "meta-type")))
         return 0;

-    /* flatten arrays by default */
     if (STREQ(metatype, "array")) {
-        if (!(querytype = virJSONValueObjectGetString(curtype, "element-type")))
-            return 0;
+        return virQEMUQAPISchemaTraverseArray(cur, query, schema, type);
     } else if (STREQ(metatype, "object")) {
-        querystr = *query;
-        modifier = **query;
-
-        if (!c_isalpha(modifier))
-            querystr++;
-
-        if (modifier == '+') {
-            querytype = virQEMUQAPISchemaObjectGetType("variants",
-                                                       querystr,
-                                                       "case", curtype);
-        } else {
-            obj = virQEMUQAPISchemaObjectGet("members", querystr,
-                                             "name", curtype);
-
-            if (modifier == '*' &&
-                !virJSONValueObjectHasKey(obj, "default"))
-                return 0;
-
-            querytype = virQEMUQAPISchemaTypeFromObject(obj);
-        }
-        query++;
+        return virQEMUQAPISchemaTraverseObject(cur, query, schema, type);
     } else if (STREQ(metatype, "command") ||
                STREQ(metatype, "event")) {
-        if (!(querytype = virJSONValueObjectGetString(curtype, *query)))
-            return 0;
-        query++;
+        return virQEMUQAPISchemaTraverseCommand(cur, query, schema, type);
     } else {
         /* alternates, basic types and enums can't be entered */
         return 0;
     }

-    if (!querytype)
-        return 0;
-
-    return virQEMUQAPISchemaTraverse(querytype, query, schema, type);
+    return 0;
 }


-- 
2.20.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 08/21] qemu: qapi: Separate virQEMUQAPISchemaTraverse into functions by object type
Posted by Ján Tomko 6 years, 9 months ago
On Mon, Apr 15, 2019 at 06:02:01PM +0200, Peter Krempa wrote:
>Simplify virQEMUQAPISchemaTraverse by separating out the necessary
>operations for given 'meta-type' into separate functions.
>
>Signed-off-by: Peter Krempa <pkrempa@redhat.com>
>---
> src/qemu/qemu_qapi.c | 117 ++++++++++++++++++++++++++++---------------
> 1 file changed, 78 insertions(+), 39 deletions(-)
>
>diff --git a/src/qemu/qemu_qapi.c b/src/qemu/qemu_qapi.c
>index 2652061f4e..5995e5006e 100644
>--- a/src/qemu/qemu_qapi.c
>+++ b/src/qemu/qemu_qapi.c
>@@ -105,68 +105,107 @@ static int
> virQEMUQAPISchemaTraverse(const char *baseName,
>                           char **query,
>                           virHashTablePtr schema,
>-                          virJSONValuePtr *type)
>+                          virJSONValuePtr *type);
>+
>+
>+static int
>+virQEMUQAPISchemaTraverseObject(virJSONValuePtr cur,
>+                                char **query,
>+                                virHashTablePtr schema,
>+                                virJSONValuePtr *type)
> {
>-    virJSONValuePtr curtype;
>     virJSONValuePtr obj;
>-    const char *metatype;
>     const char *querytype = NULL;
>-    const char *querystr;
>-    char modifier;
>+    const char *querystr = *query;
>+    char modifier = *querystr;
>+
>+    if (!c_isalpha(modifier))
>+        querystr++;
>+
>+    if (modifier == '+') {
>+        querytype = virQEMUQAPISchemaObjectGetType("variants",
>+                                                   querystr,
>+                                                   "case", cur);
>+    } else {
>+        obj = virQEMUQAPISchemaObjectGet("members", querystr, "name", cur);
>+
>+        if (modifier == '*' &&
>+            !virJSONValueObjectHasKey(obj, "default"))
>+            return 0;
>+
>+        querytype = virQEMUQAPISchemaTypeFromObject(obj);
>+    }
>
>-    if (!(curtype = virHashLookup(schema, baseName)))

The object-specific code lost the
    if (!querytype)
        return 0;
condition

[...]

>     } else if (STREQ(metatype, "object")) {
>-        querystr = *query;
>-        modifier = **query;
>-
>-        if (!c_isalpha(modifier))
>-            querystr++;
>-
>-        if (modifier == '+') {
>-            querytype = virQEMUQAPISchemaObjectGetType("variants",
>-                                                       querystr,
>-                                                       "case", curtype);
>-        } else {
>-            obj = virQEMUQAPISchemaObjectGet("members", querystr,
>-                                             "name", curtype);
>-
>-            if (modifier == '*' &&
>-                !virJSONValueObjectHasKey(obj, "default"))
>-                return 0;
>-
>-            querytype = virQEMUQAPISchemaTypeFromObject(obj);
>-        }
>-        query++;
>+        return virQEMUQAPISchemaTraverseObject(cur, query, schema, type);
>     } else if (STREQ(metatype, "command") ||
>                STREQ(metatype, "event")) {
>-        if (!(querytype = virJSONValueObjectGetString(curtype, *query)))
>-            return 0;
>-        query++;
>+        return virQEMUQAPISchemaTraverseCommand(cur, query, schema, type);
>     } else {
>         /* alternates, basic types and enums can't be entered */
>         return 0;
>     }
>
>-    if (!querytype)
>-        return 0;
>-

That was executed here.

Reviewed-by: Ján Tomko <jtomko@redhat.com>

Jano
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 08/21] qemu: qapi: Separate virQEMUQAPISchemaTraverse into functions by object type
Posted by Peter Krempa 6 years, 9 months ago
On Thu, Apr 25, 2019 at 15:28:31 +0200, Ján Tomko wrote:
> On Mon, Apr 15, 2019 at 06:02:01PM +0200, Peter Krempa wrote:
> > Simplify virQEMUQAPISchemaTraverse by separating out the necessary
> > operations for given 'meta-type' into separate functions.
> > 
> > Signed-off-by: Peter Krempa <pkrempa@redhat.com>
> > ---
> > src/qemu/qemu_qapi.c | 117 ++++++++++++++++++++++++++++---------------
> > 1 file changed, 78 insertions(+), 39 deletions(-)
> > 
> > diff --git a/src/qemu/qemu_qapi.c b/src/qemu/qemu_qapi.c
> > index 2652061f4e..5995e5006e 100644
> > --- a/src/qemu/qemu_qapi.c
> > +++ b/src/qemu/qemu_qapi.c
> > @@ -105,68 +105,107 @@ static int
> > virQEMUQAPISchemaTraverse(const char *baseName,
> >                           char **query,
> >                           virHashTablePtr schema,
> > -                          virJSONValuePtr *type)
> > +                          virJSONValuePtr *type);
> > +
> > +
> > +static int
> > +virQEMUQAPISchemaTraverseObject(virJSONValuePtr cur,
> > +                                char **query,
> > +                                virHashTablePtr schema,
> > +                                virJSONValuePtr *type)
> > {
> > -    virJSONValuePtr curtype;
> >     virJSONValuePtr obj;
> > -    const char *metatype;
> >     const char *querytype = NULL;
> > -    const char *querystr;
> > -    char modifier;
> > +    const char *querystr = *query;
> > +    char modifier = *querystr;
> > +
> > +    if (!c_isalpha(modifier))
> > +        querystr++;
> > +
> > +    if (modifier == '+') {
> > +        querytype = virQEMUQAPISchemaObjectGetType("variants",
> > +                                                   querystr,
> > +                                                   "case", cur);
> > +    } else {
> > +        obj = virQEMUQAPISchemaObjectGet("members", querystr, "name", cur);
> > +
> > +        if (modifier == '*' &&
> > +            !virJSONValueObjectHasKey(obj, "default"))
> > +            return 0;
> > +
> > +        querytype = virQEMUQAPISchemaTypeFromObject(obj);
> > +    }
> > 
> > -    if (!(curtype = virHashLookup(schema, baseName)))
> 
> The object-specific code lost the
>    if (!querytype)
>        return 0;
> condition

It is not necessary as virHashLookup returns NULL if @name is NULL and
it's called right as the first thing in virQEMUQAPISchemaTraverse which
is called from virQEMUQAPISchemaTraverseObject.

Dropping that part makes it work the same in all of the individual
workers.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list